diff --git a/doc/classes/RenderSceneBuffers.xml b/doc/classes/RenderSceneBuffers.xml new file mode 100644 index 00000000000..b2a5213dba9 --- /dev/null +++ b/doc/classes/RenderSceneBuffers.xml @@ -0,0 +1,21 @@ + + + + Abstract scene buffers object, created for each viewport for which 3D rendering is done. + + + Abstract scene buffers object, created for each viewport for which 3D rendering is done. It manages any additional buffers used during rendering and will discard buffers when the viewport is resized. + [b]Note:[/b] this is an internal rendering server object only exposed for GDExtension plugins. + + + + + + + + + This method is called by the rendering server when the associated viewports configuration is changed. It will discard the old buffers and recreate the internal buffers used. + + + + diff --git a/doc/classes/RenderSceneBuffersConfiguration.xml b/doc/classes/RenderSceneBuffersConfiguration.xml new file mode 100644 index 00000000000..cb369552060 --- /dev/null +++ b/doc/classes/RenderSceneBuffersConfiguration.xml @@ -0,0 +1,40 @@ + + + + Configuration object used to setup a [RenderSceneBuffers] object. + + + This configuration object is created and populated by the render engine on a viewport change and used to (re)configure a [RenderSceneBuffers] object. + + + + + + FSR Sharpness applicable if FSR upscaling is used. + + + The size of the 3D render buffer used for rendering. + + + The MSAA mode we're using for 3D rendering. + + + The render target associated with these buffer. + + + The requested scaling mode with which we upscale/downscale if [member internal_size] and [member target_size] are not equal. + + + The requested screen space AA applied in post processing. + + + The target (upscale) size if scaling is used. + + + Bias applied to mipmaps. + + + The number of views we're rendering. + + + diff --git a/doc/classes/RenderSceneBuffersExtension.xml b/doc/classes/RenderSceneBuffersExtension.xml new file mode 100644 index 00000000000..f9960f0fbe4 --- /dev/null +++ b/doc/classes/RenderSceneBuffersExtension.xml @@ -0,0 +1,41 @@ + + + + This class allows for a RenderSceneBuffer implementation to be made in GDExtension. + + + This class allows for a RenderSceneBuffer implementation to be made in GDExtension. + + + + + + + + + Implement this in GDExtension to handle the (re)sizing of a viewport. + + + + + + + Implement this in GDExtension to record a new FSR sharpness value. + + + + + + + Implement this in GDExtension to change the texture mipmap bias. + + + + + + + Implement this in GDExtension to react to the debanding flag changing. + + + + diff --git a/doc/classes/RenderSceneBuffersRD.xml b/doc/classes/RenderSceneBuffersRD.xml new file mode 100644 index 00000000000..80a644ad265 --- /dev/null +++ b/doc/classes/RenderSceneBuffersRD.xml @@ -0,0 +1,167 @@ + + + + Abstract render scene buffer implementation for the RenderingDevice based renderers. + + + This object manages all 3D rendering buffers for the rendering device based renderers. An instance of this object is created for every viewport that has 3D rendering enabled. + All buffers are organised in [b]contexts[/b]. The default context is called [b]render_buffers[/b] and can contain amongst others the color buffer, depth buffer, velocity buffers, VRS density map and MSAA variants of these buffers. + Buffers are only guaranteed to exist during rendering of the viewport. + [b]Note:[/b] this is an internal rendering server object only exposed for GDExtension plugins. + + + + + + + + + Frees all buffers related to this context. + + + + + + + + + + + + + + + Create a new texture with the given definition and cache this under the given name. Will return the existing texture if it already exists. + + + + + + + + + + + Create a new texture using the given format and view and cache this under the given name. Will return the existing texture if it already exists. + + + + + + + + + + Create a new texture view for an existing texture and cache this under the given view_name. Will return the existing teture view if it already exists. Will error if the source texture doesn't exist. + + + + + + + Returns the specified layer from the color texture we are rendering 3D content to. + + + + + + Returns the color texture we are rendering 3D content to. If multiview is used this will be a texture array with all views. + + + + + + + Returns the specified layer from the depth texture we are rendering 3D content to. + + + + + + Returns the depth texture we are rendering 3D content to. If multiview is used this will be a texture array with all views. + + + + + + Returns the internal size of the render buffer (size before upscaling) with which textures are created by default. + + + + + + Returns the render target associated with this buffers object. + + + + + + + + Returns a cached texture with this name. + + + + + + + + Returns the texture format information with which a cached texture was created. + + + + + + + + + + + + Returns a specific slice (layer or mipmap) for a cached texture. + + + + + + + + + Returns the texture size of a given slice of a cached texture. + + + + + + Returns [b]true[/b] if TAA is enabled. + + + + + + + Returns the specified layer from the velocity texture we are rendering 3D content to. + + + + + + Returns the velocity texture we are rendering 3D content to. If multiview is used this will be a texture array with all views. + + + + + + Returns the view count for the associated viewport. + + + + + + + + Returns [b]true[/b] if a cached texture exists for this name. + + + + diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.cpp b/drivers/gles3/storage/render_scene_buffers_gles3.cpp index 19bf57df945..76c0097bab0 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.cpp +++ b/drivers/gles3/storage/render_scene_buffers_gles3.cpp @@ -37,25 +37,25 @@ RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() { free_render_buffer_data(); } -void RenderSceneBuffersGLES3::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { +void RenderSceneBuffersGLES3::configure(const RenderSceneBuffersConfiguration *p_config) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); - //internal_size.x = p_internal_size.x; // ignore for now - //internal_size.y = p_internal_size.y; - width = p_target_size.x; - height = p_target_size.y; - //scaling_3d_mode = p_scaling_3d_mode - //fsr_sharpness = p_fsr_sharpness; - //texture_mipmap_bias = p_texture_mipmap_bias; - render_target = p_render_target; - //msaa = p_msaa; - //screen_space_aa = p_screen_space_aa; - //use_debanding = p_use_debanding; - view_count = p_view_count; + //internal_size.x = p_config->get_internal_size().x; // ignore for now + //internal_size.y = p_config->get_internal_size().y; + width = p_config->get_target_size().x; + height = p_config->get_target_size().y; + //scaling_3d_mode = p_config->get_scaling_3d_mode() + //fsr_sharpness = p_config->get_fsr_sharpness(); + //texture_mipmap_bias = p_config->get_texture_mipmap_bias(); + render_target = p_config->get_render_target(); + //msaa = p_config->get_msaa_3d(); + //screen_space_aa = p_config->get_screen_space_aa(); + //use_debanding = p_config->get_use_debanding(); + view_count = p_config->get_view_count(); free_render_buffer_data(); - GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); + GLES3::RenderTarget *rt = texture_storage->get_render_target(render_target); is_transparent = rt->is_transparent; } diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h index d07a0812f64..64b95c417c2 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.h +++ b/drivers/gles3/storage/render_scene_buffers_gles3.h @@ -81,7 +81,7 @@ public: private: public: virtual ~RenderSceneBuffersGLES3(); - virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + virtual void configure(const RenderSceneBuffersConfiguration *p_config) override; virtual void set_fsr_sharpness(float p_fsr_sharpness) override{}; virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override{}; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 7cc9a82699e..67e48df9c9c 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -69,8 +69,10 @@ #include "physics_server_3d.h" #include "physics_server_3d_wrap_mt.h" #include "rendering/renderer_compositor.h" +#include "rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h" #include "rendering/rendering_device.h" #include "rendering/rendering_device_binds.h" +#include "rendering/storage/render_scene_buffers.h" #include "rendering_server.h" #include "servers/extensions/physics_server_2d_extension.h" #include "servers/extensions/physics_server_3d_extension.h" @@ -247,6 +249,11 @@ void register_server_types() { GDREGISTER_CLASS(RDShaderFile); GDREGISTER_CLASS(RDPipelineSpecializationConstant); + GDREGISTER_CLASS(RenderSceneBuffersConfiguration); + GDREGISTER_ABSTRACT_CLASS(RenderSceneBuffers); + GDREGISTER_CLASS(RenderSceneBuffersExtension); + GDREGISTER_ABSTRACT_CLASS(RenderSceneBuffersRD); + GDREGISTER_CLASS(CameraFeed); GDREGISTER_ABSTRACT_CLASS(PhysicsDirectBodyState2D); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 6bef7929227..ef09552603c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -59,7 +59,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) { usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR_MSAA, format, usage_bits, texture_samples); + render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR_MSAA, format, usage_bits, render_buffers->get_texture_samples()); } } } @@ -81,7 +81,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_rou if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) { usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, format, usage_bits, texture_samples); + render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples()); } } } @@ -100,7 +100,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) { usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI_MSAA, format, usage_bits, texture_samples); + render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI_MSAA, format, usage_bits, render_buffers->get_texture_samples()); } } } @@ -134,29 +134,6 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RenderS render_buffers = p_render_buffers; ERR_FAIL_NULL(render_buffers); - RS::ViewportMSAA msaa_3d = render_buffers->get_msaa_3d(); - - if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED) { - RD::DataFormat format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - uint32_t usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - - const RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { - RD::TEXTURE_SAMPLES_1, - RD::TEXTURE_SAMPLES_2, - RD::TEXTURE_SAMPLES_4, - RD::TEXTURE_SAMPLES_8, - }; - - texture_samples = ts[msaa_3d]; - - p_render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_COLOR_MSAA, format, usage_bits, texture_samples); - - format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; - usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - - p_render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_DEPTH_MSAA, format, usage_bits, texture_samples); - } - if (cluster_builder == nullptr) { cluster_builder = memnew(ClusterBuilderRD); } @@ -171,8 +148,8 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_only_fb( bool use_msaa = render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED; - RID color = use_msaa ? render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_COLOR_MSAA) : render_buffers->get_internal_texture(); - RID depth = use_msaa ? render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_DEPTH_MSAA) : render_buffers->get_depth_texture(); + RID color = use_msaa ? render_buffers->get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA) : render_buffers->get_internal_texture(); + RID depth = use_msaa ? render_buffers->get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA) : render_buffers->get_depth_texture(); if (render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE)) { RID vrs_texture = render_buffers->get_texture(RB_SCOPE_VRS, RB_TEXTURE); @@ -188,7 +165,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb( bool use_msaa = render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED; int v_count = (p_color_pass_flags & COLOR_PASS_FLAG_MULTIVIEW) ? render_buffers->get_view_count() : 1; - RID color = use_msaa ? render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_COLOR_MSAA) : render_buffers->get_internal_texture(); + RID color = use_msaa ? render_buffers->get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA) : render_buffers->get_internal_texture(); RID specular; if (p_color_pass_flags & COLOR_PASS_FLAG_SEPARATE_SPECULAR) { @@ -202,7 +179,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb( velocity_buffer = render_buffers->get_velocity_buffer(use_msaa); } - RID depth = use_msaa ? render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_DEPTH_MSAA) : render_buffers->get_depth_texture(); + RID depth = use_msaa ? render_buffers->get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA) : render_buffers->get_depth_texture(); if (render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE)) { RID vrs_texture = render_buffers->get_texture(RB_SCOPE_VRS, RB_TEXTURE); @@ -217,7 +194,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth ERR_FAIL_NULL_V(render_buffers, RID()); bool use_msaa = render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED; - RID depth = use_msaa ? render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_DEPTH_MSAA) : render_buffers->get_depth_texture(); + RID depth = use_msaa ? render_buffers->get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA) : render_buffers->get_depth_texture(); switch (p_type) { case DEPTH_FB: { @@ -1878,11 +1855,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); } for (uint32_t v = 0; v < rb->get_view_count(); v++) { - resolve_effects->resolve_gi(rb_data->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); + resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); } } else if (finish_depth) { for (uint32_t v = 0; v < rb->get_view_count(); v++) { - resolve_effects->resolve_depth(rb_data->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); + resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); } } RD::get_singleton()->draw_command_end_label(); @@ -1990,7 +1967,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (!can_continue_color) { // Handle views individual, might want to look at rewriting our resolve to do both layers in one pass. for (uint32_t v = 0; v < rb->get_view_count(); v++) { - RD::get_singleton()->texture_resolve_multisample(rb_data->get_color_msaa(v), rb->get_internal_texture(v)); + RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v)); } if (using_separate_specular) { for (uint32_t v = 0; v < rb->get_view_count(); v++) { @@ -2001,7 +1978,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (!can_continue_depth) { for (uint32_t v = 0; v < rb->get_view_count(); v++) { - resolve_effects->resolve_depth(rb_data->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); + resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); } } } @@ -2077,8 +2054,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (rb_data.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) { for (uint32_t v = 0; v < rb->get_view_count(); v++) { - RD::get_singleton()->texture_resolve_multisample(rb_data->get_color_msaa(v), rb->get_internal_texture(v)); - resolve_effects->resolve_depth(rb_data->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); + RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v)); + resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]); } if (taa && rb->get_use_taa()) { taa->msaa_resolve(rb); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 24f96adc6d8..155e8b4d19c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -100,7 +100,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { private: RenderSceneBuffersRD *render_buffers = nullptr; - RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1; public: ClusterBuilderRD *cluster_builder = nullptr; @@ -122,12 +121,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID render_sdfgi_uniform_set; - RID get_color_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_COLOR_MSAA); } - RID get_color_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_COLOR_MSAA, p_layer, 0); } - - RID get_depth_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_DEPTH_MSAA); } - RID get_depth_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_DEPTH_MSAA, p_layer, 0); } - void ensure_specular(); bool has_specular() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR); } RID get_specular() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR); } 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 c29204ed1e2..6434682fc25 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -136,30 +136,6 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RenderSceneBu render_buffers = p_render_buffers; ERR_FAIL_NULL(render_buffers); // Huh? really? - - RS::ViewportMSAA msaa_3d = render_buffers->get_msaa_3d(); - if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED) { - // Create our MSAA textures... - - RD::DataFormat format = render_buffers->get_base_data_format(); - uint32_t usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - - const RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { - RD::TEXTURE_SAMPLES_1, - RD::TEXTURE_SAMPLES_2, - RD::TEXTURE_SAMPLES_4, - RD::TEXTURE_SAMPLES_8, - }; - - texture_samples = ts[msaa_3d]; - - render_buffers->create_texture(RB_SCOPE_MOBILE, RB_TEX_COLOR_MSAA, format, usage_bits, texture_samples); - - usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, usage_bits) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; - - render_buffers->create_texture(RB_SCOPE_MOBILE, RB_TEX_DEPTH_MSAA, format, usage_bits, texture_samples); - } } RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(FramebufferConfigType p_config_type) { @@ -185,8 +161,8 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe Vector textures; int color_buffer_id = 0; - textures.push_back(use_msaa ? get_color_msaa() : render_buffers->get_internal_texture()); // 0 - color buffer - textures.push_back(use_msaa ? get_depth_msaa() : render_buffers->get_depth_texture()); // 1 - depth buffer + textures.push_back(use_msaa ? render_buffers->get_color_msaa() : render_buffers->get_internal_texture()); // 0 - color buffer + textures.push_back(use_msaa ? render_buffers->get_depth_msaa() : render_buffers->get_depth_texture()); // 1 - depth buffer if (vrs_texture.is_valid()) { textures.push_back(vrs_texture); // 2 - vrs texture } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index c89b5a8892e..f2913dd1859 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -120,19 +120,12 @@ private: FB_CONFIG_MAX }; - RID get_color_msaa() const { return render_buffers->get_texture(RB_SCOPE_MOBILE, RB_TEX_COLOR_MSAA); } - RID get_color_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_MOBILE, RB_TEX_COLOR_MSAA, p_layer, 0); } - - RID get_depth_msaa() const { return render_buffers->get_texture(RB_SCOPE_MOBILE, RB_TEX_DEPTH_MSAA); } - RID get_depth_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_MOBILE, RB_TEX_DEPTH_MSAA, p_layer, 0); } - RID get_color_fbs(FramebufferConfigType p_config_type); virtual void free_data() override; virtual void configure(RenderSceneBuffersRD *p_render_buffers) override; private: RenderSceneBuffersRD *render_buffers = nullptr; - RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1; }; virtual void setup_render_buffer_data(Ref p_render_buffers) override; 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 609fb2afe74..71bc21d5d48 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 @@ -44,15 +44,28 @@ RenderSceneBuffersRD::~RenderSceneBuffersRD() { void RenderSceneBuffersRD::_bind_methods() { ClassDB::bind_method(D_METHOD("has_texture", "context", "name"), &RenderSceneBuffersRD::has_texture); - // FIXME we can't pass RD::DataFormat, RD::TextureSamples and RD::TextureView in ClassDB, need to solve views differently... - // ClassDB::bind_method(D_METHOD("create_texture", "context", "name", "data_format", "usage_bits", "texture_samples", "size", "layers", "mipmaps", "unique"), &RenderSceneBuffersRD::create_texture); - // ClassDB::bind_method(D_METHOD("create_texture_from_format", "context", "name", "format", "view", "unique"), &RenderSceneBuffersRD::create_texture_from_format); - // ClassDB::bind_method(D_METHOD("create_texture_view", "context", "name", "view_name", "view"), &RenderSceneBuffersRD::has_texture); + ClassDB::bind_method(D_METHOD("create_texture", "context", "name", "data_format", "usage_bits", "texture_samples", "size", "layers", "mipmaps", "unique"), &RenderSceneBuffersRD::create_texture); + ClassDB::bind_method(D_METHOD("create_texture_from_format", "context", "name", "format", "view", "unique"), &RenderSceneBuffersRD::_create_texture_from_format); + ClassDB::bind_method(D_METHOD("create_texture_view", "context", "name", "view_name", "view"), &RenderSceneBuffersRD::_create_texture_view); ClassDB::bind_method(D_METHOD("get_texture", "context", "name"), &RenderSceneBuffersRD::get_texture); - // ClassDB::bind_method(D_METHOD("get_texture_format", "context", "name"), &RenderSceneBuffersRD::get_texture_format); + ClassDB::bind_method(D_METHOD("get_texture_format", "context", "name"), &RenderSceneBuffersRD::_get_texture_format); ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap", "layers", "mipmaps"), &RenderSceneBuffersRD::get_texture_slice); ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size); ClassDB::bind_method(D_METHOD("clear_context", "context"), &RenderSceneBuffersRD::clear_context); + + // Access to some core buffers so users don't need to know their names. + ClassDB::bind_method(D_METHOD("get_color_texture"), &RenderSceneBuffersRD::_get_color_texture); + ClassDB::bind_method(D_METHOD("get_color_layer", "layer"), &RenderSceneBuffersRD::_get_color_layer); + ClassDB::bind_method(D_METHOD("get_depth_texture"), &RenderSceneBuffersRD::_get_depth_texture); + ClassDB::bind_method(D_METHOD("get_depth_layer", "layer"), &RenderSceneBuffersRD::_get_depth_layer); + ClassDB::bind_method(D_METHOD("get_velocity_texture"), &RenderSceneBuffersRD::_get_velocity_texture); + ClassDB::bind_method(D_METHOD("get_velocity_layer", "layer"), &RenderSceneBuffersRD::_get_velocity_layer); + + // Expose a few properties we're likely to use externally + ClassDB::bind_method(D_METHOD("get_render_target"), &RenderSceneBuffersRD::get_render_target); + ClassDB::bind_method(D_METHOD("get_view_count"), &RenderSceneBuffersRD::get_view_count); + ClassDB::bind_method(D_METHOD("get_internal_size"), &RenderSceneBuffersRD::get_internal_size); + ClassDB::bind_method(D_METHOD("get_use_taa"), &RenderSceneBuffersRD::get_use_taa); } void RenderSceneBuffersRD::update_sizes(NamedTexture &p_named_texture) { @@ -90,42 +103,44 @@ void RenderSceneBuffersRD::cleanup() { named_textures.clear(); } -void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { +void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_config) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view"); + render_target = p_config->get_render_target(); + target_size = p_config->get_target_size(); + internal_size = p_config->get_internal_size(); + view_count = p_config->get_view_count(); - target_size = p_target_size; - internal_size = p_internal_size; - scaling_3d_mode = p_scaling_3d_mode; + scaling_3d_mode = p_config->get_scaling_3d_mode(); + msaa_3d = p_config->get_msaa_3d(); + screen_space_aa = p_config->get_screen_space_aa(); - if (p_use_taa) { + fsr_sharpness = p_config->get_fsr_sharpness(); + texture_mipmap_bias = p_config->get_texture_mipmap_bias(); + use_taa = p_config->get_use_taa(); + use_debanding = p_config->get_use_debanding(); + + ERR_FAIL_COND_MSG(view_count == 0, "Must have at least 1 view"); + + if (use_taa) { // Use negative mipmap LOD bias when TAA is enabled to compensate for loss of sharpness. // This restores sharpness in still images to be roughly at the same level as without TAA, // but moving scenes will still be blurrier. - p_texture_mipmap_bias -= 0.5; + texture_mipmap_bias -= 0.5; } - if (p_screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { + if (screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { // Use negative mipmap LOD bias when FXAA is enabled to compensate for loss of sharpness. // If both TAA and FXAA are enabled, combine their negative LOD biases together. - p_texture_mipmap_bias -= 0.25; + texture_mipmap_bias -= 0.25; } - material_storage->sampler_rd_configure_custom(p_texture_mipmap_bias); + material_storage->sampler_rd_configure_custom(texture_mipmap_bias); // need to check if we really need to do this here.. RendererSceneRenderRD::get_singleton()->update_uniform_sets(); - render_target = p_render_target; - fsr_sharpness = p_fsr_sharpness; - msaa_3d = p_msaa_3d; - screen_space_aa = p_screen_space_aa; - use_taa = p_use_taa; - use_debanding = p_use_debanding; - view_count = p_view_count; - // cleanout any old buffers we had. cleanup(); @@ -161,9 +176,33 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH, format, usage_bits); } + // Create our MSAA buffers + if (msaa_3d == RS::VIEWPORT_MSAA_DISABLED) { + texture_samples = RD::TEXTURE_SAMPLES_1; + } else { + RD::DataFormat format = base_data_format; + uint32_t usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + + const RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { + RD::TEXTURE_SAMPLES_1, + RD::TEXTURE_SAMPLES_2, + RD::TEXTURE_SAMPLES_4, + RD::TEXTURE_SAMPLES_8, + }; + + texture_samples = ts[msaa_3d]; + + create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, format, usage_bits, texture_samples); + + usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, usage_bits) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; + + create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, format, usage_bits, texture_samples); + } + // 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(p_render_target); + RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(render_target); if (vrs && vrs_mode != RS::VIEWPORT_VRS_DISABLED) { uint32_t usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; vrs_texture = create_texture(RB_SCOPE_VRS, RB_TEXTURE, RD::DATA_FORMAT_R8_UINT, usage_bits, RD::TEXTURE_SAMPLES_1, vrs->get_vrs_texture_size(internal_size)); @@ -244,6 +283,17 @@ RID RenderSceneBuffersRD::create_texture(const StringName &p_context, const Stri return create_texture_from_format(p_context, p_texture_name, tf, RD::TextureView(), p_unique); } +RID RenderSceneBuffersRD::_create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const Ref &p_texture_format, const Ref &p_view, bool p_unique) { + ERR_FAIL_COND_V(p_texture_format.is_null(), RID()); + + RD::TextureView texture_view; + if (p_view.is_valid()) { // only use when supplied, else default. + texture_view = p_view->base; + } + + return create_texture_from_format(p_context, p_texture_name, p_texture_format->base, texture_view, p_unique); +} + RID RenderSceneBuffersRD::create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const RD::TextureFormat &p_texture_format, RD::TextureView p_view, bool p_unique) { // TODO p_unique, if p_unique is true, this is a texture that can be shared. This will be implemented later as an optimization. @@ -272,6 +322,15 @@ RID RenderSceneBuffersRD::create_texture_from_format(const StringName &p_context return named_texture.texture; } +RID RenderSceneBuffersRD::_create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName p_view_name, const Ref p_view) { + RD::TextureView texture_view; + if (p_view.is_valid()) { // only use when supplied, else default. + texture_view = p_view->base; + } + + return create_texture_view(p_context, p_texture_name, p_view_name, texture_view); +} + RID RenderSceneBuffersRD::create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName p_view_name, RD::TextureView p_view) { NTKey view_key(p_context, p_view_name); @@ -310,6 +369,15 @@ RID RenderSceneBuffersRD::get_texture(const StringName &p_context, const StringN return named_textures[key].texture; } +Ref RenderSceneBuffersRD::_get_texture_format(const StringName &p_context, const StringName &p_texture_name) const { + Ref tf; + tf.instantiate(); + + tf->base = get_texture_format(p_context, p_texture_name); + + return tf; +} + const RD::TextureFormat RenderSceneBuffersRD::get_texture_format(const StringName &p_context, const StringName &p_texture_name) const { NTKey key(p_context, p_texture_name); @@ -535,15 +603,6 @@ void RenderSceneBuffersRD::ensure_velocity() { uint32_t msaa_usage_bits = usage_bits | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; - const RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { - RD::TEXTURE_SAMPLES_1, - RD::TEXTURE_SAMPLES_2, - RD::TEXTURE_SAMPLES_4, - RD::TEXTURE_SAMPLES_8, - }; - - RD::TextureSamples texture_samples = ts[msaa_3d]; - create_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA, RD::DATA_FORMAT_R16G16_SFLOAT, msaa_usage_bits, texture_samples); } 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 9a299a34157..85140c674c0 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 @@ -36,6 +36,7 @@ #include "core/templates/hash_map.h" #include "render_buffer_custom_data_rd.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/rendering_device_binds.h" #include "servers/rendering/rendering_method.h" #include "servers/rendering/storage/render_scene_buffers.h" @@ -75,12 +76,14 @@ private: Size2i internal_size = Size2i(0, 0); RS::ViewportScaling3DMode scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF; float fsr_sharpness = 0.2f; + float texture_mipmap_bias = 0.0f; // Aliassing settings RS::ViewportMSAA msaa_3d = RS::VIEWPORT_MSAA_DISABLED; RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; bool use_taa = false; bool use_debanding = false; + RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1; // Named Textures @@ -166,7 +169,7 @@ public: void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; } void cleanup(); - virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + virtual void configure(const RenderSceneBuffersConfiguration *p_config) override; void configure_for_reflections(const Size2i p_reflection_size); virtual void set_fsr_sharpness(float p_fsr_sharpness) override; virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override; @@ -202,6 +205,7 @@ public: _FORCE_INLINE_ RS::ViewportScaling3DMode get_scaling_3d_mode() const { return scaling_3d_mode; } _FORCE_INLINE_ float get_fsr_sharpness() const { return fsr_sharpness; } _FORCE_INLINE_ RS::ViewportMSAA get_msaa_3d() const { return msaa_3d; } + _FORCE_INLINE_ RD::TextureSamples get_texture_samples() const { return texture_samples; } _FORCE_INLINE_ RS::ViewportScreenSpaceAA get_screen_space_aa() const { return screen_space_aa; } _FORCE_INLINE_ bool get_use_taa() const { return use_taa; } _FORCE_INLINE_ bool get_use_debanding() const { return use_debanding; } @@ -220,11 +224,24 @@ public: _FORCE_INLINE_ RID get_internal_texture(const uint32_t p_layer) { return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR, p_layer, 0); } + _FORCE_INLINE_ RID get_color_msaa() const { + return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA); + } + _FORCE_INLINE_ RID get_color_msaa(uint32_t p_layer) { + return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, p_layer, 0); + } bool has_depth_texture(); RID get_depth_texture(); RID get_depth_texture(const uint32_t p_layer); + RID get_depth_msaa() const { + return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA); + } + RID get_depth_msaa(uint32_t p_layer) { + return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, p_layer, 0); + } + // back buffer (color) RID get_back_buffer_texture() const { return has_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0) ? get_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0) : RID(); } // We (re)use our blur texture here. @@ -236,8 +253,78 @@ public: RID get_velocity_buffer(bool p_get_msaa, uint32_t p_layer); //////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Everything after this needs to be re-evaluated, this is all old implementation + // Our classDB doesn't support calling our normal exposed functions +private: + RID _create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const Ref &p_texture_format, const Ref &p_view = Ref(), bool p_unique = true); + RID _create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName p_view_name, const Ref p_view = Ref()); + Ref _get_texture_format(const StringName &p_context, const StringName &p_texture_name) const; + + // For color and depth as exposed to extensions, we return the buffer that we're rendering into. + // Resolving happens after effects etc. are run. + RID _get_color_texture() { + if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) { + return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA); + } else if (has_internal_texture()) { + return get_internal_texture(); + } else { + return RID(); + } + } + + RID _get_color_layer(const uint32_t p_layer) { + if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) { + return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, p_layer, 0); + } else if (has_internal_texture()) { + return get_internal_texture(p_layer); + } else { + return RID(); + } + } + + RID _get_depth_texture() { + if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) { + return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA); + } else if (has_depth_texture()) { + return get_depth_texture(); + } else { + return RID(); + } + } + + RID _get_depth_layer(const uint32_t p_layer) { + if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) { + return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, p_layer, 0); + } else if (has_depth_texture()) { + return get_depth_texture(p_layer); + } else { + return RID(); + } + } + + RID _get_velocity_texture() { + if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_velocity_buffer(true)) { + return get_velocity_buffer(true); + } else if (has_velocity_buffer(false)) { + return get_velocity_buffer(false); + } else { + return RID(); + } + } + + RID _get_velocity_layer(const uint32_t p_layer) { + if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_velocity_buffer(true)) { + return get_velocity_buffer(true, p_layer); + } else if (has_velocity_buffer(false)) { + return get_velocity_buffer(false, p_layer); + } else { + return RID(); + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Everything after this needs to be re-evaluated, this is all old implementation +public: struct WeightBuffers { RID weight; RID fb; // FB with both texture and weight writing into one level lower diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 71f6a28671f..7a829826d2b 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -180,7 +180,19 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { // to compensate for the loss of sharpness. const float texture_mipmap_bias = log2f(MIN(scaling_3d_scale, 1.0)) + p_viewport->texture_mipmap_bias; - p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), scaling_3d_mode, p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->view_count); + 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_view_count(p_viewport->view_count); + rb_config.set_scaling_3d_mode(scaling_3d_mode); + rb_config.set_msaa_3d(p_viewport->msaa_3d); + rb_config.set_screen_space_aa(p_viewport->screen_space_aa); + rb_config.set_fsr_sharpness(p_viewport->fsr_sharpness); + rb_config.set_texture_mipmap_bias(texture_mipmap_bias); + rb_config.set_use_taa(p_viewport->use_taa); + + p_viewport->render_buffers->configure(&rb_config); } } } diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index e1734002991..bf30efbcf62 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -53,7 +53,9 @@ class RDTextureFormat : public RefCounted { GDCLASS(RDTextureFormat, RefCounted) + friend class RenderingDevice; + friend class RenderSceneBuffersRD; RD::TextureFormat base; @@ -91,6 +93,7 @@ class RDTextureView : public RefCounted { GDCLASS(RDTextureView, RefCounted) friend class RenderingDevice; + friend class RenderSceneBuffersRD; RD::TextureView base; diff --git a/servers/rendering/storage/render_scene_buffers.cpp b/servers/rendering/storage/render_scene_buffers.cpp index 6369139aa67..19496c0116d 100644 --- a/servers/rendering/storage/render_scene_buffers.cpp +++ b/servers/rendering/storage/render_scene_buffers.cpp @@ -30,22 +30,67 @@ #include "render_scene_buffers.h" -void RenderSceneBuffers::_bind_methods() { - ClassDB::bind_method(D_METHOD("configure", "render_target", "internal_size", "target_size", "fsr_sharpness", "texture_mipmap_bias", "msaa", "screen_space_aa", "use_taa", "use_debanding", "view_count"), &RenderSceneBuffers::configure); +void RenderSceneBuffersConfiguration::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_render_target"), &RenderSceneBuffersConfiguration::get_render_target); + ClassDB::bind_method(D_METHOD("set_render_target", "render_target"), &RenderSceneBuffersConfiguration::set_render_target); + ADD_PROPERTY(PropertyInfo(Variant::RID, "render_target"), "set_render_target", "get_render_target"); + + ClassDB::bind_method(D_METHOD("get_internal_size"), &RenderSceneBuffersConfiguration::get_internal_size); + ClassDB::bind_method(D_METHOD("set_internal_size", "internal_size"), &RenderSceneBuffersConfiguration::set_internal_size); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "internal_size"), "set_internal_size", "get_internal_size"); + + ClassDB::bind_method(D_METHOD("get_target_size"), &RenderSceneBuffersConfiguration::get_target_size); + ClassDB::bind_method(D_METHOD("set_target_size", "target_size"), &RenderSceneBuffersConfiguration::set_target_size); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "target_size"), "set_target_size", "get_target_size"); + + ClassDB::bind_method(D_METHOD("get_view_count"), &RenderSceneBuffersConfiguration::get_view_count); + ClassDB::bind_method(D_METHOD("set_view_count", "view_count"), &RenderSceneBuffersConfiguration::set_view_count); + ADD_PROPERTY(PropertyInfo(Variant::INT, "view_count"), "set_view_count", "get_view_count"); + + ClassDB::bind_method(D_METHOD("get_scaling_3d_mode"), &RenderSceneBuffersConfiguration::get_scaling_3d_mode); + ClassDB::bind_method(D_METHOD("set_scaling_3d_mode", "scaling_3d_mode"), &RenderSceneBuffersConfiguration::set_scaling_3d_mode); + ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast)"), "set_scaling_3d_mode", "get_scaling_3d_mode"); // TODO VIEWPORT_SCALING_3D_MODE_OFF is possible here too, but we can't specify an enum string for it. + + ClassDB::bind_method(D_METHOD("get_msaa_3d"), &RenderSceneBuffersConfiguration::get_msaa_3d); + ClassDB::bind_method(D_METHOD("set_msaa_3d", "msaa_3d"), &RenderSceneBuffersConfiguration::set_msaa_3d); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa_3d", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x"), "set_msaa_3d", "get_msaa_3d"); + + ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &RenderSceneBuffersConfiguration::get_screen_space_aa); + ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &RenderSceneBuffersConfiguration::set_screen_space_aa); + ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa"); + + ClassDB::bind_method(D_METHOD("get_fsr_sharpness"), &RenderSceneBuffersConfiguration::get_fsr_sharpness); + ClassDB::bind_method(D_METHOD("set_fsr_sharpness", "fsr_sharpness"), &RenderSceneBuffersConfiguration::set_fsr_sharpness); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fsr_sharpness"), "set_fsr_sharpness", "get_fsr_sharpness"); + + ClassDB::bind_method(D_METHOD("get_texture_mipmap_bias"), &RenderSceneBuffersConfiguration::get_texture_mipmap_bias); + ClassDB::bind_method(D_METHOD("set_texture_mipmap_bias", "texture_mipmap_bias"), &RenderSceneBuffersConfiguration::set_texture_mipmap_bias); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "texture_mipmap_bias"), "set_texture_mipmap_bias", "get_texture_mipmap_bias"); } -void RenderSceneBuffers::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { - GDVIRTUAL_CALL(_configure, p_render_target, p_internal_size, p_target_size, p_scaling_3d_mode, p_fsr_sharpness, p_texture_mipmap_bias, p_msaa, p_screen_space_aa, p_use_taa, p_use_debanding, p_view_count); +void RenderSceneBuffers::_bind_methods() { + ClassDB::bind_method(D_METHOD("configure", "config"), &RenderSceneBuffers::configure); +} + +void RenderSceneBuffersExtension::_bind_methods() { + GDVIRTUAL_BIND(_configure, "config"); + GDVIRTUAL_BIND(_set_fsr_sharpness, "fsr_sharpness"); + GDVIRTUAL_BIND(_set_texture_mipmap_bias, "texture_mipmap_bias"); + GDVIRTUAL_BIND(_set_use_debanding, "use_debanding"); +} + +void RenderSceneBuffersExtension::configure(const RenderSceneBuffersConfiguration *p_config) { + GDVIRTUAL_CALL(_configure, p_config); }; -void RenderSceneBuffers::set_fsr_sharpness(float p_fsr_sharpness) { +void RenderSceneBuffersExtension::set_fsr_sharpness(float p_fsr_sharpness) { GDVIRTUAL_CALL(_set_fsr_sharpness, p_fsr_sharpness); } -void RenderSceneBuffers::set_texture_mipmap_bias(float p_texture_mipmap_bias) { +void RenderSceneBuffersExtension::set_texture_mipmap_bias(float p_texture_mipmap_bias) { GDVIRTUAL_CALL(_set_texture_mipmap_bias, p_texture_mipmap_bias); } -void RenderSceneBuffers::set_use_debanding(bool p_use_debanding) { +void RenderSceneBuffersExtension::set_use_debanding(bool p_use_debanding) { GDVIRTUAL_CALL(_set_use_debanding, p_use_debanding); } diff --git a/servers/rendering/storage/render_scene_buffers.h b/servers/rendering/storage/render_scene_buffers.h index cf96a9f372c..6c82d477997 100644 --- a/servers/rendering/storage/render_scene_buffers.h +++ b/servers/rendering/storage/render_scene_buffers.h @@ -34,27 +34,103 @@ #include "core/object/ref_counted.h" #include "servers/rendering_server.h" +class RenderSceneBuffersConfiguration : public RefCounted { + GDCLASS(RenderSceneBuffersConfiguration, RefCounted); + +private: + RID render_target; + + Size2i internal_size; + Size2i target_size; + uint32_t view_count = 1; + + RS::ViewportScaling3DMode scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF; + RS::ViewportMSAA msaa_3d = RS::VIEWPORT_MSAA_DISABLED; + RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + + float fsr_sharpness = 0.0; + float texture_mipmap_bias = 0.0; + bool use_taa = false; + bool use_debanding = false; + +protected: + static void _bind_methods(); + +public: + RID get_render_target() const { return render_target; } + void set_render_target(RID p_render_target) { render_target = p_render_target; } + + Size2i get_internal_size() const { return internal_size; } + void set_internal_size(Size2i p_internal_size) { internal_size = p_internal_size; } + + Size2i get_target_size() const { return target_size; } + void set_target_size(Size2i p_target_size) { target_size = p_target_size; } + + uint32_t get_view_count() const { return view_count; } + void set_view_count(uint32_t p_view_count) { view_count = p_view_count; } + + RS::ViewportScaling3DMode get_scaling_3d_mode() const { return scaling_3d_mode; } + void set_scaling_3d_mode(RS::ViewportScaling3DMode p_scaling_3d_mode) { scaling_3d_mode = p_scaling_3d_mode; } + + RS::ViewportMSAA get_msaa_3d() const { return msaa_3d; } + void set_msaa_3d(RS::ViewportMSAA p_msaa_3d) { msaa_3d = p_msaa_3d; } + + RS::ViewportScreenSpaceAA get_screen_space_aa() const { return screen_space_aa; } + void set_screen_space_aa(RS::ViewportScreenSpaceAA p_screen_space_aa) { screen_space_aa = p_screen_space_aa; } + + float get_fsr_sharpness() const { return fsr_sharpness; } + void set_fsr_sharpness(float p_fsr_sharpness) { fsr_sharpness = p_fsr_sharpness; } + + float get_texture_mipmap_bias() const { return texture_mipmap_bias; } + void set_texture_mipmap_bias(float p_texture_mipmap_bias) { texture_mipmap_bias = p_texture_mipmap_bias; } + + bool get_use_taa() const { return use_taa; } + void set_use_taa(bool p_use_taa) { use_taa = p_use_taa; } + + bool get_use_debanding() const { return use_debanding; } + void set_use_debanding(bool p_use_debanding) { use_debanding = p_use_debanding; } + + RenderSceneBuffersConfiguration() {} + virtual ~RenderSceneBuffersConfiguration(){}; +}; + class RenderSceneBuffers : public RefCounted { GDCLASS(RenderSceneBuffers, RefCounted); protected: static void _bind_methods(); - GDVIRTUAL11(_configure, RID, Size2i, Size2i, RS::ViewportScaling3DMode, float, float, RS::ViewportMSAA, RenderingServer::ViewportScreenSpaceAA, bool, bool, uint32_t) +public: + RenderSceneBuffers(){}; + virtual ~RenderSceneBuffers(){}; + + virtual void configure(const RenderSceneBuffersConfiguration *p_config) = 0; + + // for those settings that are unlikely to require buffers to be recreated, we'll add setters + virtual void set_fsr_sharpness(float p_fsr_sharpness) = 0; + virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) = 0; + virtual void set_use_debanding(bool p_use_debanding) = 0; +}; + +class RenderSceneBuffersExtension : public RenderSceneBuffers { + GDCLASS(RenderSceneBuffersExtension, RenderSceneBuffers); + +protected: + static void _bind_methods(); + + GDVIRTUAL1(_configure, const RenderSceneBuffersConfiguration *) GDVIRTUAL1(_set_fsr_sharpness, float) GDVIRTUAL1(_set_texture_mipmap_bias, float) GDVIRTUAL1(_set_use_debanding, bool) public: - RenderSceneBuffers(){}; - virtual ~RenderSceneBuffers(){}; + virtual ~RenderSceneBuffersExtension(){}; - virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count); + virtual void configure(const RenderSceneBuffersConfiguration *p_config) override; - // for those settings that are unlikely to require buffers to be recreated, we'll add setters - virtual void set_fsr_sharpness(float p_fsr_sharpness); - virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias); - virtual void set_use_debanding(bool p_use_debanding); + virtual void set_fsr_sharpness(float p_fsr_sharpness) override; + virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override; + virtual void set_use_debanding(bool p_use_debanding) override; }; #endif // RENDER_SCENE_BUFFERS_H