mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #108636 from clayjohn/MSAA-depth-mobile
Add depth resolve to the mobile renderer
This commit is contained in:
commit
8c7c96e2c4
8 changed files with 131 additions and 27 deletions
|
@ -34,26 +34,43 @@
|
|||
|
||||
using namespace RendererRD;
|
||||
|
||||
Resolve::Resolve() {
|
||||
Vector<String> resolve_modes;
|
||||
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
|
||||
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
|
||||
resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
|
||||
Resolve::Resolve(bool p_prefer_raster_effects) {
|
||||
prefer_raster_effects = p_prefer_raster_effects;
|
||||
|
||||
resolve.shader.initialize(resolve_modes);
|
||||
if (prefer_raster_effects) {
|
||||
Vector<String> resolve_modes;
|
||||
resolve_modes.push_back("");
|
||||
|
||||
resolve.shader_version = resolve.shader.version_create();
|
||||
resolve_raster.shader.initialize(resolve_modes);
|
||||
resolve_raster.shader_version = resolve_raster.shader.version_create();
|
||||
resolve_raster.pipeline.setup(resolve_raster.shader.version_get_shader(resolve_raster.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
|
||||
} else {
|
||||
Vector<String> resolve_modes;
|
||||
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
|
||||
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
|
||||
resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
|
||||
|
||||
for (int i = 0; i < RESOLVE_MODE_MAX; i++) {
|
||||
resolve.pipelines[i] = RD::get_singleton()->compute_pipeline_create(resolve.shader.version_get_shader(resolve.shader_version, i));
|
||||
resolve.shader.initialize(resolve_modes);
|
||||
|
||||
resolve.shader_version = resolve.shader.version_create();
|
||||
|
||||
for (int i = 0; i < RESOLVE_MODE_MAX; i++) {
|
||||
resolve.pipelines[i] = RD::get_singleton()->compute_pipeline_create(resolve.shader.version_get_shader(resolve.shader_version, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Resolve::~Resolve() {
|
||||
resolve.shader.version_free(resolve.shader_version);
|
||||
if (prefer_raster_effects) {
|
||||
resolve_raster.shader.version_free(resolve_raster.shader_version);
|
||||
} else {
|
||||
resolve.shader.version_free(resolve.shader_version);
|
||||
}
|
||||
}
|
||||
|
||||
void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples) {
|
||||
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute shader resolve with the mobile renderer.");
|
||||
|
||||
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
|
||||
ERR_FAIL_NULL(uniform_set_cache);
|
||||
MaterialStorage *material_storage = MaterialStorage::get_singleton();
|
||||
|
@ -96,6 +113,8 @@ void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID
|
|||
}
|
||||
|
||||
void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples) {
|
||||
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute shader resolve with the mobile renderer.");
|
||||
|
||||
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
|
||||
ERR_FAIL_NULL(uniform_set_cache);
|
||||
MaterialStorage *material_storage = MaterialStorage::get_singleton();
|
||||
|
@ -127,3 +146,27 @@ void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_scr
|
|||
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void Resolve::resolve_depth_raster(RID p_source_rd_texture, RID p_dest_framebuffer, int p_samples) {
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
|
||||
|
||||
memset(&resolve_raster.push_constant, 0, sizeof(ResolvePushConstant));
|
||||
resolve_raster.push_constant.samples = p_samples;
|
||||
|
||||
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
||||
|
||||
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
|
||||
|
||||
RID shader = resolve_raster.shader.version_get_shader(resolve_raster.shader_version, 0);
|
||||
ERR_FAIL_COND(shader.is_null());
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, resolve_raster.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
|
||||
|
||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &resolve_raster.push_constant, sizeof(ResolvePushConstant));
|
||||
|
||||
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
|
|
@ -30,12 +30,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/effects/resolve.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/effects/resolve_raster.glsl.gen.h"
|
||||
|
||||
namespace RendererRD {
|
||||
|
||||
class Resolve {
|
||||
private:
|
||||
bool prefer_raster_effects;
|
||||
|
||||
struct ResolvePushConstant {
|
||||
int32_t screen_size[2];
|
||||
int32_t samples;
|
||||
|
@ -56,12 +60,20 @@ private:
|
|||
RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
|
||||
} resolve;
|
||||
|
||||
struct ResolveRasterShader {
|
||||
ResolvePushConstant push_constant;
|
||||
ResolveRasterShaderRD shader;
|
||||
RID shader_version;
|
||||
PipelineCacheRD pipeline;
|
||||
} resolve_raster;
|
||||
|
||||
public:
|
||||
Resolve();
|
||||
Resolve(bool p_prefer_raster_effects);
|
||||
~Resolve();
|
||||
|
||||
void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples);
|
||||
void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples);
|
||||
void resolve_depth_raster(RID p_source_rd_texture, RID p_dest_framebuffer, int p_samples);
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
|
|
@ -5044,7 +5044,6 @@ RenderForwardClustered::RenderForwardClustered() {
|
|||
_update_shader_quality_settings();
|
||||
_update_global_pipeline_data_requirements_from_project();
|
||||
|
||||
resolve_effects = memnew(RendererRD::Resolve());
|
||||
taa = memnew(RendererRD::TAA);
|
||||
fsr2_effect = memnew(RendererRD::FSR2Effect);
|
||||
ss_effects = memnew(RendererRD::SSEffects);
|
||||
|
@ -5082,11 +5081,6 @@ RenderForwardClustered::~RenderForwardClustered() {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (resolve_effects != nullptr) {
|
||||
memdelete(resolve_effects);
|
||||
resolve_effects = nullptr;
|
||||
}
|
||||
|
||||
RD::get_singleton()->free(shadow_sampler);
|
||||
RSG::light_storage->directional_shadow_atlas_set_size(0);
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "servers/rendering/renderer_rd/effects/metal_fx.h"
|
||||
#endif
|
||||
#include "servers/rendering/renderer_rd/effects/motion_vectors_store.h"
|
||||
#include "servers/rendering/renderer_rd/effects/resolve.h"
|
||||
#include "servers/rendering/renderer_rd/effects/ss_effects.h"
|
||||
#include "servers/rendering/renderer_rd/effects/taa.h"
|
||||
#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
|
||||
|
@ -716,7 +715,6 @@ private:
|
|||
|
||||
/* Effects */
|
||||
|
||||
RendererRD::Resolve *resolve_effects = nullptr;
|
||||
RendererRD::TAA *taa = nullptr;
|
||||
RendererRD::FSR2Effect *fsr2_effect = nullptr;
|
||||
RendererRD::SSEffects *ss_effects = nullptr;
|
||||
|
|
|
@ -233,8 +233,6 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||
if (use_msaa) {
|
||||
color_buffer_id = textures.size();
|
||||
textures.push_back(render_buffers->get_internal_texture()); // color buffer for resolve
|
||||
|
||||
// TODO add support for resolving depth buffer!!!
|
||||
}
|
||||
|
||||
// Now define our subpasses
|
||||
|
@ -1252,7 +1250,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
RD::get_singleton()->draw_list_end();
|
||||
} else {
|
||||
// We're done with our subpasses so end our container pass
|
||||
// note, if MSAA is used we should get an automatic resolve here
|
||||
// note, if MSAA is used we should get an automatic resolve of the color buffer here.
|
||||
|
||||
RD::get_singleton()->draw_list_end();
|
||||
|
||||
|
@ -1276,8 +1274,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
_render_buffers_ensure_depth_texture(p_render_data);
|
||||
|
||||
if (scene_state.used_depth_texture) {
|
||||
// Copy depth texture to backbuffer so we can read from it
|
||||
_render_buffers_copy_depth_texture(p_render_data);
|
||||
// Copy depth texture to backbuffer so we can read from it.
|
||||
_render_buffers_copy_depth_texture(p_render_data, use_msaa);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -412,7 +412,7 @@ void RendererSceneRenderRD::_render_buffers_ensure_depth_texture(const RenderDat
|
|||
rb->create_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, RD::DATA_FORMAT_R32_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1);
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data) {
|
||||
void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data, bool p_use_msaa) {
|
||||
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
|
||||
ERR_FAIL_COND(rb.is_null());
|
||||
|
||||
|
@ -433,7 +433,13 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
|
|||
copy_effects->copy_to_rect(depth_texture, depth_back_texture, Rect2i(0, 0, size.x, size.y));
|
||||
} else {
|
||||
RID depth_back_fb = FramebufferCacheRD::get_singleton()->get_cache(depth_back_texture);
|
||||
copy_effects->copy_to_fb_rect(depth_texture, depth_back_fb, Rect2i(0, 0, size.x, size.y));
|
||||
if (p_use_msaa) {
|
||||
static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8 };
|
||||
|
||||
resolve_effects->resolve_depth_raster(rb->get_depth_msaa(v), depth_back_fb, texture_multisamples[rb->get_msaa_3d()]);
|
||||
} else {
|
||||
copy_effects->copy_to_fb_rect(depth_texture, depth_back_fb, Rect2i(0, 0, size.x, size.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1716,6 +1722,7 @@ void RendererSceneRenderRD::init() {
|
|||
#ifdef METAL_ENABLED
|
||||
mfx_spatial = memnew(RendererRD::MFXSpatialEffect);
|
||||
#endif
|
||||
resolve_effects = memnew(RendererRD::Resolve(!can_use_storage));
|
||||
}
|
||||
|
||||
RendererSceneRenderRD::~RendererSceneRenderRD() {
|
||||
|
@ -1753,6 +1760,10 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (resolve_effects) {
|
||||
memdelete(resolve_effects);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#ifdef METAL_ENABLED
|
||||
#include "servers/rendering/renderer_rd/effects/metal_fx.h"
|
||||
#endif
|
||||
#include "servers/rendering/renderer_rd/effects/resolve.h"
|
||||
#include "servers/rendering/renderer_rd/effects/smaa.h"
|
||||
#include "servers/rendering/renderer_rd/effects/tone_mapper.h"
|
||||
#include "servers/rendering/renderer_rd/effects/vrs.h"
|
||||
|
@ -66,6 +67,7 @@ protected:
|
|||
RendererRD::ToneMapper *tone_mapper = nullptr;
|
||||
RendererRD::FSR *fsr = nullptr;
|
||||
RendererRD::VRS *vrs = nullptr;
|
||||
RendererRD::Resolve *resolve_effects = nullptr;
|
||||
#ifdef METAL_ENABLED
|
||||
RendererRD::MFXSpatialEffect *mfx_spatial = nullptr;
|
||||
#endif
|
||||
|
@ -108,7 +110,7 @@ protected:
|
|||
void _render_buffers_ensure_screen_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_ensure_depth_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data, bool p_use_msaa = false);
|
||||
void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
|
||||
void _post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data);
|
||||
void _disable_clear_request(const RenderDataRD *p_render_data);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* clang-format off */
|
||||
#[vertex]
|
||||
|
||||
#version 450
|
||||
|
||||
#VERSION_DEFINES
|
||||
|
||||
layout(location = 0) out vec2 uv_interp;
|
||||
/* clang-format on */
|
||||
|
||||
void main() {
|
||||
vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
|
||||
gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0);
|
||||
uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#[fragment]
|
||||
|
||||
#version 450
|
||||
|
||||
#VERSION_DEFINES
|
||||
|
||||
layout(location = 0) in vec2 uv_interp;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
|
||||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
ivec2 pad;
|
||||
int sample_count;
|
||||
int pad2;
|
||||
}
|
||||
params;
|
||||
|
||||
layout (location = 0) out float out_depth;
|
||||
|
||||
void main() {
|
||||
ivec2 pos = ivec2(gl_FragCoord.xy);
|
||||
|
||||
float depth_avg = 0.0;
|
||||
for (int i = 0; i < params.sample_count; i++) {
|
||||
depth_avg += texelFetch(source_depth, pos, i).r;
|
||||
}
|
||||
depth_avg /= float(params.sample_count);
|
||||
out_depth = depth_avg;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue