diff options
Diffstat (limited to 'servers/rendering/renderer_rd')
71 files changed, 3252 insertions, 2388 deletions
diff --git a/servers/rendering/renderer_rd/SCsub b/servers/rendering/renderer_rd/SCsub index 774a6b7951..10b83dca11 100644 --- a/servers/rendering/renderer_rd/SCsub +++ b/servers/rendering/renderer_rd/SCsub @@ -5,6 +5,7 @@ Import("env") env.add_source_files(env.servers_sources, "*.cpp") SConscript("effects/SCsub") +SConscript("environment/SCsub") SConscript("forward_clustered/SCsub") SConscript("forward_mobile/SCsub") SConscript("shaders/SCsub") diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 0b36fe3964..228933d618 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -413,7 +413,7 @@ void ClusterBuilderRD::bake_cluster() { StateUniform state; - RendererStorageRD::store_camera(adjusted_projection, state.projection); + RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection); state.inv_z_far = 1.0 / z_far; state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size); state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h index e82193ea6a..74ca530ff6 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.h +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -31,10 +31,10 @@ #ifndef CLUSTER_BUILDER_RD_H #define CLUSTER_BUILDER_RD_H -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/cluster_debug.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/cluster_render.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/cluster_store.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" class ClusterBuilderSharedDataRD { friend class ClusterBuilderRD; @@ -261,7 +261,7 @@ public: e.type = ELEMENT_TYPE_OMNI_LIGHT; e.original_index = cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]; - RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv); + RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv); cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]++; @@ -309,7 +309,7 @@ public: e.type = ELEMENT_TYPE_SPOT_LIGHT; e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; //use omni since they share index - RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv); + RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv); cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]++; } @@ -356,7 +356,7 @@ public: e.type = (p_box_type == BOX_TYPE_DECAL) ? ELEMENT_TYPE_DECAL : ELEMENT_TYPE_REFLECTION_PROBE; e.original_index = cluster_count_by_type[e.type]; - RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv); + RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv); cluster_count_by_type[e.type]++; render_element_count++; diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index 6b786fdf16..c30e8ed58f 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -29,9 +29,11 @@ /*************************************************************************/ #include "copy_effects.h" +#include "core/config/project_settings.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" +#include "thirdparty/misc/cubemap_coeffs.h" using namespace RendererRD; @@ -123,16 +125,157 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { } } } + + { + // Initialize copier + Vector<String> copy_modes; + copy_modes.push_back("\n"); + + cube_to_dp.shader.initialize(copy_modes); + + cube_to_dp.shader_version = cube_to_dp.shader.version_create(); + RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0); + RD::PipelineDepthStencilState dss; + dss.enable_depth_test = true; + dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS; + dss.enable_depth_write = true; + cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); + } + + { + //Initialize cubemap downsampler + Vector<String> cubemap_downsampler_modes; + cubemap_downsampler_modes.push_back(""); + + if (prefer_raster_effects) { + cubemap_downsampler.raster_shader.initialize(cubemap_downsampler_modes); + + cubemap_downsampler.shader_version = cubemap_downsampler.raster_shader.version_create(); + + cubemap_downsampler.raster_pipeline.setup(cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } else { + cubemap_downsampler.compute_shader.initialize(cubemap_downsampler_modes); + + cubemap_downsampler.shader_version = cubemap_downsampler.compute_shader.version_create(); + + cubemap_downsampler.compute_pipeline = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.compute_shader.version_get_shader(cubemap_downsampler.shader_version, 0)); + cubemap_downsampler.raster_pipeline.clear(); + } + } + + { + // Initialize cubemap filter + filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality"); + + Vector<String> cubemap_filter_modes; + cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n"); + cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n"); + cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n#define USE_TEXTURE_ARRAY\n"); + cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n#define USE_TEXTURE_ARRAY\n"); + + if (filter.use_high_quality) { + filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs)); + RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]); + } else { + filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs)); + RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]); + } + + if (prefer_raster_effects) { + filter.raster_shader.initialize(cubemap_filter_modes); + + // array variants are not supported in raster + filter.raster_shader.set_variant_enabled(FILTER_MODE_HIGH_QUALITY_ARRAY, false); + filter.raster_shader.set_variant_enabled(FILTER_MODE_LOW_QUALITY_ARRAY, false); + + filter.shader_version = filter.raster_shader.version_create(); + + for (int i = 0; i < FILTER_MODE_MAX; i++) { + if (filter.raster_shader.is_variant_enabled(i)) { + filter.raster_pipelines[i].setup(filter.raster_shader.version_get_shader(filter.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } else { + filter.raster_pipelines[i].clear(); + } + } + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 0; + u.append_id(filter.coefficient_buffer); + uniforms.push_back(u); + } + filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); + } else { + filter.compute_shader.initialize(cubemap_filter_modes); + filter.shader_version = filter.compute_shader.version_create(); + + for (int i = 0; i < FILTER_MODE_MAX; i++) { + filter.compute_pipelines[i] = RD::get_singleton()->compute_pipeline_create(filter.compute_shader.version_get_shader(filter.shader_version, i)); + filter.raster_pipelines[i].clear(); + } + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 0; + u.append_id(filter.coefficient_buffer); + uniforms.push_back(u); + } + filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); + } + } + + { + // Initialize roughness + Vector<String> cubemap_roughness_modes; + cubemap_roughness_modes.push_back(""); + + if (prefer_raster_effects) { + roughness.raster_shader.initialize(cubemap_roughness_modes); + + roughness.shader_version = roughness.raster_shader.version_create(); + + roughness.raster_pipeline.setup(roughness.raster_shader.version_get_shader(roughness.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + + } else { + roughness.compute_shader.initialize(cubemap_roughness_modes); + + roughness.shader_version = roughness.compute_shader.version_create(); + + roughness.compute_pipeline = RD::get_singleton()->compute_pipeline_create(roughness.compute_shader.version_get_shader(roughness.shader_version, 0)); + roughness.raster_pipeline.clear(); + } + } } CopyEffects::~CopyEffects() { if (prefer_raster_effects) { blur_raster.shader.version_free(blur_raster.shader_version); + cubemap_downsampler.raster_shader.version_free(cubemap_downsampler.shader_version); + filter.raster_shader.version_free(filter.shader_version); + roughness.raster_shader.version_free(roughness.shader_version); } else { copy.shader.version_free(copy.shader_version); + cubemap_downsampler.compute_shader.version_free(cubemap_downsampler.shader_version); + filter.compute_shader.version_free(filter.shader_version); + roughness.compute_shader.version_free(roughness.shader_version); + } + + RD::get_singleton()->free(filter.coefficient_buffer); + + if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { + RD::get_singleton()->free(filter.image_uniform_set); + } + + if (RD::get_singleton()->uniform_set_is_valid(filter.uniform_set)) { + RD::get_singleton()->free(filter.uniform_set); } copy_to_fb.shader.version_free(copy_to_fb.shader_version); + cube_to_dp.shader.version_free(cube_to_dp.shader_version); singleton = nullptr; } @@ -681,3 +824,262 @@ void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_end(); } + +void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + CopyToDPPushConstant push_constant; + push_constant.screen_rect[0] = p_rect.position.x; + push_constant.screen_rect[1] = p_rect.position.y; + push_constant.screen_rect[2] = p_rect.size.width; + push_constant.screen_rect[3] = p_rect.size.height; + push_constant.z_far = p_z_far; + push_constant.z_near = p_z_near; + push_constant.texel_size[0] = 1.0f / p_dst_size.x; + push_constant.texel_size[1] = 1.0f / p_dst_size.y; + push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, 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 = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_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_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER); +} + +void CopyEffects::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap downsample with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + cubemap_downsampler.push_constant.face_size = p_size.x; + cubemap_downsampler.push_constant.face_id = 0; // we render all 6 sides to each layer in one call + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_cubemap })); + RD::Uniform u_dest_cubemap(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_cubemap })); + + RID shader = cubemap_downsampler.compute_shader.version_get_shader(cubemap_downsampler.shader_version, 0); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.compute_pipeline); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_cubemap), 1); + + int x_groups = (p_size.x - 1) / 8 + 1; + int y_groups = (p_size.y - 1) / 8 + 1; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 6); // one z_group for each face + + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap downsample with the clustered renderer."); + ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap downsample must process one side at a time."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + cubemap_downsampler.push_constant.face_size = p_size.x; + cubemap_downsampler.push_constant.face_id = p_face_id; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_cubemap })); + + RID shader = cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cubemap_downsampler.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_cubemap), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap filter with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + Vector<RD::Uniform> uniforms; + for (int i = 0; i < p_dest_cubemap.size(); i++) { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = i; + u.append_id(p_dest_cubemap[i]); + uniforms.push_back(u); + } + if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { + RD::get_singleton()->free(filter.image_uniform_set); + } + filter.image_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, 0), 2); + + // setup our uniforms + RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_cubemap })); + + int mode = p_use_array ? FILTER_MODE_HIGH_QUALITY_ARRAY : FILTER_MODE_HIGH_QUALITY; + mode = filter.use_high_quality ? mode : mode + 1; + + RID shader = filter.compute_shader.version_get_shader(filter.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.compute_pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.image_uniform_set, 2); + + int x_groups = p_use_array ? 1792 : 342; // (128 * 128 * 7) / 64 : (128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) / 64 + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, 6, 1); // one y_group for each face + + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap filter with the clustered renderer."); + ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap filter must process one side at a time."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + // TODO implement! + CubemapFilterRasterPushConstant push_constant; + push_constant.mip_level = p_mip_level; + push_constant.face_id = p_face_id; + + // setup our uniforms + RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_cubemap })); + + CubemapFilterMode mode = filter.use_high_quality ? FILTER_MODE_HIGH_QUALITY : FILTER_MODE_LOW_QUALITY; + + RID shader = filter.raster_shader.version_get_shader(filter.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_pipelines[mode].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_cubemap), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CubemapFilterRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap roughness with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); + + roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; + roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. + roughness.push_constant.sample_count = p_sample_count; + roughness.push_constant.use_direct_write = p_roughness == 0.0; + roughness.push_constant.face_size = p_size; + + // setup our uniforms + RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_rd_texture })); + RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_texture })); + + RID shader = roughness.compute_shader.version_get_shader(roughness.shader_version, 0); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipeline); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_texture), 1); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); + + int x_groups = (p_size - 1) / 8 + 1; + int y_groups = (p_size - 1) / 8 + 1; + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1); + + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap roughness with the clustered renderer."); + ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap roughness must process one side at a time."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); + + roughness.push_constant.face_id = p_face_id; + roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. + roughness.push_constant.sample_count = p_sample_count; + roughness.push_constant.use_direct_write = p_roughness == 0.0; + roughness.push_constant.face_size = p_size; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, 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 = roughness.raster_shader.version_get_shader(roughness.shader_version, 0); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.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_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index e522408d20..882b446964 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -35,6 +35,13 @@ #include "servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/effects/copy.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering_server.h" @@ -189,6 +196,84 @@ private: } copy_to_fb; + // Copy to DP + + struct CopyToDPPushConstant { + float z_far; + float z_near; + float texel_size[2]; + float screen_rect[4]; + }; + + struct CopyToDP { + CubeToDpShaderRD shader; + RID shader_version; + PipelineCacheRD pipeline; + } cube_to_dp; + + // Cubemap effects + + struct CubemapDownsamplerPushConstant { + uint32_t face_size; + uint32_t face_id; + float pad[2]; + }; + + struct CubemapDownsampler { + CubemapDownsamplerPushConstant push_constant; + CubemapDownsamplerShaderRD compute_shader; + CubemapDownsamplerRasterShaderRD raster_shader; + RID shader_version; + RID compute_pipeline; + PipelineCacheRD raster_pipeline; + } cubemap_downsampler; + + enum CubemapFilterMode { + FILTER_MODE_HIGH_QUALITY, + FILTER_MODE_LOW_QUALITY, + FILTER_MODE_HIGH_QUALITY_ARRAY, + FILTER_MODE_LOW_QUALITY_ARRAY, + FILTER_MODE_MAX, + }; + + struct CubemapFilterRasterPushConstant { + uint32_t mip_level; + uint32_t face_id; + float pad[2]; + }; + + struct CubemapFilter { + CubemapFilterShaderRD compute_shader; + CubemapFilterRasterShaderRD raster_shader; + RID shader_version; + RID compute_pipelines[FILTER_MODE_MAX]; + PipelineCacheRD raster_pipelines[FILTER_MODE_MAX]; + + RID uniform_set; + RID image_uniform_set; + RID coefficient_buffer; + bool use_high_quality; + + } filter; + + struct CubemapRoughnessPushConstant { + uint32_t face_id; + uint32_t sample_count; + float roughness; + uint32_t use_direct_write; + float face_size; + float pad[3]; + }; + + struct CubemapRoughness { + CubemapRoughnessPushConstant push_constant; + CubemapRoughnessShaderRD compute_shader; + CubemapRoughnessRasterShaderRD raster_shader; + RID shader_version; + RID compute_pipeline; + PipelineCacheRD raster_pipeline; + } roughness; + static CopyEffects *singleton; public: @@ -197,6 +282,8 @@ public: CopyEffects(bool p_prefer_raster_effects); ~CopyEffects(); + bool get_prefer_raster_effects() { return prefer_raster_effects; } + void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); @@ -213,6 +300,15 @@ public: void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size); void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false); + + void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip); + void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size); + void cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size); + void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array); + void cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level); + + void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); + void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); }; } // namespace RendererRD diff --git a/servers/rendering/renderer_rd/effects/resolve.cpp b/servers/rendering/renderer_rd/effects/resolve.cpp new file mode 100644 index 0000000000..6c49a2ebce --- /dev/null +++ b/servers/rendering/renderer_rd/effects/resolve.cpp @@ -0,0 +1,130 @@ +/*************************************************************************/ +/* resolve.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "resolve.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" + +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.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); +} + +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, uint32_t p_barrier) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + ResolvePushConstant push_constant; + push_constant.screen_size[0] = p_screen_size.x; + push_constant.screen_size[1] = p_screen_size.y; + push_constant.samples = p_samples; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_depth })); + RD::Uniform u_source_normal_roughness(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector<RID>({ default_sampler, p_source_normal_roughness })); + RD::Uniform u_dest_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_depth })); + RD::Uniform u_dest_normal_roughness(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_dest_normal_roughness })); + + ResolveMode mode = p_source_voxel_gi.is_valid() ? RESOLVE_MODE_GI_VOXEL_GI : RESOLVE_MODE_GI; + RID shader = resolve.shader.version_get_shader(resolve.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_depth, u_source_normal_roughness), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_depth, u_dest_normal_roughness), 1); + if (p_source_voxel_gi.is_valid()) { + RD::Uniform u_source_voxel_gi(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_voxel_gi })); + RD::Uniform u_dest_voxel_gi(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_voxel_gi); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_source_voxel_gi), 2); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_voxel_gi), 3); + } + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); + + RD::get_singleton()->compute_list_end(p_barrier); +} + +void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + ResolvePushConstant push_constant; + push_constant.screen_size[0] = p_screen_size.x; + push_constant.screen_size[1] = p_screen_size.y; + push_constant.samples = p_samples; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_depth })); + RD::Uniform u_dest_depth(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_depth); + + ResolveMode mode = RESOLVE_MODE_DEPTH; + RID shader = resolve.shader.version_get_shader(resolve.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_depth), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_depth), 1); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); + + RD::get_singleton()->compute_list_end(p_barrier); +} diff --git a/servers/rendering/renderer_rd/effects/resolve.h b/servers/rendering/renderer_rd/effects/resolve.h new file mode 100644 index 0000000000..d4b24a610f --- /dev/null +++ b/servers/rendering/renderer_rd/effects/resolve.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* resolve.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RESOLVE_RD_H +#define RESOLVE_RD_H + +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/shaders/effects/resolve.glsl.gen.h" +#include "servers/rendering/renderer_scene_render.h" + +#include "servers/rendering_server.h" + +namespace RendererRD { + +class Resolve { +private: + struct ResolvePushConstant { + int32_t screen_size[2]; + int32_t samples; + uint32_t pad; + }; + + enum ResolveMode { + RESOLVE_MODE_GI, + RESOLVE_MODE_GI_VOXEL_GI, + RESOLVE_MODE_DEPTH, + RESOLVE_MODE_MAX + }; + + struct ResolveShader { + ResolvePushConstant push_constant; + ResolveShaderRD shader; + RID shader_version; + RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels + } resolve; + +public: + Resolve(); + ~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, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); +}; + +} // namespace RendererRD + +#endif // !RESOLVE_RD_H diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index bf97c6fbe9..d45ddbc392 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -86,7 +86,7 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) u.append_id(p_texture); uniforms.push_back(u); // anything with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0), 0); + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, specular_merge.shader.version_get_shader(specular_merge.shader_version, 0), 0); texture_to_uniform_set_cache[p_texture] = uniform_set; @@ -473,28 +473,6 @@ void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_bas RD::get_singleton()->draw_list_end(); } -void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) { - CopyToDPPushConstant push_constant; - push_constant.screen_rect[0] = p_rect.position.x; - push_constant.screen_rect[1] = p_rect.position.y; - push_constant.screen_rect[2] = p_rect.size.width; - push_constant.screen_rect[3] = p_rect.size.height; - push_constant.z_far = p_z_far; - push_constant.z_near = p_z_near; - push_constant.texel_size[0] = 1.0f / p_dst_size.x; - push_constant.texel_size[1] = 1.0f / p_dst_size.y; - push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER); -} - void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer."); @@ -1253,189 +1231,6 @@ void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size RD::get_singleton()->compute_list_end(); } -void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { - ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap roughness with the mobile renderer."); - - memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); - - roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; - roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. - roughness.push_constant.sample_count = p_sample_count; - roughness.push_constant.use_direct_write = p_roughness == 0.0; - roughness.push_constant.face_size = p_size; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipeline); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture, true), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); - - int x_groups = (p_size - 1) / 8 + 1; - int y_groups = (p_size - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1); - - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap roughness with the clustered renderer."); - ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap roughness must process one side at a time."); - - memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); - - roughness.push_constant.face_id = p_face_id; - roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. - roughness.push_constant.sample_count = p_sample_count; - roughness.push_constant.use_direct_write = p_roughness == 0.0; - roughness.push_constant.face_size = p_size; - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.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, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - -void EffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) { - ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap downsample with the mobile renderer."); - - cubemap_downsampler.push_constant.face_size = p_size.x; - cubemap_downsampler.push_constant.face_id = 0; // we render all 6 sides to each layer in one call - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.compute_pipeline); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_cubemap), 1); - - int x_groups = (p_size.x - 1) / 8 + 1; - int y_groups = (p_size.y - 1) / 8 + 1; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant)); - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 6); // one z_group for each face - - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap downsample with the clustered renderer."); - ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap downsample must process one side at a time."); - - cubemap_downsampler.push_constant.face_size = p_size.x; - cubemap_downsampler.push_constant.face_id = p_face_id; - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cubemap_downsampler.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, _get_uniform_set_from_texture(p_source_cubemap), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - -void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { - ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap filter with the mobile renderer."); - - Vector<RD::Uniform> uniforms; - for (int i = 0; i < p_dest_cubemap.size(); i++) { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = i; - u.append_id(p_dest_cubemap[i]); - uniforms.push_back(u); - } - if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { - RD::get_singleton()->free(filter.image_uniform_set); - } - filter.image_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, 0), 2); - - int pipeline = p_use_array ? FILTER_MODE_HIGH_QUALITY_ARRAY : FILTER_MODE_HIGH_QUALITY; - pipeline = filter.use_high_quality ? pipeline : pipeline + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.compute_pipelines[pipeline]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap, true), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.image_uniform_set, 2); - - int x_groups = p_use_array ? 1792 : 342; // (128 * 128 * 7) / 64 : (128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) / 64 - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, 6, 1); // one y_group for each face - - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap filter with the clustered renderer."); - ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap filter must process one side at a time."); - - // TODO implement! - CubemapFilterRasterPushConstant push_constant; - push_constant.mip_level = p_mip_level; - push_constant.face_id = p_face_id; - - CubemapFilterMode mode = filter.use_high_quality ? FILTER_MODE_HIGH_QUALITY : FILTER_MODE_LOW_QUALITY; - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_pipelines[mode].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, _get_uniform_set_from_texture(p_source_cubemap), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CubemapFilterRasterPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - -void EffectsRD::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, uint32_t p_barrier) { - ResolvePushConstant push_constant; - push_constant.screen_size[0] = p_screen_size.x; - push_constant.screen_size[1] = p_screen_size.y; - push_constant.samples = p_samples; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[p_source_voxel_gi.is_valid() ? RESOLVE_MODE_GI_VOXEL_GI : RESOLVE_MODE_GI]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_source_depth, p_source_normal_roughness), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_dest_depth, p_dest_normal_roughness), 1); - if (p_source_voxel_gi.is_valid()) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_voxel_gi), 2); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_voxel_gi), 3); - } - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); - - RD::get_singleton()->compute_list_end(p_barrier); -} - -void EffectsRD::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { - ResolvePushConstant push_constant; - push_constant.screen_size[0] = p_screen_size.x; - push_constant.screen_size[1] = p_screen_size.y; - push_constant.samples = p_samples; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[RESOLVE_MODE_DEPTH]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_depth), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_depth), 1); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); - - RD::get_singleton()->compute_list_end(p_barrier); -} - void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { Sort::PushConstant push_constant; push_constant.total_elements = p_size; @@ -1529,28 +1324,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { prefer_raster_effects = p_prefer_raster_effects; - { - // Initialize roughness - Vector<String> cubemap_roughness_modes; - cubemap_roughness_modes.push_back(""); - - if (prefer_raster_effects) { - roughness.raster_shader.initialize(cubemap_roughness_modes); - - roughness.shader_version = roughness.raster_shader.version_create(); - - roughness.raster_pipeline.setup(roughness.raster_shader.version_get_shader(roughness.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); - - } else { - roughness.compute_shader.initialize(cubemap_roughness_modes); - - roughness.shader_version = roughness.compute_shader.version_create(); - - roughness.compute_pipeline = RD::get_singleton()->compute_pipeline_create(roughness.compute_shader.version_get_shader(roughness.shader_version, 0)); - roughness.raster_pipeline.clear(); - } - } - if (prefer_raster_effects) { Vector<String> luminance_reduce_modes; luminance_reduce_modes.push_back("\n#define FIRST_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FIRST @@ -1584,22 +1357,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { } } - { - // Initialize copier - Vector<String> copy_modes; - copy_modes.push_back("\n"); - - cube_to_dp.shader.initialize(copy_modes); - - cube_to_dp.shader_version = cube_to_dp.shader.version_create(); - RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0); - RD::PipelineDepthStencilState dss; - dss.enable_depth_test = true; - dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS; - dss.enable_depth_write = true; - cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); - } - if (!prefer_raster_effects) { { // Initialize depth buffer for screen space effects @@ -1760,92 +1517,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { roughness_limiter.pipeline = RD::get_singleton()->compute_pipeline_create(roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0)); } - { - //Initialize cubemap downsampler - Vector<String> cubemap_downsampler_modes; - cubemap_downsampler_modes.push_back(""); - - if (prefer_raster_effects) { - cubemap_downsampler.raster_shader.initialize(cubemap_downsampler_modes); - - cubemap_downsampler.shader_version = cubemap_downsampler.raster_shader.version_create(); - - cubemap_downsampler.raster_pipeline.setup(cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); - } else { - cubemap_downsampler.compute_shader.initialize(cubemap_downsampler_modes); - - cubemap_downsampler.shader_version = cubemap_downsampler.compute_shader.version_create(); - - cubemap_downsampler.compute_pipeline = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.compute_shader.version_get_shader(cubemap_downsampler.shader_version, 0)); - cubemap_downsampler.raster_pipeline.clear(); - } - } - - { - // Initialize cubemap filter - filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality"); - - Vector<String> cubemap_filter_modes; - cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n"); - cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n"); - cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n#define USE_TEXTURE_ARRAY\n"); - cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n#define USE_TEXTURE_ARRAY\n"); - - if (filter.use_high_quality) { - filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs)); - RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]); - } else { - filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs)); - RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]); - } - - if (prefer_raster_effects) { - filter.raster_shader.initialize(cubemap_filter_modes); - - // array variants are not supported in raster - filter.raster_shader.set_variant_enabled(FILTER_MODE_HIGH_QUALITY_ARRAY, false); - filter.raster_shader.set_variant_enabled(FILTER_MODE_LOW_QUALITY_ARRAY, false); - - filter.shader_version = filter.raster_shader.version_create(); - - for (int i = 0; i < FILTER_MODE_MAX; i++) { - if (filter.raster_shader.is_variant_enabled(i)) { - filter.raster_pipelines[i].setup(filter.raster_shader.version_get_shader(filter.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); - } else { - filter.raster_pipelines[i].clear(); - } - } - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 0; - u.append_id(filter.coefficient_buffer); - uniforms.push_back(u); - } - filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); - } else { - filter.compute_shader.initialize(cubemap_filter_modes); - filter.shader_version = filter.compute_shader.version_create(); - - for (int i = 0; i < FILTER_MODE_MAX; i++) { - filter.compute_pipelines[i] = RD::get_singleton()->compute_pipeline_create(filter.compute_shader.version_get_shader(filter.shader_version, i)); - filter.raster_pipelines[i].clear(); - } - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 0; - u.append_id(filter.coefficient_buffer); - uniforms.push_back(u); - } - filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); - } - } - if (!prefer_raster_effects) { Vector<String> specular_modes; specular_modes.push_back("\n#define MODE_MERGE\n"); @@ -2009,21 +1680,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE)); } } - - { - 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.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)); - } - } } { @@ -2083,34 +1739,18 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { } EffectsRD::~EffectsRD() { - if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { - RD::get_singleton()->free(filter.image_uniform_set); - } - - if (RD::get_singleton()->uniform_set_is_valid(filter.uniform_set)) { - RD::get_singleton()->free(filter.uniform_set); - } - RD::get_singleton()->free(default_sampler); RD::get_singleton()->free(default_mipmap_sampler); RD::get_singleton()->free(index_buffer); //array gets freed as dependency - RD::get_singleton()->free(filter.coefficient_buffer); FSR_upscale.shader.version_free(FSR_upscale.shader_version); TAA_resolve.shader.version_free(TAA_resolve.shader_version); if (prefer_raster_effects) { luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version); - roughness.raster_shader.version_free(roughness.shader_version); - cubemap_downsampler.raster_shader.version_free(cubemap_downsampler.shader_version); - filter.raster_shader.version_free(filter.shader_version); } else { luminance_reduce.shader.version_free(luminance_reduce.shader_version); - roughness.compute_shader.version_free(roughness.shader_version); - cubemap_downsampler.compute_shader.version_free(cubemap_downsampler.shader_version); - filter.compute_shader.version_free(filter.shader_version); } if (!prefer_raster_effects) { - resolve.shader.version_free(resolve.shader_version); specular_merge.shader.version_free(specular_merge.shader_version); ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version); ssao.blur_shader.version_free(ssao.blur_shader_version); @@ -2133,6 +1773,5 @@ EffectsRD::~EffectsRD() { RD::get_singleton()->free(ssil.importance_map_load_counter); RD::get_singleton()->free(ssil.projection_uniform_buffer); } - cube_to_dp.shader.version_free(cube_to_dp.shader_version); sort.shader.version_free(sort.shader_version); } diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 787873642e..76627a8d7d 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -33,17 +33,9 @@ #include "core/math/camera_matrix.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" -#include "servers/rendering/renderer_rd/shaders/cube_to_dp.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/cubemap_filter.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/fsr_upscale.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/resolve.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" @@ -105,24 +97,6 @@ private: RID pipeline; } TAA_resolve; - struct CubemapRoughnessPushConstant { - uint32_t face_id; - uint32_t sample_count; - float roughness; - uint32_t use_direct_write; - float face_size; - float pad[3]; - }; - - struct CubemapRoughness { - CubemapRoughnessPushConstant push_constant; - CubemapRoughnessShaderRD compute_shader; - CubemapRoughnessRasterShaderRD raster_shader; - RID shader_version; - RID compute_pipeline; - PipelineCacheRD raster_pipeline; - } roughness; - enum LuminanceReduceMode { LUMINANCE_REDUCE_READ, LUMINANCE_REDUCE, @@ -168,19 +142,6 @@ private: PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX]; } luminance_reduce_raster; - struct CopyToDPPushConstant { - float z_far; - float z_near; - float texel_size[2]; - float screen_rect[4]; - }; - - struct CoptToDP { - CubeToDpShaderRD shader; - RID shader_version; - PipelineCacheRD pipeline; - } cube_to_dp; - struct SSEffectsDownsamplePushConstant { float pixel_size[2]; float z_far; @@ -420,49 +381,6 @@ private: } roughness_limiter; - struct CubemapDownsamplerPushConstant { - uint32_t face_size; - uint32_t face_id; - float pad[2]; - }; - - struct CubemapDownsampler { - CubemapDownsamplerPushConstant push_constant; - CubemapDownsamplerShaderRD compute_shader; - CubemapDownsamplerRasterShaderRD raster_shader; - RID shader_version; - RID compute_pipeline; - PipelineCacheRD raster_pipeline; - } cubemap_downsampler; - - enum CubemapFilterMode { - FILTER_MODE_HIGH_QUALITY, - FILTER_MODE_LOW_QUALITY, - FILTER_MODE_HIGH_QUALITY_ARRAY, - FILTER_MODE_LOW_QUALITY_ARRAY, - FILTER_MODE_MAX, - }; - - struct CubemapFilterRasterPushConstant { - uint32_t mip_level; - uint32_t face_id; - float pad[2]; - }; - - struct CubemapFilter { - CubemapFilterShaderRD compute_shader; - CubemapFilterRasterShaderRD raster_shader; - RID shader_version; - RID compute_pipelines[FILTER_MODE_MAX]; - PipelineCacheRD raster_pipelines[FILTER_MODE_MAX]; - - RID uniform_set; - RID image_uniform_set; - RID coefficient_buffer; - bool use_high_quality; - - } filter; - enum SpecularMergeMode { SPECULAR_MERGE_ADD, SPECULAR_MERGE_SSR, @@ -579,26 +497,6 @@ private: RID pipelines[3]; //3 quality levels } sss; - struct ResolvePushConstant { - int32_t screen_size[2]; - int32_t samples; - uint32_t pad; - }; - - enum ResolveMode { - RESOLVE_MODE_GI, - RESOLVE_MODE_GI_VOXEL_GI, - RESOLVE_MODE_DEPTH, - RESOLVE_MODE_MAX - }; - - struct Resolve { - ResolvePushConstant push_constant; - ResolveShaderRD shader; - RID shader_version; - RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels - } resolve; - enum SortMode { SORT_MODE_BLOCK, SORT_MODE_STEP, @@ -671,9 +569,6 @@ public: void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness); void taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity, RID p_prev_velocity, RID p_history, Size2 p_resolution, float p_z_near, float p_z_far); - void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); - void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); - void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); @@ -724,18 +619,11 @@ public: void screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set); void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve); - void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size); - void cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size); - void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array); - void cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level); void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera); void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection); void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); - 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, uint32_t p_barrier = RD::BARRIER_MASK_ALL); - void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); - void sort_buffer(RID p_uniform_set, int p_size); EffectsRD(bool p_prefer_raster_effects); diff --git a/servers/rendering/renderer_rd/environment/SCsub b/servers/rendering/renderer_rd/environment/SCsub new file mode 100644 index 0000000000..86681f9c74 --- /dev/null +++ b/servers/rendering/renderer_rd/environment/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp new file mode 100644 index 0000000000..2a6c96480e --- /dev/null +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -0,0 +1,128 @@ +/*************************************************************************/ +/* fog.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "fog.h" + +using namespace RendererRD; + +Fog *Fog::singleton = nullptr; + +Fog::Fog() { + singleton = this; +} + +Fog::~Fog() { + singleton = nullptr; +} + +/* FOG VOLUMES */ + +RID Fog::fog_volume_allocate() { + return fog_volume_owner.allocate_rid(); +} + +void Fog::fog_volume_initialize(RID p_rid) { + fog_volume_owner.initialize_rid(p_rid, FogVolume()); +} + +void Fog::fog_free(RID p_rid) { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid); + fog_volume->dependency.deleted_notify(p_rid); + fog_volume_owner.free(p_rid); +} + +void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND(!fog_volume); + + if (p_shape == fog_volume->shape) { + return; + } + + fog_volume->shape = p_shape; + fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); +} + +void Fog::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND(!fog_volume); + + fog_volume->extents = p_extents; + fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); +} + +void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND(!fog_volume); + fog_volume->material = p_material; +} + +RID Fog::fog_volume_get_material(RID p_fog_volume) const { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND_V(!fog_volume, RID()); + + return fog_volume->material; +} + +RS::FogVolumeShape Fog::fog_volume_get_shape(RID p_fog_volume) const { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX); + + return fog_volume->shape; +} + +AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND_V(!fog_volume, AABB()); + + switch (fog_volume->shape) { + case RS::FOG_VOLUME_SHAPE_ELLIPSOID: + case RS::FOG_VOLUME_SHAPE_CONE: + case RS::FOG_VOLUME_SHAPE_CYLINDER: + case RS::FOG_VOLUME_SHAPE_BOX: { + AABB aabb; + aabb.position = -fog_volume->extents; + aabb.size = fog_volume->extents * 2; + return aabb; + } + default: { + // Need some size otherwise will get culled + return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); + } + } + + return AABB(); +} + +Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const { + const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_COND_V(!fog_volume, Vector3()); + return fog_volume->extents; +} diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h new file mode 100644 index 0000000000..55a01c3616 --- /dev/null +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -0,0 +1,83 @@ +/*************************************************************************/ +/* fog.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef FOG_RD_H +#define FOG_RD_H + +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "servers/rendering/environment/renderer_fog.h" +#include "servers/rendering/storage/utilities.h" + +namespace RendererRD { + +class Fog : public RendererFog { +public: + struct FogVolume { + RID material; + Vector3 extents = Vector3(1, 1, 1); + + RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX; + + Dependency dependency; + }; + +private: + static Fog *singleton; + + mutable RID_Owner<FogVolume, true> fog_volume_owner; + +public: + static Fog *get_singleton() { return singleton; } + + Fog(); + ~Fog(); + + /* FOG VOLUMES */ + + FogVolume *get_fog_volume(RID p_rid) { return fog_volume_owner.get_or_null(p_rid); }; + bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); }; + + virtual RID fog_volume_allocate() override; + virtual void fog_volume_initialize(RID p_rid) override; + virtual void fog_free(RID p_rid) override; + + virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override; + virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override; + virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override; + virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override; + RID fog_volume_get_material(RID p_fog_volume) const; + virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override; + Vector3 fog_volume_get_extents(RID p_fog_volume) const; +}; + +} // namespace RendererRD + +#endif // !FOG_RD_H diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 7aede6bb48..a749e7d5bc 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene_gi_rd.cpp */ +/* gi.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,24 +28,354 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "renderer_scene_gi_rd.h" +#include "gi.h" #include "core/config/project_settings.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_default.h" -const Vector3i RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF); +using namespace RendererRD; + +const Vector3i GI::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF); + +GI *GI::singleton = nullptr; + +//////////////////////////////////////////////////////////////////////////////// +// VOXEL GI STORAGE + +RID GI::voxel_gi_allocate() { + return voxel_gi_owner.allocate_rid(); +} + +void GI::voxel_gi_free(RID p_voxel_gi) { + voxel_gi_allocate_data(p_voxel_gi, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + voxel_gi->dependency.deleted_notify(p_voxel_gi); + voxel_gi_owner.free(p_voxel_gi); +} + +void GI::voxel_gi_initialize(RID p_voxel_gi) { + voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI()); +} + +void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + if (voxel_gi->octree_buffer.is_valid()) { + RD::get_singleton()->free(voxel_gi->octree_buffer); + RD::get_singleton()->free(voxel_gi->data_buffer); + if (voxel_gi->sdf_texture.is_valid()) { + RD::get_singleton()->free(voxel_gi->sdf_texture); + } + + voxel_gi->sdf_texture = RID(); + voxel_gi->octree_buffer = RID(); + voxel_gi->data_buffer = RID(); + voxel_gi->octree_buffer_size = 0; + voxel_gi->data_buffer_size = 0; + voxel_gi->cell_count = 0; + } + + voxel_gi->to_cell_xform = p_to_cell_xform; + voxel_gi->bounds = p_aabb; + voxel_gi->octree_size = p_octree_size; + voxel_gi->level_counts = p_level_counts; + + if (p_octree_cells.size()) { + ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32 + + uint32_t cell_count = p_octree_cells.size() / 32; + + ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches + + voxel_gi->cell_count = cell_count; + voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells); + voxel_gi->octree_buffer_size = p_octree_cells.size(); + voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells); + voxel_gi->data_buffer_size = p_data_cells.size(); + + if (p_distance_field.size()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = voxel_gi->octree_size.x; + tf.height = voxel_gi->octree_size.y; + tf.depth = voxel_gi->octree_size.z; + tf.texture_type = RD::TEXTURE_TYPE_3D; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + Vector<Vector<uint8_t>> s; + s.push_back(p_distance_field); + voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s); + } +#if 0 + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = voxel_gi->octree_size.x; + tf.height = voxel_gi->octree_size.y; + tf.depth = voxel_gi->octree_size.z; + tf.type = RD::TEXTURE_TYPE_3D; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM); + tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT); + voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + } + RID shared_tex; + { + RD::TextureView tv; + tv.format_override = RD::DATA_FORMAT_R8_UINT; + shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture); + } + //update SDF texture + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 1; + u.append_id(voxel_gi->octree_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.append_id(voxel_gi->data_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 3; + u.append_id(shared_tex); + uniforms.push_back(u); + } + + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0); + + { + uint32_t push_constant[4] = { 0, 0, 0, 0 }; + + for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) { + push_constant[0] += voxel_gi->level_counts[i]; + } + push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1]; + + print_line("offset: " + itos(push_constant[0])); + print_line("size: " + itos(push_constant[1])); + //create SDF + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0); + RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4); + RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4); + RD::get_singleton()->compute_list_end(); + } + + RD::get_singleton()->free(uniform_set); + RD::get_singleton()->free(shared_tex); + } +#endif + } + + voxel_gi->version++; + voxel_gi->data_version++; + + voxel_gi->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); +} + +AABB GI::voxel_gi_get_bounds(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, AABB()); + + return voxel_gi->bounds; +} + +Vector3i GI::voxel_gi_get_octree_size(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector3i()); + return voxel_gi->octree_size; +} + +Vector<uint8_t> GI::voxel_gi_get_octree_cells(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); + + if (voxel_gi->octree_buffer.is_valid()) { + return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer); + } + return Vector<uint8_t>(); +} + +Vector<uint8_t> GI::voxel_gi_get_data_cells(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); + + if (voxel_gi->data_buffer.is_valid()) { + return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer); + } + return Vector<uint8_t>(); +} + +Vector<uint8_t> GI::voxel_gi_get_distance_field(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); + + if (voxel_gi->data_buffer.is_valid()) { + return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0); + } + return Vector<uint8_t>(); +} + +Vector<int> GI::voxel_gi_get_level_counts(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<int>()); + + return voxel_gi->level_counts; +} + +Transform3D GI::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Transform3D()); + + return voxel_gi->to_cell_xform; +} + +void GI::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->dynamic_range = p_range; + voxel_gi->version++; +} + +float GI::voxel_gi_get_dynamic_range(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + + return voxel_gi->dynamic_range; +} + +void GI::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->propagation = p_range; + voxel_gi->version++; +} + +float GI::voxel_gi_get_propagation(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->propagation; +} + +void GI::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->energy = p_energy; +} + +float GI::voxel_gi_get_energy(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->energy; +} + +void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->bias = p_bias; +} + +float GI::voxel_gi_get_bias(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->bias; +} + +void GI::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->normal_bias = p_normal_bias; +} + +float GI::voxel_gi_get_normal_bias(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->normal_bias; +} + +void GI::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->interior = p_enable; +} + +void GI::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->use_two_bounces = p_enable; + voxel_gi->version++; +} + +bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, false); + return voxel_gi->use_two_bounces; +} + +bool GI::voxel_gi_is_interior(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->interior; +} + +uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->version; +} + +uint32_t GI::voxel_gi_get_data_version(RID p_voxel_gi) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->data_version; +} + +RID GI::voxel_gi_get_octree_buffer(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, RID()); + return voxel_gi->octree_buffer; +} + +RID GI::voxel_gi_get_data_buffer(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, RID()); + return voxel_gi->data_buffer; +} + +RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, RID()); + + return voxel_gi->sdf_texture; +} //////////////////////////////////////////////////////////////////////////////// // SDFGI -void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi) { +void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - storage = p_gi->storage; gi = p_gi; num_cascades = p_env->sdfgi_cascades; min_cell_size = p_env->sdfgi_min_cell_size; @@ -755,7 +1085,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V reads_sky = p_env->sdfgi_read_sky_light; } -void RendererSceneGIRD::SDFGI::erase() { +void GI::SDFGI::erase() { for (uint32_t i = 0; i < cascades.size(); i++) { const SDFGI::Cascade &c = cascades[i]; RD::get_singleton()->free(c.light_data); @@ -791,9 +1121,26 @@ void RendererSceneGIRD::SDFGI::erase() { RD::get_singleton()->free(ambient_texture); RD::get_singleton()->free(cascades_ubo); + + for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { + if (RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) { + RD::get_singleton()->free(debug_uniform_set[v]); + } + debug_uniform_set[v] = RID(); + } + + if (RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) { + RD::get_singleton()->free(debug_probes_uniform_set); + } + debug_probes_uniform_set = RID(); + + if (debug_probes_scene_data_ubo.is_valid()) { + RD::get_singleton()->free(debug_probes_scene_data_ubo); + debug_probes_scene_data_ubo = RID(); + } } -void RendererSceneGIRD::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) { +void GI::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) { bounce_feedback = p_env->sdfgi_bounce_feedback; energy = p_env->sdfgi_energy; normal_bias = p_env->sdfgi_normal_bias; @@ -851,7 +1198,7 @@ void RendererSceneGIRD::SDFGI::update(RendererSceneEnvironmentRD *p_env, const V } } -void RendererSceneGIRD::SDFGI::update_light() { +void GI::SDFGI::update_light() { RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light"); /* Update dynamic light */ @@ -898,7 +1245,7 @@ void RendererSceneGIRD::SDFGI::update_light() { RD::get_singleton()->draw_command_end_label(); } -void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) { +void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) { RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes"); SDFGIShader::IntegratePushConstant push_constant; @@ -925,7 +1272,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, if (p_env->background == RS::ENV_BG_CLEAR_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; - Color c = storage->get_default_clear_color().srgb_to_linear(); + Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear(); push_constant.sky_color[0] = c.r; push_constant.sky_color[1] = c.g; push_constant.sky_color[2] = c.b; @@ -990,7 +1337,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RD::get_singleton()->draw_command_end_label(); } -void RendererSceneGIRD::SDFGI::store_probes() { +void GI::SDFGI::store_probes() { RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE); RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes"); @@ -1035,7 +1382,7 @@ void RendererSceneGIRD::SDFGI::store_probes() { RD::get_singleton()->draw_command_end_label(); } -int RendererSceneGIRD::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const { +int GI::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const { int dirty_count = 0; for (uint32_t i = 0; i < cascades.size(); i++) { const SDFGI::Cascade &c = cascades[i]; @@ -1091,7 +1438,7 @@ int RendererSceneGIRD::SDFGI::get_pending_region_data(int p_region, Vector3i &r_ return -1; } -void RendererSceneGIRD::SDFGI::update_cascades() { +void GI::SDFGI::update_cascades() { //update cascades SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES]; int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR; @@ -1112,160 +1459,177 @@ void RendererSceneGIRD::SDFGI::update_cascades() { RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); } -void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) { +void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.binding = 1; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { - if (i < cascades.size()) { - u.append_id(cascades[i].sdf_tex); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + for (uint32_t v = 0; v < p_view_count; v++) { + if (!debug_uniform_set[v].is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { + if (i < cascades.size()) { + u.append_id(cascades[i].sdf_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 2; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { - if (i < cascades.size()) { - u.append_id(cascades[i].light_tex); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + { + RD::Uniform u; + u.binding = 2; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { + if (i < cascades.size()) { + u.append_id(cascades[i].light_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 3; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { - if (i < cascades.size()) { - u.append_id(cascades[i].light_aniso_0_tex); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + { + RD::Uniform u; + u.binding = 3; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { + if (i < cascades.size()) { + u.append_id(cascades[i].light_aniso_0_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 4; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { - if (i < cascades.size()) { - u.append_id(cascades[i].light_aniso_1_tex); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + { + RD::Uniform u; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { + if (i < cascades.size()) { + u.append_id(cascades[i].light_aniso_1_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 5; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.append_id(occlusion_texture); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 8; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 9; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.append_id(cascades_ubo); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 10; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.append_id(p_texture); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 11; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.append_id(lightprobe_texture); - uniforms.push_back(u); + { + RD::Uniform u; + u.binding = 5; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.append_id(occlusion_texture); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 8; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 9; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(cascades_ubo); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 10; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.append_id(p_texture_views[v]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 11; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.append_id(lightprobe_texture); + uniforms.push_back(u); + } + debug_uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0); } - debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0); - } - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0); - - SDFGIShader::DebugPushConstant push_constant; - push_constant.grid_size[0] = cascade_size; - push_constant.grid_size[1] = cascade_size; - push_constant.grid_size[2] = cascade_size; - push_constant.max_cascades = cascades.size(); - push_constant.screen_size[0] = p_width; - push_constant.screen_size[1] = p_height; - push_constant.probe_axis_size = probe_axis_count; - push_constant.use_occlusion = uses_occlusion; - push_constant.y_mult = y_mult; - Vector2 vp_half = p_projection.get_viewport_half_extents(); - push_constant.cam_extent[0] = vp_half.x; - push_constant.cam_extent[1] = vp_half.y; - push_constant.cam_extent[2] = -p_projection.get_z_near(); - - push_constant.cam_transform[0] = p_transform.basis.rows[0][0]; - push_constant.cam_transform[1] = p_transform.basis.rows[1][0]; - push_constant.cam_transform[2] = p_transform.basis.rows[2][0]; - push_constant.cam_transform[3] = 0; - push_constant.cam_transform[4] = p_transform.basis.rows[0][1]; - push_constant.cam_transform[5] = p_transform.basis.rows[1][1]; - push_constant.cam_transform[6] = p_transform.basis.rows[2][1]; - push_constant.cam_transform[7] = 0; - push_constant.cam_transform[8] = p_transform.basis.rows[0][2]; - push_constant.cam_transform[9] = p_transform.basis.rows[1][2]; - push_constant.cam_transform[10] = p_transform.basis.rows[2][2]; - push_constant.cam_transform[11] = 0; - push_constant.cam_transform[12] = p_transform.origin.x; - push_constant.cam_transform[13] = p_transform.origin.y; - push_constant.cam_transform[14] = p_transform.origin.z; - push_constant.cam_transform[15] = 1; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1); - RD::get_singleton()->compute_list_end(); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set[v], 0); + + SDFGIShader::DebugPushConstant push_constant; + push_constant.grid_size[0] = cascade_size; + push_constant.grid_size[1] = cascade_size; + push_constant.grid_size[2] = cascade_size; + push_constant.max_cascades = cascades.size(); + push_constant.screen_size[0] = p_width; + push_constant.screen_size[1] = p_height; + push_constant.probe_axis_size = probe_axis_count; + push_constant.use_occlusion = uses_occlusion; + push_constant.y_mult = y_mult; + + push_constant.z_near = -p_projections[v].get_z_near(); + + push_constant.cam_transform[0] = p_transform.basis.rows[0][0]; + push_constant.cam_transform[1] = p_transform.basis.rows[1][0]; + push_constant.cam_transform[2] = p_transform.basis.rows[2][0]; + push_constant.cam_transform[3] = 0; + push_constant.cam_transform[4] = p_transform.basis.rows[0][1]; + push_constant.cam_transform[5] = p_transform.basis.rows[1][1]; + push_constant.cam_transform[6] = p_transform.basis.rows[2][1]; + push_constant.cam_transform[7] = 0; + push_constant.cam_transform[8] = p_transform.basis.rows[0][2]; + push_constant.cam_transform[9] = p_transform.basis.rows[1][2]; + push_constant.cam_transform[10] = p_transform.basis.rows[2][2]; + push_constant.cam_transform[11] = 0; + push_constant.cam_transform[12] = p_transform.origin.x; + push_constant.cam_transform[13] = p_transform.origin.y; + push_constant.cam_transform[14] = p_transform.origin.z; + push_constant.cam_transform[15] = 1; + + // need to properly unproject for asymmetric projection matrices in stereo.. + CameraMatrix inv_projection = p_projections[v].inverse(); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + push_constant.inv_projection[i * 4 + j] = inv_projection.matrix[i][j]; + } + } + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1); + RD::get_singleton()->compute_list_end(); + } Size2 rtsize = texture_storage->render_target_get_size(p_render_target); - copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true); + copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true, false, false, false, RID(), p_view_count > 1); } -void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { +void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - SDFGIShader::DebugProbesPushConstant push_constant; + // setup scene data + { + SDFGIShader::DebugProbesSceneData scene_data; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - push_constant.projection[i * 4 + j] = p_camera_with_transform.matrix[i][j]; + if (debug_probes_scene_data_ubo.is_null()) { + debug_probes_scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIShader::DebugProbesSceneData)); } + + for (uint32_t v = 0; v < p_view_count; v++) { + RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]); + } + + RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data, RD::BARRIER_MASK_RASTER); } + // setup push constant + SDFGIShader::DebugProbesPushConstant push_constant; + //gen spheres from strips uint32_t band_points = 16; push_constant.band_power = 4; @@ -1314,14 +1678,26 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr u.append_id(occlusion_texture); uniforms.push_back(u); } + { + RD::Uniform u; + u.binding = 5; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(debug_probes_scene_data_ubo); + uniforms.push_back(u); + } debug_probes_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_probes.version_get_shader(gi->sdfgi_shader.debug_probes_shader, 0), 0); } - RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, gi->sdfgi_shader.debug_probes_pipeline[SDFGIShader::PROBE_DEBUG_PROBES].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, debug_probes_uniform_set, 0); - RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant)); - RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points); + SDFGIShader::ProbeDebugMode mode = p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_PROBES_MULTIVIEW : SDFGIShader::PROBE_DEBUG_PROBES; + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CONTINUE, p_will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); + RD::get_singleton()->draw_command_begin_label("Debug SDFGI"); + + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[mode].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, false, total_probes, total_points); if (gi->sdfgi_debug_probe_dir != Vector3()) { uint32_t cascade = 0; @@ -1373,14 +1749,17 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2; - RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, gi->sdfgi_shader.debug_probes_pipeline[SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, debug_probes_uniform_set, 0); - RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant)); - RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, total_points); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_VISIBILITY_MULTIVIEW : SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, false, cell_count, total_points); } + + RD::get_singleton()->draw_command_end_label(); + RD::get_singleton()->draw_list_end(); } -void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) { /* Update general SDFGI Buffer */ SDFGIData sdfgi_data; @@ -1545,7 +1924,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re } } -void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { //print_line("rendering region " + itos(p_region)); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -1904,7 +2283,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } } -void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) { RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -2026,10 +2405,10 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32 //////////////////////////////////////////////////////////////////////////////// // VoxelGIInstance -void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - uint32_t data_version = storage->voxel_gi_get_data_version(probe); + uint32_t data_version = gi->voxel_gi_get_data_version(probe); // (RE)CREATE IF NEEDED @@ -2048,11 +2427,11 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c dynamic_maps.clear(); - Vector3i octree_size = storage->voxel_gi_get_octree_size(probe); + Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); if (octree_size != Vector3i()) { //can create a 3D texture - Vector<int> levels = storage->voxel_gi_get_level_counts(probe); + Vector<int> levels = gi->voxel_gi_get_level_counts(probe); RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; @@ -2092,14 +2471,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.append_id(storage->voxel_gi_get_octree_buffer(probe)); + u.append_id(gi->voxel_gi_get_octree_buffer(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.append_id(storage->voxel_gi_get_data_buffer(probe)); + u.append_id(gi->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } @@ -2114,7 +2493,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.append_id(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(gi->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { @@ -2268,7 +2647,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.append_id(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(gi->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { @@ -2337,7 +2716,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.append_id(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(gi->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { @@ -2388,7 +2767,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size()); { - Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(probe); + Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe); Transform3D to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse(); //update lights @@ -2439,7 +2818,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c if (mipmaps.size()) { //can update mipmaps - Vector3i probe_size = storage->voxel_gi_get_octree_size(probe); + Vector3i probe_size = gi->voxel_gi_get_octree_size(probe); VoxelGIPushConstant push_constant; @@ -2448,8 +2827,8 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c push_constant.limits[2] = probe_size.z; push_constant.stack_size = mipmaps.size(); push_constant.emission_scale = 1.0; - push_constant.propagation = storage->voxel_gi_get_propagation(probe); - push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe); + push_constant.propagation = gi->voxel_gi_get_propagation(probe); + push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe); push_constant.light_count = light_count; push_constant.aniso_strength = 0; @@ -2461,7 +2840,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c int passes; if (p_update_light_instances) { - passes = storage->voxel_gi_is_using_two_bounces(probe) ? 2 : 1; + passes = gi->voxel_gi_is_using_two_bounces(probe) ? 2 : 1; } else { passes = 1; //only re-blitting is necessary } @@ -2528,13 +2907,13 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c has_dynamic_object_data = false; //clear until dynamic object data is used again if (p_dynamic_objects.size() && dynamic_maps.size()) { - Vector3i octree_size = storage->voxel_gi_get_octree_size(probe); + Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z); Transform3D oversample_scale; oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier)); - Transform3D to_cell = oversample_scale * storage->voxel_gi_get_to_cell_xform(probe); + Transform3D to_cell = oversample_scale * gi->voxel_gi_get_to_cell_xform(probe); Transform3D to_world_xform = transform * to_cell.affine_inverse(); Transform3D to_probe_xform = to_world_xform.affine_inverse(); @@ -2634,7 +3013,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c push_constant.z_base = xform.origin[z_axis]; push_constant.z_sign = (z_flip ? -1.0 : 1.0); push_constant.pos_multiplier = float(1.0) / multiplier; - push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe); + push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe); push_constant.flip_x = x_flip; push_constant.flip_y = y_flip; push_constant.rect_pos[0] = rect.position[0]; @@ -2646,7 +3025,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c push_constant.prev_rect_size[0] = 0; push_constant.prev_rect_size[1] = 0; push_constant.on_mipmap = false; - push_constant.propagation = storage->voxel_gi_get_propagation(probe); + push_constant.propagation = gi->voxel_gi_get_propagation(probe); push_constant.pad[0] = 0; push_constant.pad[1] = 0; push_constant.pad[2] = 0; @@ -2728,24 +3107,24 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c has_dynamic_object_data = true; //clear until dynamic object data is used again } - last_probe_version = storage->voxel_gi_get_version(probe); + last_probe_version = gi->voxel_gi_get_version(probe); } -void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); if (mipmaps.size() == 0) { return; } - CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->voxel_gi_get_to_cell_xform(probe).affine_inverse()); + CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse()); int level = 0; - Vector3i octree_size = storage->voxel_gi_get_octree_size(probe); + Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); VoxelGIDebugPushConstant push_constant; push_constant.alpha = p_alpha; - push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe); + push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe); push_constant.cell_offset = mipmaps[level].cell_offset; push_constant.level = level; @@ -2768,7 +3147,7 @@ void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.append_id(storage->voxel_gi_get_data_buffer(probe)); + u.append_id(gi->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } { @@ -2810,23 +3189,24 @@ void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p } //////////////////////////////////////////////////////////////////////////////// -// GIRD +// GI + +GI::GI() { + singleton = this; -RendererSceneGIRD::RendererSceneGIRD() { sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1))); sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1))); sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1))); } -RendererSceneGIRD::~RendererSceneGIRD() { +GI::~GI() { + singleton = nullptr; } -void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) { +void GI::init(RendererSceneSkyRD *p_sky) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - storage = p_storage; - /* GI */ { @@ -2962,17 +3342,38 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p //calculate tables String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n"; Vector<String> gi_modes; - gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); - gi_modes.push_back("\n#define USE_SDFGI\n"); - gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); - gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n"); - gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n"); - gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); + gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_VOXEL_GI + gi_modes.push_back("\n#define USE_SDFGI\n"); // MODE_SDFGI + gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_COMBINED + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_HALF_RES_VOXEL_GI + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n"); // MODE_HALF_RES_SDFGI + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_HALF_RES_COMBINED + + gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_VOXEL_GI_MULTIVIEW + gi_modes.push_back("\n#define USE_SDFGI\n#define USE_MULTIVIEW\n"); // MODE_SDFGI_MULTIVIEW + gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_COMBINED_MULTIVIEW + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_VOXEL_GI_MULTIVIEW + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_SDFGI_MULTIVIEW + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_COMBINED_MULTIVIEW shader.initialize(gi_modes, defines); + + if (!RendererCompositorRD::singleton->is_xr_enabled()) { + shader.set_variant_enabled(MODE_VOXEL_GI_MULTIVIEW, false); + shader.set_variant_enabled(MODE_SDFGI_MULTIVIEW, false); + shader.set_variant_enabled(MODE_COMBINED_MULTIVIEW, false); + shader.set_variant_enabled(MODE_HALF_RES_VOXEL_GI_MULTIVIEW, false); + shader.set_variant_enabled(MODE_HALF_RES_SDFGI_MULTIVIEW, false); + shader.set_variant_enabled(MODE_HALF_RES_COMBINED_MULTIVIEW, false); + } + shader_version = shader.version_create(); for (int i = 0; i < MODE_MAX; i++) { - pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i)); + if (shader.is_variant_enabled(i)) { + pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i)); + } else { + pipelines[i] = RID(); + } } sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIData)); @@ -2991,9 +3392,14 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p Vector<String> versions; versions.push_back("\n#define MODE_PROBES\n"); + versions.push_back("\n#define MODE_PROBES\n#define USE_MULTIVIEW\n"); versions.push_back("\n#define MODE_VISIBILITY\n"); + versions.push_back("\n#define MODE_VISIBILITY\n#define USE_MULTIVIEW\n"); sdfgi_shader.debug_probes.initialize(versions, defines); + + // TODO disable multiview versions if turned off + sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create(); { @@ -3004,6 +3410,8 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p ds.enable_depth_write = true; ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) { + // TODO check if version is enabled + RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i); sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); } @@ -3013,7 +3421,7 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution"); } -void RendererSceneGIRD::free() { +void GI::free() { RD::get_singleton()->free(default_voxel_gi_buffer); RD::get_singleton()->free(voxel_gi_lights_uniform); RD::get_singleton()->free(sdfgi_ubo); @@ -3032,7 +3440,7 @@ void RendererSceneGIRD::free() { } } -RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { +GI::SDFGI *GI::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { SDFGI *sdfgi = memnew(SDFGI); sdfgi->create(p_env, p_world_position, p_requested_history_size, this); @@ -3040,7 +3448,7 @@ RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironme return sdfgi; } -void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { +void GI::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); r_voxel_gi_instances_used = 0; @@ -3069,7 +3477,7 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra RID base_probe = gipi->probe; - Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera; + Transform3D to_cell = voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera; gipd.xform[0] = to_cell.basis.rows[0][0]; gipd.xform[1] = to_cell.basis.rows[1][0]; @@ -3088,16 +3496,16 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra gipd.xform[14] = to_cell.origin.z; gipd.xform[15] = 1; - Vector3 bounds = storage->voxel_gi_get_octree_size(base_probe); + Vector3 bounds = voxel_gi_get_octree_size(base_probe); gipd.bounds[0] = bounds.x; gipd.bounds[1] = bounds.y; gipd.bounds[2] = bounds.z; - gipd.dynamic_range = storage->voxel_gi_get_dynamic_range(base_probe) * storage->voxel_gi_get_energy(base_probe); - gipd.bias = storage->voxel_gi_get_bias(base_probe); - gipd.normal_bias = storage->voxel_gi_get_normal_bias(base_probe); - gipd.blend_ambient = !storage->voxel_gi_is_interior(base_probe); + gipd.dynamic_range = voxel_gi_get_dynamic_range(base_probe) * voxel_gi_get_energy(base_probe); + gipd.bias = voxel_gi_get_bias(base_probe); + gipd.normal_bias = voxel_gi_get_normal_bias(base_probe); + gipd.blend_ambient = !voxel_gi_is_interior(base_probe); gipd.mipmaps = gipi->mipmaps.size(); } @@ -3108,17 +3516,19 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); } - if (texture != rb->gi.voxel_gi_textures[i]) { + if (texture != rb->rbgi.voxel_gi_textures[i]) { voxel_gi_instances_changed = true; - rb->gi.voxel_gi_textures[i] = texture; + rb->rbgi.voxel_gi_textures[i] = texture; } } if (voxel_gi_instances_changed) { - if (RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) { - RD::get_singleton()->free(rb->gi.uniform_set); + for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { + if (RD::get_singleton()->uniform_set_is_valid(rb->rbgi.uniform_set[v])) { + RD::get_singleton()->free(rb->rbgi.uniform_set[v]); + } + rb->rbgi.uniform_set[v] = RID(); } - rb->gi.uniform_set = RID(); if (rb->volumetric_fog) { if (RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) { RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set); @@ -3140,21 +3550,76 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra } } -void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { +void GI::RenderBuffersGI::free() { + for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { + if (RD::get_singleton()->uniform_set_is_valid(uniform_set[v])) { + RD::get_singleton()->free(uniform_set[v]); + } + uniform_set[v] = RID(); + } + + if (scene_data_ubo.is_valid()) { + RD::get_singleton()->free(scene_data_ubo); + scene_data_ubo = RID(); + } + + if (ambient_buffer.is_valid()) { + if (view_count == 1) { + // Only one view? then these are copies of our main buffers. + ambient_view[0] = RID(); + reflection_view[0] = RID(); + } else { + // Multiple views? free our slices. + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(ambient_view[v]); + RD::get_singleton()->free(reflection_view[v]); + ambient_view[v] = RID(); + reflection_view[v] = RID(); + } + } + + // Now we can free our buffers. + RD::get_singleton()->free(ambient_buffer); + RD::get_singleton()->free(reflection_buffer); + ambient_buffer = RID(); + reflection_buffer = RID(); + view_count = 0; + } + + if (voxel_gi_buffer.is_valid()) { + RD::get_singleton()->free(voxel_gi_buffer); + voxel_gi_buffer = RID(); + } +} + +void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + ERR_FAIL_COND_MSG(p_view_count > 2, "Maximum of 2 views supported for Processing GI."); + RD::get_singleton()->draw_command_begin_label("GI Render"); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(rb == nullptr); - if (rb->ambient_buffer.is_null() || rb->gi.using_half_size_gi != half_resolution) { - if (rb->ambient_buffer.is_valid()) { - RD::get_singleton()->free(rb->ambient_buffer); - RD::get_singleton()->free(rb->reflection_buffer); + if (rb->rbgi.ambient_buffer.is_null() || rb->rbgi.using_half_size_gi != half_resolution || rb->rbgi.view_count != p_view_count) { + // Free our old buffer if applicable + if (rb->rbgi.ambient_buffer.is_valid()) { + if (rb->rbgi.view_count > 1) { + for (uint32_t v = 0; v < rb->rbgi.view_count; v++) { + RD::get_singleton()->free(rb->rbgi.ambient_view[v]); + RD::get_singleton()->free(rb->rbgi.reflection_view[v]); + } + } + RD::get_singleton()->free(rb->rbgi.ambient_buffer); + RD::get_singleton()->free(rb->rbgi.reflection_buffer); } + // Remember the view count we're using + rb->rbgi.view_count = p_view_count; + + // Create textures for our ambient and reflection data RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = rb->internal_width; @@ -3163,252 +3628,309 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ tf.width >>= 1; tf.height >>= 1; } + if (p_view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.array_layers = p_view_count; + } else { + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + } tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->gi.using_half_size_gi = half_resolution; - } - - PushConstant push_constant; - - push_constant.screen_size[0] = rb->internal_width; - push_constant.screen_size[1] = rb->internal_height; - push_constant.z_near = p_projection.get_z_near(); - push_constant.z_far = p_projection.get_z_far(); - push_constant.orthogonal = p_projection.is_orthogonal(); - push_constant.proj_info[0] = -2.0f / (rb->internal_width * p_projection.matrix[0][0]); - push_constant.proj_info[1] = -2.0f / (rb->internal_height * p_projection.matrix[1][1]); - push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0]; - push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1]; - push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()); - push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH; - - bool use_sdfgi = rb->sdfgi != nullptr; - bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0; - - push_constant.cam_rotation[0] = p_transform.basis[0][0]; - push_constant.cam_rotation[1] = p_transform.basis[1][0]; - push_constant.cam_rotation[2] = p_transform.basis[2][0]; - push_constant.cam_rotation[3] = 0; - push_constant.cam_rotation[4] = p_transform.basis[0][1]; - push_constant.cam_rotation[5] = p_transform.basis[1][1]; - push_constant.cam_rotation[6] = p_transform.basis[2][1]; - push_constant.cam_rotation[7] = 0; - push_constant.cam_rotation[8] = p_transform.basis[0][2]; - push_constant.cam_rotation[9] = p_transform.basis[1][2]; - push_constant.cam_rotation[10] = p_transform.basis[2][2]; - push_constant.cam_rotation[11] = 0; - - if (rb->gi.uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.binding = 1; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { - if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.append_id(rb->sdfgi->cascades[j].sdf_tex); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); - } + rb->rbgi.ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->rbgi.reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->rbgi.using_half_size_gi = half_resolution; + + if (p_view_count == 1) { + // Just one view? Copy our buffers + rb->rbgi.ambient_view[0] = rb->rbgi.ambient_buffer; + rb->rbgi.reflection_view[0] = rb->rbgi.reflection_buffer; + } else { + // More then one view? Create slices for each view + for (uint32_t v = 0; v < p_view_count; v++) { + rb->rbgi.ambient_view[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.ambient_buffer, v, 0); + rb->rbgi.reflection_view[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.reflection_buffer, v, 0); } - uniforms.push_back(u); } - { - RD::Uniform u; - u.binding = 2; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { - if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.append_id(rb->sdfgi->cascades[j].light_tex); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } + + // Setup our scene data + { + SceneData scene_data; + + if (rb->rbgi.scene_data_ubo.is_null()) { + rb->rbgi.scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SceneData)); + } + + for (uint32_t v = 0; v < p_view_count; v++) { + RendererRD::MaterialStorage::store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]); + scene_data.eye_offset[v][0] = p_eye_offsets[v].x; + scene_data.eye_offset[v][1] = p_eye_offsets[v].y; + scene_data.eye_offset[v][2] = p_eye_offsets[v].z; + scene_data.eye_offset[v][3] = 0.0; + } + + // Note that we will be ignoring the origin of this transform. + RendererRD::MaterialStorage::store_transform(p_cam_transform, scene_data.cam_transform); + + scene_data.screen_size[0] = rb->internal_width; + scene_data.screen_size[1] = rb->internal_height; + + RD::get_singleton()->buffer_update(rb->rbgi.scene_data_ubo, 0, sizeof(SceneData), &scene_data, RD::BARRIER_MASK_COMPUTE); + } + + // Now compute the contents of our buffers. + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); + + for (uint32_t v = 0; v < p_view_count; v++) { + // Render each eye seperately. + // We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference.. + + // setup our push constant + + PushConstant push_constant; + + push_constant.view_index = v; + push_constant.orthogonal = p_projections[v].is_orthogonal(); + push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()); + push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH; + + push_constant.z_near = p_projections[v].get_z_near(); + push_constant.z_far = p_projections[v].get_z_far(); + + push_constant.proj_info[0] = -2.0f / (rb->internal_width * p_projections[v].matrix[0][0]); + push_constant.proj_info[1] = -2.0f / (rb->internal_height * p_projections[v].matrix[1][1]); + push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0]; + push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1]; + + bool use_sdfgi = rb->sdfgi != nullptr; + bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0; + + // setup our uniform set + if (rb->rbgi.uniform_set[v].is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->rbgi.uniform_set[v])) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { + if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { + u.append_id(rb->sdfgi->cascades[j].sdf_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 3; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { - if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex); + { + RD::Uniform u; + u.binding = 2; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { + if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { + u.append_id(rb->sdfgi->cascades[j].light_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } + } + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 3; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { + if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { + u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } + } + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { + if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { + u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + } + } + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 5; + if (rb->sdfgi) { + u.append_id(rb->sdfgi->occlusion_texture); } else { u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 4; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { - if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex); + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 6; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 7; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 9; + u.append_id(rb->rbgi.ambient_view[v]); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 10; + u.append_id(rb->rbgi.reflection_view[v]); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 11; + if (rb->sdfgi) { + u.append_id(rb->sdfgi->lightprobe_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); } + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 5; - if (rb->sdfgi) { - u.append_id(rb->sdfgi->occlusion_texture); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 12; + u.append_id(rb->views[v].view_depth); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 13; + u.append_id(p_normal_roughness_views[v]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 14; + RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 15; + u.append_id(sdfgi_ubo); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 16; + u.append_id(rb->rbgi.voxel_gi_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 17; + for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { + u.append_id(rb->rbgi.voxel_gi_textures[i]); + } + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 18; + u.append_id(rb->rbgi.scene_data_ubo); + uniforms.push_back(u); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 6; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 7; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; - u.append_id(rb->ambient_buffer); - uniforms.push_back(u); + rb->rbgi.uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0); } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 10; - u.append_id(rb->reflection_buffer); - uniforms.push_back(u); - } + Mode mode; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 11; - if (rb->sdfgi) { - u.append_id(rb->sdfgi->lightprobe_texture); + if (p_view_count > 1) { + if (rb->rbgi.using_half_size_gi) { + mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED_MULTIVIEW : (use_sdfgi ? MODE_HALF_RES_SDFGI_MULTIVIEW : MODE_HALF_RES_VOXEL_GI_MULTIVIEW); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); + mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED_MULTIVIEW : (use_sdfgi ? MODE_SDFGI_MULTIVIEW : MODE_VOXEL_GI_MULTIVIEW); } - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 12; - u.append_id(rb->depth_texture); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 13; - u.append_id(p_normal_roughness_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 14; - RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); - u.append_id(buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 15; - u.append_id(sdfgi_ubo); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 16; - u.append_id(rb->gi.voxel_gi_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 17; - for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { - u.append_id(rb->gi.voxel_gi_textures[i]); + } else { + if (rb->rbgi.using_half_size_gi) { + mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI); + } else { + mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI); } - uniforms.push_back(u); } - rb->gi.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0); - } - - Mode mode; + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->rbgi.uniform_set[v], 0); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); - if (rb->gi.using_half_size_gi) { - mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI); - } else { - mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI); + if (rb->rbgi.using_half_size_gi) { + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width >> 1, rb->internal_height >> 1, 1); + } else { + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width, rb->internal_height, 1); + } } - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi.uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); - - if (rb->gi.using_half_size_gi) { - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width >> 1, rb->internal_height >> 1, 1); - } else { - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width, rb->internal_height, 1); - } //do barrier later to allow oeverlap //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time RD::get_singleton()->draw_command_end_label(); } -RID RendererSceneGIRD::voxel_gi_instance_create(RID p_base) { +RID GI::voxel_gi_instance_create(RID p_base) { VoxelGIInstance voxel_gi; voxel_gi.gi = this; - voxel_gi.storage = storage; voxel_gi.probe = p_base; RID rid = voxel_gi_instance_owner.make_rid(voxel_gi); return rid; } -void RendererSceneGIRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { +void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND(!voxel_gi); voxel_gi->transform = p_xform; } -bool RendererSceneGIRD::voxel_gi_needs_update(RID p_probe) const { +bool GI::voxel_gi_needs_update(RID p_probe) const { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND_V(!voxel_gi, false); - return voxel_gi->last_probe_version != storage->voxel_gi_get_version(voxel_gi->probe); + return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe); } -void RendererSceneGIRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND(!voxel_gi); voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render); } -void RendererSceneGIRD::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/environment/gi.h index 122644498b..294b8d3cfd 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene_gi_rd.h */ +/* gi.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,33 +28,73 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_SCENE_GI_RD_H -#define RENDERING_SERVER_SCENE_GI_RD_H +#ifndef GI_RD_H +#define GI_RD_H #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" +#include "servers/rendering/environment/renderer_gi.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" -#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/storage/utilities.h" // Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound struct RenderDataRD; class RendererSceneRenderRD; -class RendererSceneGIRD { +namespace RendererRD { + +class GI : public RendererGI { +public: + /* VOXEL GI STORAGE */ + + struct VoxelGI { + RID octree_buffer; + RID data_buffer; + RID sdf_texture; + + uint32_t octree_buffer_size = 0; + uint32_t data_buffer_size = 0; + + Vector<int> level_counts; + + int cell_count = 0; + + Transform3D to_cell_xform; + AABB bounds; + Vector3i octree_size; + + float dynamic_range = 2.0; + float energy = 1.0; + float bias = 1.4; + float normal_bias = 0.0; + float propagation = 0.7; + bool interior = false; + bool use_two_bounces = false; + + uint32_t version = 1; + uint32_t data_version = 1; + + Dependency dependency; + }; + private: - RendererStorageRD *storage = nullptr; + static GI *singleton; + + /* VOXEL GI STORAGE */ + + mutable RID_Owner<VoxelGI, true> voxel_gi_owner; /* VOXEL_GI INSTANCE */ @@ -196,10 +236,13 @@ private: uint32_t use_occlusion; float y_mult; - float cam_extent[3]; uint32_t probe_axis_size; + float z_near; + float reserved1; + float reserved2; float cam_transform[16]; + float inv_projection[16]; }; SdfgiDebugShaderRD debug; @@ -209,13 +252,17 @@ private: enum ProbeDebugMode { PROBE_DEBUG_PROBES, + PROBE_DEBUG_PROBES_MULTIVIEW, PROBE_DEBUG_VISIBILITY, + PROBE_DEBUG_VISIBILITY_MULTIVIEW, PROBE_DEBUG_MAX }; - struct DebugProbesPushConstant { - float projection[16]; + struct DebugProbesSceneData { + float projection[2][16]; + }; + struct DebugProbesPushConstant { uint32_t band_power; uint32_t sections_in_band; uint32_t band_mask; @@ -324,14 +371,64 @@ private: } sdfgi_shader; public: + static GI *get_singleton() { return singleton; } + + /* VOXEL GI API */ + + VoxelGI *get_voxel_gi(RID p_rid) { return voxel_gi_owner.get_or_null(p_rid); }; + bool owns_voxel_gi(RID p_rid) { return voxel_gi_owner.owns(p_rid); }; + + virtual RID voxel_gi_allocate() override; + virtual void voxel_gi_free(RID p_voxel_gi) override; + virtual void voxel_gi_initialize(RID p_voxel_gi) override; + + virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override; + + virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const override; + virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override; + virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override; + virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override; + virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override; + + virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override; + virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override; + virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override; + virtual float voxel_gi_get_propagation(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) override; + virtual float voxel_gi_get_energy(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) override; + virtual float voxel_gi_get_bias(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override; + virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override; + virtual bool voxel_gi_is_interior(RID p_voxel_gi) const override; + + virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override; + virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override; + + virtual uint32_t voxel_gi_get_version(RID p_probe) const override; + uint32_t voxel_gi_get_data_version(RID p_probe); + + RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const; + RID voxel_gi_get_data_buffer(RID p_voxel_gi) const; + + RID voxel_gi_get_sdf_texture(RID p_voxel_gi); + /* VOXEL_GI INSTANCE */ //@TODO VoxelGIInstance is still directly used in the render code, we'll address this when we refactor the render code itself. struct VoxelGIInstance { // access to our containers - RendererStorageRD *storage = nullptr; - RendererSceneGIRD *gi = nullptr; + GI *gi = nullptr; RID probe; RID texture; @@ -454,8 +551,7 @@ public: }; // access to our containers - RendererStorageRD *storage = nullptr; - RendererSceneGIRD *gi = nullptr; + GI *gi = nullptr; // used for rendering (voxelization) RID render_albedo; @@ -497,7 +593,8 @@ public: float min_cell_size = 0; uint32_t probe_axis_count = 0; //amount of probes per axis, this is an odd number because it encloses endpoints - RID debug_uniform_set; + RID debug_uniform_set[RendererSceneRender::MAX_RENDER_VIEWS]; + RID debug_probes_scene_data_ubo; RID debug_probes_uniform_set; RID cascades_ubo; @@ -516,7 +613,7 @@ public: int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically RID integrate_sky_uniform_set; - void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi); + void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi); void erase(); void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position); void update_light(); @@ -525,8 +622,8 @@ public: int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; void update_cascades(); - void debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture); - void debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform); + void debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views); + void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); @@ -561,8 +658,18 @@ public: RID full_dispatch; RID full_mask; - RID uniform_set; + /* GI buffers */ + RID ambient_buffer; + RID reflection_buffer; + RID ambient_view[RendererSceneRender::MAX_RENDER_VIEWS]; + RID reflection_view[RendererSceneRender::MAX_RENDER_VIEWS]; + RID uniform_set[RendererSceneRender::MAX_RENDER_VIEWS]; bool using_half_size_gi = false; + uint32_t view_count = 1; + + RID scene_data_ubo; + + void free(); }; struct SDFGIData { @@ -611,19 +718,28 @@ public: uint32_t mipmaps; // 4 - 96 }; - struct PushConstant { - int32_t screen_size[2]; - float z_near; - float z_far; + struct SceneData { + float inv_projection[2][16]; + float cam_transform[16]; + float eye_offset[2][4]; - float proj_info[4]; + int32_t screen_size[2]; + float pad1; + float pad2; + }; + struct PushConstant { + uint32_t view_index; uint32_t max_voxel_gi_instances; uint32_t high_quality_vct; uint32_t orthogonal; - uint32_t pad; - float cam_rotation[12]; + float proj_info[4]; + + float z_near; + float z_far; + float pad1; + float pad2; }; RID sdfgi_ubo; @@ -634,6 +750,14 @@ public: MODE_HALF_RES_VOXEL_GI, MODE_HALF_RES_SDFGI, MODE_HALF_RES_COMBINED, + + MODE_VOXEL_GI_MULTIVIEW, + MODE_SDFGI_MULTIVIEW, + MODE_COMBINED_MULTIVIEW, + MODE_HALF_RES_VOXEL_GI_MULTIVIEW, + MODE_HALF_RES_SDFGI_MULTIVIEW, + MODE_HALF_RES_COMBINED_MULTIVIEW, + MODE_MAX }; @@ -644,16 +768,16 @@ public: RID shader_version; RID pipelines[MODE_MAX]; - RendererSceneGIRD(); - ~RendererSceneGIRD(); + GI(); + ~GI(); - void init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky); + void init(RendererSceneSkyRD *p_sky); void free(); SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); - void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); + void process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); RID voxel_gi_instance_create(RID p_base); void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); @@ -662,4 +786,6 @@ public: void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; -#endif /* !RENDERING_SERVER_SCENE_GI_RD_H */ +} // namespace RendererRD + +#endif /* !GI_RD_H */ 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 d390614e53..f759fa3aa5 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -30,6 +30,7 @@ #include "render_forward_clustered.h" #include "core/config/project_settings.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/storage_rd/light_storage.h" #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h" #include "servers/rendering/renderer_rd/storage_rd/particles_storage.h" @@ -48,6 +49,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() if (!specular.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + if (view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.array_layers = view_count; + } else { + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + } tf.width = width; tf.height = height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; @@ -64,7 +72,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() Vector<RID> fb; fb.push_back(specular); - specular_only_fb = RD::get_singleton()->framebuffer_create(fb); + specular_only_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, view_count); } } else { @@ -76,7 +84,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() Vector<RID> fb; fb.push_back(specular_msaa); - specular_only_fb = RD::get_singleton()->framebuffer_create(fb); + specular_only_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, view_count); } } } @@ -106,6 +114,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_velocity() void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() { if (!voxelgi_buffer.is_valid()) { RD::TextureFormat tf; + if (view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.array_layers = view_count; + } else { + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + } tf.format = RD::DATA_FORMAT_R8G8_UINT; tf.width = width; tf.height = height; @@ -116,6 +131,14 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() tf_aa.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; tf_aa.samples = texture_samples; voxelgi_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView()); + + if (view_count == 1) { + voxelgi_msaa_views[0] = voxelgi_buffer_msaa; + } else { + for (uint32_t v = 0; v < view_count; v++) { + voxelgi_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), voxelgi_buffer_msaa, v, 0); + } + } } else { tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; } @@ -124,6 +147,14 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() voxelgi_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + if (view_count == 1) { + voxelgi_views[0] = voxelgi_buffer; + } else { + for (uint32_t v = 0; v < view_count; v++) { + voxelgi_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), voxelgi_buffer, v, 0); + } + } + Vector<RID> fb; if (msaa != RS::VIEWPORT_MSAA_DISABLED) { fb.push_back(depth_msaa); @@ -135,7 +166,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() fb.push_back(voxelgi_buffer); } - depth_normal_roughness_voxelgi_fb = RD::get_singleton()->framebuffer_create(fb); + depth_normal_roughness_voxelgi_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, view_count); } } @@ -144,7 +175,25 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() { RD::get_singleton()->free(voxelgi_buffer); voxelgi_buffer = RID(); + if (view_count == 1) { + voxelgi_views[0] = RID(); + } else { + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(voxelgi_views[v]); + voxelgi_views[v] = RID(); + } + } + if (voxelgi_buffer_msaa.is_valid()) { + if (view_count == 1) { + voxelgi_msaa_views[0] = RID(); + } else { + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(voxelgi_msaa_views[v]); + voxelgi_msaa_views[v] = RID(); + } + } + RD::get_singleton()->free(voxelgi_buffer_msaa); voxelgi_buffer_msaa = RID(); } @@ -153,11 +202,35 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() { } if (color_msaa.is_valid()) { + if (view_count == 1) { + color_views[0] = RID(); + color_msaa_views[0] = RID(); + } else { + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(color_views[v]); + RD::get_singleton()->free(color_msaa_views[v]); + color_views[v] = RID(); + color_msaa_views[v] = RID(); + } + } + RD::get_singleton()->free(color_msaa); color_msaa = RID(); } if (depth_msaa.is_valid()) { + if (view_count == 1) { + depth_views[0] = RID(); + depth_msaa_views[0] = RID(); + } else { + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(depth_views[v]); + RD::get_singleton()->free(depth_msaa_views[v]); + depth_views[v] = RID(); + depth_msaa_views[v] = RID(); + } + } + RD::get_singleton()->free(depth_msaa); depth_msaa = RID(); } @@ -178,12 +251,31 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() { color_framebuffers.clear(); // Color pass framebuffers are freed automatically by their dependency relations if (normal_roughness_buffer.is_valid()) { + if (view_count == 1) { + normal_roughness_views[0] = RID(); + } else { + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(normal_roughness_views[v]); + normal_roughness_views[v] = RID(); + } + } + RD::get_singleton()->free(normal_roughness_buffer); + normal_roughness_buffer = RID(); + if (normal_roughness_buffer_msaa.is_valid()) { + if (view_count == 1) { + normal_roughness_msaa_views[0] = RID(); + } else { + for (uint32_t v = 0; v < view_count; v++) { + RD::get_singleton()->free(normal_roughness_msaa_views[v]); + normal_roughness_msaa_views[v] = RID(); + } + } RD::get_singleton()->free(normal_roughness_buffer_msaa); normal_roughness_buffer_msaa = RID(); } - normal_roughness_buffer = RID(); + depth_normal_roughness_fb = RID(); } @@ -254,11 +346,27 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c color_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); - tf.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::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; + tf.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; tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; depth_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + if (view_count == 1) { + // just reuse + color_views[0] = color; + depth_views[0] = depth; + color_msaa_views[0] = color_msaa; + depth_msaa_views[0] = depth_msaa; + } else { + // create slices + for (uint32_t v = 0; v < view_count; v++) { + color_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), color, v, 0); + depth_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), depth, v, 0); + color_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), color_msaa, v, 0); + depth_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), depth_msaa, v, 0); + } + } + { Vector<RID> fb; fb.push_back(color_msaa); @@ -308,6 +416,8 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb( } void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb) { + ERR_FAIL_COND_MSG(rb->view_count > 2, "Only support up to two views for roughness texture"); + if (rb->normal_roughness_buffer.is_valid()) { return; } @@ -316,10 +426,17 @@ void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferData tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; tf.width = rb->width; tf.height = rb->height; + if (rb->view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.array_layers = rb->view_count; + } else { + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + } tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { - tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; } else { tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; } @@ -330,16 +447,30 @@ void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferData Vector<RID> fb; fb.push_back(rb->depth); fb.push_back(rb->normal_roughness_buffer); - rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb); + rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count); } else { - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; tf.samples = rb->texture_samples; rb->normal_roughness_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); Vector<RID> fb; fb.push_back(rb->depth_msaa); fb.push_back(rb->normal_roughness_buffer_msaa); - rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb); + rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count); + } + + if (rb->view_count == 1) { + rb->normal_roughness_views[0] = rb->normal_roughness_buffer; + if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + rb->normal_roughness_msaa_views[0] = rb->normal_roughness_buffer_msaa; + } + } else { + for (uint32_t v = 0; v < rb->view_count; v++) { + rb->normal_roughness_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->normal_roughness_buffer, v, 0); + if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + rb->normal_roughness_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->normal_roughness_buffer_msaa, v, 0); + } + } } } @@ -503,22 +634,21 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS; } break; case PASS_MODE_SHADOW_DP: { - ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass"); + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_DP; } break; case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: { - ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for depth/roughness pass"); - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS; } break; case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: { - ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for voxel GI pass"); - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI; } break; case PASS_MODE_DEPTH_MATERIAL: { ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for material pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL; } break; case PASS_MODE_SDF: { + // Note, SDF is prepared in world space, this shouldn't be a multiview buffer even when stereoscopic rendering is used. ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for SDF pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_SDF; } break; @@ -683,15 +813,15 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat CameraMatrix projection = correction * p_render_data->cam_projection; //store camera into ubo - RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix); - RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); - RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix); + RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); + RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); + RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); + RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix); for (uint32_t v = 0; v < p_render_data->view_count; v++) { projection = correction * p_render_data->view_projection[v]; - RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); - RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x; scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y; @@ -707,10 +837,10 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.pancake_shadows = p_pancake_shadows; - RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); - RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); - RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); - RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; @@ -805,7 +935,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; - RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); + RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; @@ -876,15 +1006,15 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat CameraMatrix prev_projection = prev_correction * p_render_data->prev_cam_projection; //store camera into ubo - RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix); - RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix); - RendererStorageRD::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix); - RendererStorageRD::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix); + RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix); + RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix); + RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix); + RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix); for (uint32_t v = 0; v < p_render_data->view_count; v++) { prev_projection = prev_correction * p_render_data->view_projection[v]; - RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]); - RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]); } scene_state.prev_ubo.taa_jitter[0] = p_render_data->prev_taa_jitter.x; scene_state.prev_ubo.taa_jitter[1] = p_render_data->prev_taa_jitter.y; @@ -940,11 +1070,11 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i } if (inst->store_transform_cache) { - RendererStorageRD::store_transform(inst->transform, instance_data.transform); - RendererStorageRD::store_transform(inst->prev_transform, instance_data.prev_transform); + RendererRD::MaterialStorage::store_transform(inst->transform, instance_data.transform); + RendererRD::MaterialStorage::store_transform(inst->prev_transform, instance_data.prev_transform); } else { - RendererStorageRD::store_transform(Transform3D(), instance_data.transform); - RendererStorageRD::store_transform(Transform3D(), instance_data.prev_transform); + RendererRD::MaterialStorage::store_transform(Transform3D(), instance_data.transform); + RendererRD::MaterialStorage::store_transform(Transform3D(), instance_data.prev_transform); } instance_data.flags = inst->flags_cache; @@ -1268,7 +1398,7 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis; to_lm = to_lm.inverse().transposed(); //will transform normals - RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); + RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); scene_state.lightmap_ids[i] = p_lightmaps[i]; scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap); @@ -1323,9 +1453,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co using_voxelgi = true; } - if (p_render_data->view_count > 1) { - depth_pass_mode = PASS_MODE_DEPTH; - } else if (!p_render_data->environment.is_valid() && using_voxelgi) { + if (!p_render_data->environment.is_valid() && using_voxelgi) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI; } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) { if (environment_is_sdfgi_enabled(p_render_data->environment)) { @@ -1531,9 +1659,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (needs_pre_resolve) { RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); } - storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + for (uint32_t v = 0; v < render_buffer->view_count; v++) { + resolve_effects->resolve_gi(render_buffer->depth_msaa_views[v], render_buffer->normal_roughness_msaa_views[v], using_voxelgi ? render_buffer->voxelgi_msaa_views[v] : RID(), render_buffer->depth_views[v], render_buffer->normal_roughness_views[v], using_voxelgi ? render_buffer->voxelgi_views[v] : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + } } else if (finish_depth) { - storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + for (uint32_t v = 0; v < render_buffer->view_count; v++) { + resolve_effects->resolve_depth(render_buffer->depth_msaa_views[v], render_buffer->depth_views[v], Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + } } RD::get_singleton()->draw_command_end_label(); } @@ -1541,7 +1673,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co continue_depth = !finish_depth; } - _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->voxelgi_buffer : RID()); + RID null_rids[2]; + _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_views : null_rids, render_buffer ? render_buffer->voxelgi_buffer : RID()); RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); @@ -1604,18 +1737,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } if (debug_sdfgi_probes) { - //debug voxelgis + //debug sdfgi bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); CameraMatrix dc; dc.set_depth_correction(true); - CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); - RD::get_singleton()->draw_command_begin_label("Debug SDFGI"); - _debug_sdfgi_probes(p_render_data->render_buffers, draw_list, color_only_framebuffer, cm); - RD::get_singleton()->draw_command_end_label(); - RD::get_singleton()->draw_list_end(); + CameraMatrix cms[RendererSceneRender::MAX_RENDER_VIEWS]; + for (uint32_t v = 0; v < p_render_data->view_count; v++) { + cms[v] = (dc * p_render_data->view_projection[v]) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); + } + _debug_sdfgi_probes(p_render_data->render_buffers, color_only_framebuffer, p_render_data->view_count, cms, will_continue_color, will_continue_depth); } if (draw_sky || draw_sky_fog_only) { @@ -1635,14 +1767,20 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->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 < render_buffer->view_count; v++) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa_views[v], render_buffer->color_views[v]); + } + // TODO mame this do multiview if (using_separate_specular) { RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular); } } if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + for (uint32_t v = 0; v < render_buffer->view_count; v++) { + resolve_effects->resolve_depth(render_buffer->depth_msaa_views[v], render_buffer->depth_views[v], Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + } } if (using_separate_specular) { @@ -1661,7 +1799,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } else { //just mix specular back RENDER_TIMESTAMP("Merge Specular"); - storage->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID()); + RendererCompositorRD::singleton->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID()); } } @@ -1697,11 +1835,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Resolve"); if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color); - if (render_buffer->use_taa) { + for (uint32_t v = 0; v < render_buffer->view_count; v++) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa_views[v], render_buffer->color_views[v]); + resolve_effects->resolve_depth(render_buffer->depth_msaa_views[v], render_buffer->depth_views[v], Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); + } + if (render_buffer->use_taa) { // TODO make TAA stereo capable, this will need to be handled in a separate PR RD::get_singleton()->texture_resolve_multisample(render_buffer->velocity_buffer_msaa, render_buffer->velocity_buffer); } - storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); } RD::get_singleton()->draw_command_end_label(); @@ -2050,7 +2190,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i to_bounds.origin = p_bounds.position; to_bounds.basis.scale(p_bounds.size); - RendererStorageRD::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds); + RendererRD::MaterialStorage::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds); _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -2749,7 +2889,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet sdcache->surface_index = p_surface; if (ginstance->data->dirty_dependencies) { - storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker); + RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker); } //shadow @@ -2992,16 +3132,16 @@ void RenderForwardClustered::_update_dirty_geometry_instances() { } } -void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) { +void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) { switch (p_notification) { - case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: - case RendererStorage::DEPENDENCY_CHANGED_MESH: - case RendererStorage::DEPENDENCY_CHANGED_PARTICLES: - case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH: - case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: { + case Dependency::DEPENDENCY_CHANGED_MATERIAL: + case Dependency::DEPENDENCY_CHANGED_MESH: + case Dependency::DEPENDENCY_CHANGED_PARTICLES: + case Dependency::DEPENDENCY_CHANGED_MULTIMESH: + case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); } break; - case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { + case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata); if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { ginstance->instance_count = RendererRD::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base); @@ -3012,12 +3152,12 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStora } break; } } -void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) { +void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); } RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { - RS::InstanceType type = storage->get_base_type(p_base); + RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); GeometryInstanceForwardClustered *ginstance = geometry_instance_alloc.alloc(); @@ -3281,8 +3421,7 @@ void RenderForwardClustered::_update_shader_quality_settings() { _base_uniforms_changed(); //also need this } -RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) : - RendererSceneRenderRD(p_storage) { +RenderForwardClustered::RenderForwardClustered() { singleton = this; /* SCENE SHADER */ @@ -3314,15 +3453,22 @@ RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) : defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n"; } - scene_shader.init(p_storage, defines); + scene_shader.init(defines); } render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances"); _update_shader_quality_settings(); + + resolve_effects = memnew(RendererRD::Resolve()); } RenderForwardClustered::~RenderForwardClustered() { + if (resolve_effects != nullptr) { + memdelete(resolve_effects); + resolve_effects = nullptr; + } + directional_shadow_atlas_set_size(0); { 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 97f39164a4..9e1f1b9954 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -32,11 +32,12 @@ #define RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H #include "core/templates/paged_allocator.h" +#include "servers/rendering/renderer_rd/effects/resolve.h" #include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/utilities.h" namespace RendererSceneRenderImplementation { @@ -72,7 +73,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { RENDER_LIST_ALPHA, //used for transparent objects RENDER_LIST_SECONDARY, //used for shadows and other objects RENDER_LIST_MAX - }; /* Scene Shader */ @@ -99,7 +99,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID depth_msaa; RID specular_msaa; RID normal_roughness_buffer_msaa; - RID roughness_buffer_msaa; RID voxelgi_buffer_msaa; RID velocity_buffer_msaa; @@ -110,7 +109,17 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID specular_only_fb; int width, height; HashMap<uint32_t, RID> color_framebuffers; + + // for multiview uint32_t view_count; + RID color_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this + RID depth_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this + RID color_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; + RID depth_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; + RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS]; + RID normal_roughness_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; + RID voxelgi_views[RendererSceneRender::MAX_RENDER_VIEWS]; + RID voxelgi_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; RID render_sdfgi_uniform_set; void ensure_specular(); @@ -527,12 +536,12 @@ class RenderForwardClustered : public RendererSceneRenderRD { AABB aabb; bool use_dynamic_gi = false; - bool use_baked_light = false; + bool use_baked_light = true; bool cast_double_sided_shadows = false; bool mirror = false; bool dirty_dependencies = false; - RendererStorage::DependencyTracker dependency_tracker; + DependencyTracker dependency_tracker; }; Data *data = nullptr; @@ -541,8 +550,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { dirty_list_element(this) {} }; - static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker); - static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker); + static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); + static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker); SelfList<GeometryInstanceForwardClustered>::List geometry_instance_dirty_list; @@ -619,6 +628,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { virtual void _update_shader_quality_settings() override; + RendererRD::Resolve *resolve_effects = nullptr; + protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; @@ -672,7 +683,7 @@ public: virtual bool free(RID p_rid) override; - RenderForwardClustered(RendererStorageRD *p_storage); + RenderForwardClustered(); ~RenderForwardClustered(); }; } // namespace RendererSceneRenderImplementation diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index cfb30ef2f3..1951bfe915 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -282,6 +282,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL, SHADER_VERSION_DEPTH_PASS_WITH_SDF, SHADER_VERSION_DEPTH_PASS_MULTIVIEW, + SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW, + SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW, SHADER_VERSION_COLOR_PASS, }; @@ -349,9 +351,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW) { //none, leave empty - } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) { + } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW) { blend_state = blend_state_depth_normal_roughness; - } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) { + } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI || k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW) { blend_state = blend_state_depth_normal_roughness_giprobe; } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL) { blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way @@ -518,19 +520,20 @@ SceneShaderForwardClustered::~SceneShaderForwardClustered() { material_storage->material_free(default_material); } -void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const String p_defines) { +void SceneShaderForwardClustered::init(const String p_defines) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - storage = p_storage; { Vector<String> shader_versions; shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_DEPTH_PASS_DP shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS - shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE + shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n"); // SHADER_VERSION_DEPTH_PASS_WITH_SDF shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW + shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW + shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW Vector<String> color_pass_flags = { "\n#define MODE_SEPARATE_SPECULAR\n", // SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR @@ -553,6 +556,8 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin if (!RendererCompositorRD::singleton->is_xr_enabled()) { shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false); + shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW, false); + shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW, false); // TODO Add a way to enable/disable color pass flags } } @@ -621,7 +626,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin //builtins - actions.renames["TIME"] = "scene_data_block.data.time"; + actions.renames["TIME"] = "global_time"; actions.renames["PI"] = _MKSTR(Math_PI); actions.renames["TAU"] = _MKSTR(Math_TAU); actions.renames["E"] = _MKSTR(Math_E); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 79ccf10090..1cfe723174 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -32,7 +32,6 @@ #define RSSR_SCENE_SHADER_FC_H #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" namespace RendererSceneRenderImplementation { @@ -42,8 +41,6 @@ private: static SceneShaderForwardClustered *singleton; public: - RendererStorageRD *storage = nullptr; - enum ShaderVersion { SHADER_VERSION_DEPTH_PASS, SHADER_VERSION_DEPTH_PASS_DP, @@ -52,6 +49,8 @@ public: SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL, SHADER_VERSION_DEPTH_PASS_WITH_SDF, SHADER_VERSION_DEPTH_PASS_MULTIVIEW, + SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW, + SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW, SHADER_VERSION_COLOR_PASS, SHADER_VERSION_MAX }; @@ -72,6 +71,8 @@ public: PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL, PIPELINE_VERSION_DEPTH_PASS_WITH_SDF, PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW, + PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW, + PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW, PIPELINE_VERSION_COLOR_PASS, PIPELINE_VERSION_MAX }; @@ -245,7 +246,7 @@ public: SceneShaderForwardClustered(); ~SceneShaderForwardClustered(); - void init(RendererStorageRD *p_storage, const String p_defines); + void init(const String p_defines); void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants); }; 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 eae5685dd1..e1855ddb36 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -465,7 +465,7 @@ void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, c Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis; to_lm = to_lm.inverse().transposed(); //will transform normals - RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); + RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); scene_state.lightmap_ids[i] = p_lightmaps[i]; scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap); @@ -675,7 +675,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers } - _pre_opaque_render(p_render_data, false, false, false, RID(), RID()); + RID null_rids[2]; + _pre_opaque_render(p_render_data, false, false, false, null_rids, RID()); uint32_t spec_constant_base_flags = 0; @@ -1533,15 +1534,15 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, CameraMatrix projection = correction * p_render_data->cam_projection; //store camera into ubo - RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix); - RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); - RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix); + RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); + RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); + RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); + RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix); for (uint32_t v = 0; v < p_render_data->view_count; v++) { projection = correction * p_render_data->view_projection[v]; - RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); - RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x; scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y; @@ -1554,10 +1555,10 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, scene_state.ubo.pancake_shadows = p_pancake_shadows; - RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); - RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); - RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); - RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; @@ -1647,7 +1648,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; - RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); + RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; @@ -1865,9 +1866,9 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr GeometryInstanceForwardMobile::PushConstant push_constant; if (inst->store_transform_cache) { - RendererStorageRD::store_transform(inst->transform, push_constant.transform); + RendererRD::MaterialStorage::store_transform(inst->transform, push_constant.transform); } else { - RendererStorageRD::store_transform(Transform3D(), push_constant.transform); + RendererRD::MaterialStorage::store_transform(Transform3D(), push_constant.transform); } push_constant.flags = inst->flags_cache; @@ -2031,7 +2032,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr /* Geometry instance */ RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { - RS::InstanceType type = storage->get_base_type(p_base); + RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); GeometryInstanceForwardMobile *ginstance = geometry_instance_alloc.alloc(); @@ -2372,7 +2373,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI sdcache->surface_index = p_surface; if (ginstance->data->dirty_dependencies) { - storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker); + RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker); } //shadow @@ -2608,16 +2609,16 @@ void RenderForwardMobile::_update_dirty_geometry_instances() { } } -void RenderForwardMobile::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) { +void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) { switch (p_notification) { - case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: - case RendererStorage::DEPENDENCY_CHANGED_MESH: - case RendererStorage::DEPENDENCY_CHANGED_PARTICLES: - case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH: - case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: { + case Dependency::DEPENDENCY_CHANGED_MATERIAL: + case Dependency::DEPENDENCY_CHANGED_MESH: + case Dependency::DEPENDENCY_CHANGED_PARTICLES: + case Dependency::DEPENDENCY_CHANGED_MULTIMESH: + case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); } break; - case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { + case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata); if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { ginstance->instance_count = RendererRD::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base); @@ -2628,7 +2629,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(RendererStorage: } break; } } -void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) { +void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); } @@ -2694,8 +2695,7 @@ void RenderForwardMobile::_update_shader_quality_settings() { _base_uniforms_changed(); //also need this } -RenderForwardMobile::RenderForwardMobile(RendererStorageRD *p_storage) : - RendererSceneRenderRD(p_storage) { +RenderForwardMobile::RenderForwardMobile() { singleton = this; sky.set_texture_format(_render_buffers_get_color_format()); @@ -2727,7 +2727,7 @@ RenderForwardMobile::RenderForwardMobile(RendererStorageRD *p_storage) : defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n"; } - scene_shader.init(p_storage, defines); + scene_shader.init(defines); // !BAS! maybe we need a mobile version of this setting? render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances"); 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 1b2df0ab9f..473a58045c 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -35,7 +35,7 @@ #include "servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/utilities.h" namespace RendererSceneRenderImplementation { @@ -591,13 +591,13 @@ protected: RID material_overlay; AABB aabb; - bool use_baked_light = false; + bool use_baked_light = true; bool cast_double_sided_shadows = false; // bool mirror = false; // !BAS! Does not seem used, we already have this in the main struct bool dirty_dependencies = false; - RendererStorage::DependencyTracker dependency_tracker; + DependencyTracker dependency_tracker; }; Data *data = nullptr; @@ -613,8 +613,8 @@ protected: public: virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override; - static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker); - static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker); + static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); + static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker); SelfList<GeometryInstanceForwardMobile>::List geometry_instance_dirty_list; @@ -668,7 +668,7 @@ public: virtual bool is_volumetric_supported() const override; virtual uint32_t get_max_elements() const override; - RenderForwardMobile(RendererStorageRD *p_storage); + RenderForwardMobile(); ~RenderForwardMobile(); }; } // namespace RendererSceneRenderImplementation diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index f66ad529de..dd00dc2bf9 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -466,8 +466,7 @@ SceneShaderForwardMobile::SceneShaderForwardMobile() { singleton = this; } -void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p_defines) { - storage = p_storage; +void SceneShaderForwardMobile::init(const String p_defines) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); /* SCENE SHADER */ diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index f325d5c0a5..88c2143b09 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -32,7 +32,6 @@ #define RSSR_SCENE_SHADER_FM_H #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h" namespace RendererSceneRenderImplementation { @@ -40,7 +39,6 @@ namespace RendererSceneRenderImplementation { class SceneShaderForwardMobile { private: static SceneShaderForwardMobile *singleton; - RendererStorageRD *storage = nullptr; public: enum ShaderVersion { @@ -207,7 +205,7 @@ public: Vector<RD::PipelineSpecializationConstant> default_specialization_constants; - void init(RendererStorageRD *p_storage, const String p_defines); + void init(const String p_defines); void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants); }; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 3c2f3f8a42..b87b189d53 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2270,10 +2270,9 @@ void RendererCanvasRenderRD::set_time(double p_time) { void RendererCanvasRenderRD::update() { } -RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { +RendererCanvasRenderRD::RendererCanvasRenderRD() { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - storage = p_storage; { //create default samplers diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 04881ce7e6..2ab5a7c831 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -34,15 +34,13 @@ #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/shader_compiler.h" class RendererCanvasRenderRD : public RendererCanvasRender { - RendererStorageRD *storage = nullptr; - enum { BASE_UNIFORM_SET = 0, MATERIAL_UNIFORM_SET = 1, @@ -462,7 +460,7 @@ public: void set_time(double p_time); void update(); bool free(RID p_rid); - RendererCanvasRenderRD(RendererStorageRD *p_storage); + RendererCanvasRenderRD(); ~RendererCanvasRenderRD(); }; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index 759b8690eb..a61172c8f5 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -154,12 +154,14 @@ uint64_t RendererCompositorRD::frame = 1; void RendererCompositorRD::finalize() { memdelete(scene); memdelete(canvas); - memdelete(storage); + memdelete(effects); + memdelete(fog); memdelete(particles_storage); memdelete(light_storage); memdelete(mesh_storage); memdelete(material_storage); memdelete(texture_storage); + memdelete(utilities); //only need to erase these, the rest are erased by cascade blit.shader.version_free(blit.shader_version); @@ -287,28 +289,29 @@ RendererCompositorRD::RendererCompositorRD() { singleton = this; + utilities = memnew(RendererRD::Utilities); texture_storage = memnew(RendererRD::TextureStorage); material_storage = memnew(RendererRD::MaterialStorage); mesh_storage = memnew(RendererRD::MeshStorage); light_storage = memnew(RendererRD::LightStorage); particles_storage = memnew(RendererRD::ParticlesStorage); - storage = memnew(RendererStorageRD); - canvas = memnew(RendererCanvasRenderRD(storage)); + fog = memnew(RendererRD::Fog); + canvas = memnew(RendererCanvasRenderRD()); back_end = (bool)(int)GLOBAL_GET("rendering/vulkan/rendering/back_end"); uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); if (back_end || textures_per_stage < 48) { - scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile(storage)); + scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile()); } else { // back_end == false // default to our high end renderer - scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered(storage)); + scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered()); } scene->init(); // now we're ready to create our effects, - storage->init_effects(!scene->_render_buffers_can_be_storage()); + effects = memnew(EffectsRD(!scene->_render_buffers_can_be_storage())); } RendererCompositorRD::~RendererCompositorRD() { diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index aefc189f68..2be55743fb 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -34,28 +34,32 @@ #include "core/os/os.h" #include "core/templates/thread_work_pool.h" #include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/effects_rd.h" +#include "servers/rendering/renderer_rd/environment/fog.h" #include "servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h" #include "servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h" #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/light_storage.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h" #include "servers/rendering/renderer_rd/storage_rd/particles_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/utilities.h" #include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" class RendererCompositorRD : public RendererCompositor { protected: UniformSetCacheRD *uniform_set_cache = nullptr; RendererCanvasRenderRD *canvas = nullptr; + RendererRD::Utilities *utilities = nullptr; RendererRD::LightStorage *light_storage = nullptr; RendererRD::MaterialStorage *material_storage = nullptr; RendererRD::MeshStorage *mesh_storage = nullptr; RendererRD::ParticlesStorage *particles_storage = nullptr; RendererRD::TextureStorage *texture_storage = nullptr; - RendererStorageRD *storage = nullptr; + RendererRD::Fog *fog = nullptr; + EffectsRD *effects = nullptr; RendererSceneRenderRD *scene = nullptr; enum BlitMode { @@ -98,12 +102,18 @@ protected: static uint64_t frame; public: - RendererLightStorage *get_light_storage() { return light_storage; }; - RendererMaterialStorage *get_material_storage() { return material_storage; }; - RendererMeshStorage *get_mesh_storage() { return mesh_storage; }; - RendererParticlesStorage *get_particles_storage() { return particles_storage; }; - RendererTextureStorage *get_texture_storage() { return texture_storage; }; - RendererStorage *get_storage() { return storage; } + RendererUtilities *get_utilities() { return utilities; }; + RendererLightStorage *get_light_storage() { return light_storage; } + RendererMaterialStorage *get_material_storage() { return material_storage; } + RendererMeshStorage *get_mesh_storage() { return mesh_storage; } + RendererParticlesStorage *get_particles_storage() { return particles_storage; } + RendererTextureStorage *get_texture_storage() { return texture_storage; } + RendererGI *get_gi() { + ERR_FAIL_NULL_V(scene, nullptr); + return scene->get_gi(); + } + RendererFog *get_fog() { return fog; } + EffectsRD *get_effects() { return effects; } RendererCanvasRender *get_canvas() { return canvas; } RendererSceneRender *get_scene() { return scene; } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index a50a05d905..5185d537ec 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/environment/fog.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_default.h" @@ -74,7 +75,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment rb->sdfgi = nullptr; } - RendererSceneGIRD::SDFGI *sdfgi = rb->sdfgi; + RendererRD::GI::SDFGI *sdfgi = rb->sdfgi; if (sdfgi == nullptr) { // re-create rb->sdfgi = gi.create_sdfgi(env, p_world_position, requested_history_size); @@ -95,9 +96,9 @@ int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers) int dirty_count = 0; for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { - const RendererSceneGIRD::SDFGI::Cascade &c = rb->sdfgi->cascades[i]; + const RendererRD::GI::SDFGI::Cascade &c = rb->sdfgi->cascades[i]; - if (c.dirty_regions == RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL) { + if (c.dirty_regions == RendererRD::GI::SDFGI::Cascade::DIRTY_ALL) { dirty_count++; } else { for (int j = 0; j < 3; j++) { @@ -534,7 +535,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba return panorama; } else { const float bg_energy = env->bg_energy; - Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? storage->get_default_clear_color() : env->bg_color); + Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : env->bg_color); panorama_color = panorama_color.srgb_to_linear(); panorama_color.r *= bg_energy; panorama_color.g *= bg_energy; @@ -759,7 +760,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc } atlas->reflections.resize(atlas->count); for (int i = 0; i < atlas->count; i++) { - atlas->reflections.write[i].data.update_reflection_data(storage, atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format()); + atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format()); for (int j = 0; j < 6; j++) { atlas->reflections.write[i].fbs[j] = reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer); } @@ -829,7 +830,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) { // Using real time reflections, all roughness is done in one step - atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(storage, false); + atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(false); rpi->rendering = false; rpi->processing_side = 0; rpi->processing_layer = 1; @@ -837,7 +838,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins } if (rpi->processing_layer > 1) { - atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality); + atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality); rpi->processing_layer++; if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) { rpi->rendering = false; @@ -848,7 +849,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins return false; } else { - atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality); + atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality); } rpi->processing_side++; @@ -1533,7 +1534,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this); } -void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { +void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -1541,7 +1542,7 @@ void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawLi return; //nothing to debug } - rb->sdfgi->debug_probes(p_draw_list, p_framebuffer, p_camera_with_transform); + rb->sdfgi->debug_probes(p_framebuffer, p_view_count, p_camera_with_transforms, p_will_continue_color, p_will_continue_depth); } //////////////////////////////// @@ -1950,17 +1951,7 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { rb->taa.prev_velocity = RID(); } - if (rb->ambient_buffer.is_valid()) { - RD::get_singleton()->free(rb->ambient_buffer); - RD::get_singleton()->free(rb->reflection_buffer); - rb->ambient_buffer = RID(); - rb->reflection_buffer = RID(); - } - - if (rb->gi.voxel_gi_buffer.is_valid()) { - RD::get_singleton()->free(rb->gi.voxel_gi_buffer); - rb->gi.voxel_gi_buffer = RID(); - } + rb->rbgi.free(); } void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { @@ -1978,7 +1969,7 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri _allocate_blur_textures(rb); } - storage->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality); + RendererCompositorRD::singleton->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality); } void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { @@ -1989,7 +1980,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb if (!can_use_effects) { //just copy - storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID()); + RendererCompositorRD::singleton->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID()); return; } @@ -2029,8 +2020,8 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb _allocate_blur_textures(rb); } - storage->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection); - storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture); + RendererCompositorRD::singleton->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection); + RendererCompositorRD::singleton->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture); } void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { @@ -2155,7 +2146,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen settings.half_screen_size = Size2i(buffer_width, buffer_height); settings.quarter_screen_size = Size2i(half_width, half_height); - storage->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set); + RendererCompositorRD::singleton->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set); } void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform) { @@ -2316,7 +2307,7 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen transform.set_origin(Vector3(0.0, 0.0, 0.0)); CameraMatrix last_frame_projection = rb->ss_effects.last_frame_projection * CameraMatrix(rb->ss_effects.last_frame_transform.affine_inverse()) * CameraMatrix(transform) * projection.inverse(); - storage->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set); + RendererCompositorRD::singleton->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set); rb->ss_effects.last_frame_projection = projection; rb->ss_effects.last_frame_transform = transform; } @@ -2364,7 +2355,7 @@ void RendererSceneRenderRD::_process_taa(RID p_render_buffers, RID p_velocity_bu RD::get_singleton()->draw_command_begin_label("TAA"); if (!just_allocated) { - storage->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far); + RendererCompositorRD::singleton->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far); copy_effects->copy_to_rect(rb->taa.temp, rb->internal_texture, Rect2(0, 0, rb->internal_width, rb->internal_height)); } @@ -2502,9 +2493,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende double step = env->auto_exp_speed * time_step; if (can_use_storage) { - storage->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); } else { - storage->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); } // Swap final reduce with prev luminance. SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]); @@ -2649,7 +2640,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (can_use_effects && can_use_storage && (rb->internal_width != rb->width || rb->internal_height != rb->height)) { RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale"); - storage->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness); + RendererCompositorRD::singleton->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness); RD::get_singleton()->draw_command_end_label(); } @@ -2796,11 +2787,11 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID copy_effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); } - if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) { + if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->rbgi.ambient_buffer.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - RID ambient_texture = rb->ambient_buffer; - RID reflection_texture = rb->reflection_buffer; - copy_effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture); + RID ambient_texture = rb->rbgi.ambient_buffer; + RID reflection_texture = rb->rbgi.reflection_buffer; + copy_effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture, rb->view_count > 1); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) { @@ -2869,10 +2860,10 @@ RID RendererSceneRenderRD::render_buffers_get_ssil_texture(RID p_render_buffers) RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); - if (rb->gi.voxel_gi_buffer.is_null()) { - rb->gi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::VoxelGIData) * RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES); + if (rb->rbgi.voxel_gi_buffer.is_null()) { + rb->rbgi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererRD::GI::VoxelGIData) * RendererRD::GI::MAX_VOXEL_GI_INSTANCES); } - return rb->gi.voxel_gi_buffer; + return rb->rbgi.voxel_gi_buffer; } RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { @@ -2882,12 +2873,13 @@ RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); - return rb->ambient_buffer; + + return rb->rbgi.ambient_buffer; } RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); - return rb->reflection_buffer; + return rb->rbgi.reflection_buffer; } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const { @@ -2925,7 +2917,7 @@ Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RI ERR_FAIL_COND_V(!rb, Vector3i()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3i()); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3i()); - int32_t probe_divisor = rb->sdfgi->cascade_size / RendererSceneGIRD::SDFGI::PROBE_DIVISOR; + int32_t probe_divisor = rb->sdfgi->cascade_size / RendererRD::GI::SDFGI::PROBE_DIVISOR; return rb->sdfgi->cascades[p_cascade].position / probe_divisor; } @@ -3106,7 +3098,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; } if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) { - tf.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::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; + tf.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; } else { tf.format = RD::DATA_FORMAT_R32_SFLOAT; } @@ -3138,14 +3130,14 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p if (rb->view_count == 1) { // copy as a convenience RenderBuffers::View view; - view.view_texture = rb->internal_texture; + view.view_texture = rb->texture; view.view_depth = rb->depth_texture; view.view_fb = rb->texture_fb; rb->views.push_back(view); } else { for (uint32_t i = 0; i < rb->view_count; i++) { RenderBuffers::View view; - view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->internal_texture, i, 0); + view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->texture, i, 0); view.view_depth = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->depth_texture, i, 0); if (!_render_buffers_can_be_storage()) { @@ -3373,7 +3365,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti Transform3D transform = rpi->transform; Transform3D proj = (p_camera_inverse_transform * transform).inverse(); - RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix); + RendererRD::MaterialStorage::store_transform(proj, reflection_ubo.local_matrix); if (current_cluster_builder != nullptr) { current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, transform, extents); @@ -3491,7 +3483,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.shadow_transmittance_bias[j] = light_storage->light_get_transmittance_bias(base) * bias_scale; light_data.shadow_z_range[j] = li->shadow_transform[j].farplane; light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin; - RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]); + RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrices[j]); Vector2 uv_scale = li->shadow_transform[j].uv_scale; uv_scale *= atlas_rect.size; //adapt to atlas size @@ -3736,7 +3728,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const if (type == RS::LIGHT_OMNI) { Transform3D proj = (inverse_transform * light_transform).inverse(); - RendererStorageRD::store_transform(proj, light_data.shadow_matrix); + RendererRD::MaterialStorage::store_transform(proj, light_data.shadow_matrix); if (size > 0.0 && light_data.soft_shadow_scale > 0.0) { // Only enable PCSS-like soft shadows if blurring is enabled. @@ -3755,7 +3747,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const bias.set_light_bias(); CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview; - RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix); + RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix); if (size > 0.0 && light_data.soft_shadow_scale > 0.0) { // Only enable PCSS-like soft shadows if blurring is enabled. @@ -3874,7 +3866,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D scale_xform; scale_xform.basis.scale(decal_extents); Transform3D to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse(); - RendererStorageRD::store_transform(to_decal_xform, dd.xform); + RendererRD::MaterialStorage::store_transform(to_decal_xform, dd.xform); Vector3 normal = xform.basis.get_column(Vector3::AXIS_Y).normalized(); normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine @@ -3912,7 +3904,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const dd.normal_rect[3] = rect.size.y; Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized(); - RendererStorageRD::store_basis_3x4(normal_xform, dd.normal_xform); + RendererRD::MaterialStorage::store_basis_3x4(normal_xform, dd.normal_xform); } else { dd.normal_rect[0] = 0; dd.normal_rect[1] = 0; @@ -4159,6 +4151,9 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) { RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set); } + if (rb->volumetric_fog->process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) { + RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set_density); + } if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) { RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set); } @@ -4332,8 +4327,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; - storage->store_transform(to_prev_cam_view, params.to_prev_view); - storage->store_transform(p_cam_transform, params.transform); + RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); + RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform); RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); @@ -4395,7 +4390,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e ERR_FAIL_COND(!fog_volume_instance); RID fog_volume = fog_volume_instance->volume; - RID fog_material = storage->fog_volume_get_material(fog_volume); + RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume); FogMaterialData *material = nullptr; @@ -4424,8 +4419,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e Vector3i kernel_size = Vector3i(); Vector3 position = fog_volume_instance->transform.get_origin(); - RS::FogVolumeShape volume_type = storage->fog_volume_get_shape(fog_volume); - Vector3 extents = storage->fog_volume_get_extents(fog_volume); + RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); + Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume); if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) { // Local fog volume. @@ -4468,8 +4463,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e volumetric_fog.push_constant.corner[0] = min.x; volumetric_fog.push_constant.corner[1] = min.y; volumetric_fog.push_constant.corner[2] = min.z; - volumetric_fog.push_constant.shape = uint32_t(storage->fog_volume_get_shape(fog_volume)); - storage->store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform); + volumetric_fog.push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume)); + RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline); @@ -4491,7 +4486,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::get_singleton()->compute_list_end(); } - if (rb->volumetric_fog->process_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) { + if (rb->volumetric_fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) { //re create uniform set if needed Vector<RD::Uniform> uniforms; Vector<RD::Uniform> copy_uniforms; @@ -4615,8 +4610,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; - for (int i = 0; i < RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES; i++) { - u.append_id(rb->gi.voxel_gi_textures[i]); + for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) { + u.append_id(rb->rbgi.voxel_gi_textures[i]); } uniforms.push_back(u); copy_uniforms.push_back(u); @@ -4691,7 +4686,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0); - rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); + rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); RID aux7 = uniforms.write[7].get_id(0); RID aux8 = uniforms.write[8].get_id(0); @@ -4699,7 +4694,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e uniforms.write[7].set_id(0, aux8); uniforms.write[8].set_id(0, aux7); - rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, 0), 0); + rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); + + uniforms.remove_at(8); + uniforms.write[7].set_id(0, aux7); + rb->volumetric_fog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); } bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr); @@ -4810,7 +4809,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; - storage->store_transform(to_prev_cam_view, params.to_prev_view); + RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; @@ -4831,7 +4830,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e Basis sky_transform = env->sky_orientation; sky_transform = sky_transform.inverse() * p_cam_transform.basis; - RendererStorageRD::store_transform_3x3(sky_transform, params.radiance_inverse_xform); + RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform); RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog"); @@ -4842,7 +4841,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set_density, 0); if (using_sdfgi) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); @@ -4930,7 +4929,7 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo } } -void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) { +void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID *p_normal_roughness_views, RID p_voxel_gi_buffer) { // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); @@ -5005,7 +5004,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //start GI if (render_gi) { - gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_voxel_gi_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this); + gi.process_gi(p_render_data->render_buffers, p_normal_roughness_views, p_voxel_gi_buffer, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this); } //Do shadow rendering (in parallel with GI) @@ -5042,15 +5041,17 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool invalidate_uniform_set = true; } - storage->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection); + RendererCompositorRD::singleton->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection); } if (p_use_ssao) { - _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection); + // TODO make these proper stereo and thus use p_normal_roughness_views correctly + _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_views[0], p_render_data->cam_projection); } if (p_use_ssil) { - _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection, p_render_data->cam_transform); + // TODO make these proper stereo and thus use p_normal_roughness_views correctly + _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_views[0], p_render_data->cam_projection, p_render_data->cam_transform); } } @@ -5189,13 +5190,13 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData if (p_render_buffers.is_valid()) { clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target); } else { - clear_color = storage->get_default_clear_color(); + clear_color = RSG::texture_storage->get_default_clear_color(); } //assign render indices to voxel_gi_instances if (is_dynamic_gi_supported()) { for (uint32_t i = 0; i < (uint32_t)p_voxel_gi_instances.size(); i++) { - RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]); + RendererRD::GI::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]); if (voxel_gi_inst) { voxel_gi_inst->render_index = i; } @@ -5249,7 +5250,13 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData _render_buffers_debug_draw(p_render_buffers, p_shadow_atlas, p_occluder_debug_tex); if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SDFGI && rb != nullptr && rb->sdfgi != nullptr) { - rb->sdfgi->debug_draw(render_data.cam_projection, render_data.cam_transform, rb->width, rb->height, rb->render_target, rb->texture); + Vector<RID> view_rids; + + for (int v = 0; v < rb->views.size(); v++) { + view_rids.push_back(rb->views[v].view_texture); + } + + rb->sdfgi->debug_draw(render_data.view_count, render_data.view_projection, render_data.cam_transform, rb->width, rb->height, rb->render_target, rb->texture, view_rids); } } } @@ -5439,9 +5446,9 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, Rect2 atlas_rect_norm = atlas_rect; atlas_rect_norm.position /= float(atlas_size); atlas_rect_norm.size /= float(atlas_size); - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false); + copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false); atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true); + copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true); //restore transform so it can be properly used light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0); @@ -5518,7 +5525,7 @@ bool RendererSceneRenderRD::free(RID p_rid) { } else if (lightmap_instance_owner.owns(p_rid)) { lightmap_instance_owner.free(p_rid); } else if (gi.voxel_gi_instance_owner.owns(p_rid)) { - RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid); + RendererRD::GI::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid); if (voxel_gi->texture.is_valid()) { RD::get_singleton()->free(voxel_gi->texture); RD::get_singleton()->free(voxel_gi->write_buffer); @@ -5748,8 +5755,7 @@ uint32_t RendererSceneRenderRD::get_max_elements() const { return GLOBAL_GET("rendering/limits/cluster_builder/max_clustered_elements"); } -RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { - storage = p_storage; +RendererSceneRenderRD::RendererSceneRenderRD() { singleton = this; } @@ -5763,12 +5769,12 @@ void RendererSceneRenderRD::init() { /* SKY SHADER */ - sky.init(storage); + sky.init(); /* GI */ if (is_dynamic_gi_supported()) { - gi.init(storage, &sky); + gi.init(&sky); } { //decals diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index a90c165d83..e8296882c9 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -38,10 +38,9 @@ #include "servers/rendering/renderer_rd/effects/bokeh_dof.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" #include "servers/rendering/renderer_rd/effects/tone_mapper.h" +#include "servers/rendering/renderer_rd/environment/gi.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_gi_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h" #include "servers/rendering/renderer_scene.h" @@ -99,10 +98,9 @@ struct RenderDataRD { class RendererSceneRenderRD : public RendererSceneRender { friend RendererSceneSkyRD; - friend RendererSceneGIRD; + friend RendererRD::GI; protected: - RendererStorageRD *storage = nullptr; RendererRD::BokehDOF *bokeh_dof = nullptr; RendererRD::CopyEffects *copy_effects = nullptr; RendererRD::ToneMapper *tone_mapper = nullptr; @@ -131,7 +129,7 @@ protected: virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; - void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform); + void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void _debug_draw_cluster(RID p_render_buffers); RenderBufferData *render_buffers_get_data(RID p_render_buffers); @@ -151,7 +149,7 @@ protected: void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi); void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi); - void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer); + void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID *p_normal_roughness_views, RID p_voxel_gi_buffer); void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data); void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data); @@ -163,7 +161,7 @@ protected: PagedArrayPool<GeometryInstance *> cull_argument_pool; PagedArray<GeometryInstance *> cull_argument; //need this to exist - RendererSceneGIRD gi; + RendererRD::GI gi; RendererSceneSkyRD sky; RendererSceneEnvironmentRD *get_environment(RID p_environment) { @@ -503,9 +501,9 @@ private: }; Vector<View> views; - RendererSceneGIRD::SDFGI *sdfgi = nullptr; + RendererRD::GI::SDFGI *sdfgi = nullptr; VolumetricFog *volumetric_fog = nullptr; - RendererSceneGIRD::RenderBuffersGI gi; + RendererRD::GI::RenderBuffersGI rbgi; ClusterBuilderRD *cluster_builder = nullptr; @@ -606,9 +604,6 @@ private: RID temp; RID prev_velocity; // Last frame velocity buffer } taa; - - RID ambient_buffer; - RID reflection_buffer; }; /* GI */ @@ -802,6 +797,7 @@ private: RID fog_uniform_set; RID copy_uniform_set; + RID process_uniform_set_density; RID process_uniform_set; RID process_uniform_set2; RID sdfgi_uniform_set; @@ -997,6 +993,10 @@ public: virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0; virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; + /* GI */ + + RendererRD::GI *get_gi() { return &gi; } + /* SHADOW ATLAS API */ virtual RID shadow_atlas_create() override; @@ -1510,7 +1510,7 @@ public: void init(); - RendererSceneRenderRD(RendererStorageRD *p_storage); + RendererSceneRenderRD(); ~RendererSceneRenderRD(); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 3a237dbd8c..73175d3cf3 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -37,6 +37,7 @@ #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_default.h" +#include "servers/rendering/rendering_server_globals.h" //////////////////////////////////////////////////////////////////////////////// // SKY SHADER @@ -329,13 +330,13 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() { coefficient_buffer = RID(); } -void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { +void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { //recreate radiance and all data int mipmaps = p_mipmaps; uint32_t w = p_size, h = p_size; - EffectsRD *effects = p_storage->get_effects(); + EffectsRD *effects = RendererCompositorRD::singleton->get_effects(); ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); bool prefer_raster_effects = effects->get_prefer_raster_effects(); @@ -437,20 +438,20 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR } } -void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays) { - EffectsRD *effects = p_storage->get_effects(); - ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); - bool prefer_raster_effects = effects->get_prefer_raster_effects(); +void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { + RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); if (prefer_raster_effects) { RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); for (int k = 0; k < 6; k++) { - effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size); + copy_effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size); } for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { for (int k = 0; k < 6; k++) { - effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size); + copy_effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size); } } RD::get_singleton()->draw_command_end_label(); // Downsample Radiance @@ -459,24 +460,24 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS RD::get_singleton()->draw_command_begin_label("filter radiance map into array heads"); for (int i = 0; i < layers.size(); i++) { for (int k = 0; k < 6; k++) { - effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[i].mipmaps[0].framebuffers[k], k, i); + copy_effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[i].mipmaps[0].framebuffers[k], k, i); } } } else { RD::get_singleton()->draw_command_begin_label("filter radiance map into mipmaps directly"); for (int j = 0; j < layers[0].mipmaps.size(); j++) { for (int k = 0; k < 6; k++) { - effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[0].mipmaps[j].framebuffers[k], k, j); + copy_effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[0].mipmaps[j].framebuffers[k], k, j); } } } RD::get_singleton()->draw_command_end_label(); // Filter radiance } else { RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); - effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); + copy_effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { - effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); + copy_effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); } RD::get_singleton()->draw_command_end_label(); // Downsample Radiance Vector<RID> views; @@ -490,26 +491,26 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS } } RD::get_singleton()->draw_command_begin_label("Fast filter radiance"); - effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays); + copy_effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays); RD::get_singleton()->draw_command_end_label(); // Filter radiance } } -void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { - EffectsRD *effects = p_storage->get_effects(); - ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); - bool prefer_raster_effects = effects->get_prefer_raster_effects(); +void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { + RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); if (prefer_raster_effects) { if (p_base_layer == 1) { RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); for (int k = 0; k < 6; k++) { - effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size); + copy_effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size); } for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { for (int k = 0; k < 6; k++) { - effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size); + copy_effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size); } } RD::get_singleton()->draw_command_end_label(); // Downsample Radiance @@ -518,7 +519,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren RD::get_singleton()->draw_command_begin_label("High Quality filter radiance"); if (p_use_arrays) { for (int k = 0; k < 6; k++) { - effects->cubemap_roughness_raster( + copy_effects->cubemap_roughness_raster( downsampled_radiance_cubemap, layers[p_base_layer].mipmaps[0].framebuffers[k], k, @@ -528,7 +529,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren } } else { for (int k = 0; k < 6; k++) { - effects->cubemap_roughness_raster( + copy_effects->cubemap_roughness_raster( downsampled_radiance_cubemap, layers[0].mipmaps[p_base_layer].framebuffers[k], k, @@ -540,19 +541,19 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren } else { if (p_base_layer == 1) { RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); - effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); + copy_effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { - effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); + copy_effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); } RD::get_singleton()->draw_command_end_label(); // Downsample Radiance } RD::get_singleton()->draw_command_begin_label("High Quality filter radiance"); if (p_use_arrays) { - effects->cubemap_roughness(downsampled_radiance_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x); + copy_effects->cubemap_roughness(downsampled_radiance_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x); } else { - effects->cubemap_roughness( + copy_effects->cubemap_roughness( downsampled_radiance_cubemap, layers[0].views[p_base_layer], p_cube_side, @@ -564,10 +565,10 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren RD::get_singleton()->draw_command_end_label(); // Filter radiance } -void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) { - EffectsRD *effects = p_storage->get_effects(); - ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); - bool prefer_raster_effects = effects->get_prefer_raster_effects(); +void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { + RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); RD::get_singleton()->draw_command_begin_label("Update Radiance Cubemap Array Mipmaps"); for (int i = p_start; i < p_end; i++) { @@ -577,11 +578,11 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStora if (prefer_raster_effects) { for (int k = 0; k < 6; k++) { RID framebuffer = layers[i].mipmaps[j + 1].framebuffers[k]; - effects->cubemap_downsample_raster(view, framebuffer, k, size); + copy_effects->cubemap_downsample_raster(view, framebuffer, k, size); } } else { RID texture = layers[i].views[j + 1]; - effects->cubemap_downsample(view, texture, size); + copy_effects->cubemap_downsample(view, texture, size); } } } @@ -591,7 +592,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStora //////////////////////////////////////////////////////////////////////////////// // RendererSceneSkyRD::Sky -void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) { +void RendererSceneSkyRD::Sky::free() { if (radiance.is_valid()) { RD::get_singleton()->free(radiance); radiance = RID(); @@ -614,12 +615,12 @@ void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) { } if (material.is_valid()) { - p_storage->free(material); + RSG::material_storage->material_free(material); material = RID(); } } -RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd) { +RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) { @@ -795,10 +796,9 @@ RendererSceneSkyRD::RendererSceneSkyRD() { sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections"); } -void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { +void RendererSceneSkyRD::init() { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - storage = p_storage; { // Start with the directional lights for the sky @@ -1387,7 +1387,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier); @@ -1406,7 +1406,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier); @@ -1421,7 +1421,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap"); for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier); @@ -1430,22 +1430,22 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM RD::get_singleton()->draw_command_end_label(); if (sky_mode == RS::SKY_MODE_REALTIME) { - sky->reflection.create_reflection_fast_filter(storage, sky_use_cubemap_array); + sky->reflection.create_reflection_fast_filter(sky_use_cubemap_array); if (sky_use_cubemap_array) { - sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size()); + sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size()); } } else { if (update_single_frame) { for (int i = 1; i < max_processing_layer; i++) { - sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, i, sky_ggx_samples_quality); + sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, i, sky_ggx_samples_quality); } if (sky_use_cubemap_array) { - sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size()); + sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size()); } } else { if (sky_use_cubemap_array) { // Multi-Frame so just update the first array level - sky->reflection.update_reflection_mipmaps(storage, 0, 1); + sky->reflection.update_reflection_mipmaps(0, 1); } } sky->processing_layer = 1; @@ -1455,10 +1455,10 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM } else { if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) { - sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality); + sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality); if (sky_use_cubemap_array) { - sky->reflection.update_reflection_mipmaps(storage, sky->processing_layer, sky->processing_layer + 1); + sky->reflection.update_reflection_mipmaps(sky->processing_layer, sky->processing_layer + 1); } sky->processing_layer++; @@ -1536,7 +1536,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont if (shader_data->uses_quarter_res) { PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd); Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); @@ -1549,7 +1549,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont if (shader_data->uses_half_res) { PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd); Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); @@ -1563,7 +1563,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont RID texture_uniform_set; if (sky) { - texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd); + texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd); } else { texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set; } @@ -1634,7 +1634,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u if (shader_data->uses_quarter_res) { PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd); Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); @@ -1647,7 +1647,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u if (shader_data->uses_half_res) { PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; - RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd); Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); @@ -1729,7 +1729,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme RID texture_uniform_set; if (sky) { - texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd); + texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd); } else { texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set; } @@ -1777,7 +1777,7 @@ void RendererSceneSkyRD::update_dirty_skys() { sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - sky->reflection.update_reflection_data(storage, sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); + sky->reflection.update_reflection_data(sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); } else { //regular cubemap, lower quality (aliasing, less memory) @@ -1792,7 +1792,7 @@ void RendererSceneSkyRD::update_dirty_skys() { sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - sky->reflection.update_reflection_data(storage, sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); + sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); } texture_set_dirty = true; } @@ -1872,7 +1872,7 @@ void RendererSceneSkyRD::free_sky(RID p_sky) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); - sky->free(storage); + sky->free(); sky_owner.free(p_sky); } diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index 83a8fe6e77..a8ee406abc 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -33,11 +33,13 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/shader_compiler.h" // Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound class RendererSceneRenderRD; @@ -63,7 +65,6 @@ public: }; private: - RendererStorageRD *storage = nullptr; RD::DataFormat texture_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; RID index_buffer; @@ -211,10 +212,10 @@ public: Vector<Layer> layers; void clear_reflection_data(); - void update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format); - void create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays); - void create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality); - void update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end); + void update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format); + void create_reflection_fast_filter(bool p_use_arrays); + void create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality); + void update_reflection_mipmaps(int p_start, int p_end); }; /* Sky shader */ @@ -267,9 +268,9 @@ public: Vector3 prev_position; float prev_time; - void free(RendererStorageRD *p_storage); + void free(); - RID get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd); + RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd); bool set_radiance_size(int p_radiance_size); bool set_mode(RS::SkyMode p_mode); bool set_material(RID p_material); @@ -289,7 +290,7 @@ public: static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader); RendererSceneSkyRD(); - void init(RendererStorageRD *p_storage); + void init(); void set_texture_format(RD::DataFormat p_texture_format); ~RendererSceneSkyRD(); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp deleted file mode 100644 index d5166c6905..0000000000 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ /dev/null @@ -1,751 +0,0 @@ -/*************************************************************************/ -/* renderer_storage_rd.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "renderer_storage_rd.h" - -#include "core/config/engine.h" -#include "core/config/project_settings.h" -#include "core/io/resource_loader.h" -#include "core/math/math_defs.h" -#include "renderer_compositor_rd.h" -#include "servers/rendering/renderer_rd/storage_rd/light_storage.h" -#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h" -#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h" -#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" -#include "servers/rendering/rendering_server_globals.h" -#include "servers/rendering/shader_language.h" - -/* FOG VOLUMES */ - -RID RendererStorageRD::fog_volume_allocate() { - return fog_volume_owner.allocate_rid(); -} -void RendererStorageRD::fog_volume_initialize(RID p_rid) { - fog_volume_owner.initialize_rid(p_rid, FogVolume()); -} - -void RendererStorageRD::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND(!fog_volume); - - if (p_shape == fog_volume->shape) { - return; - } - - fog_volume->shape = p_shape; - fog_volume->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); -} - -void RendererStorageRD::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND(!fog_volume); - - fog_volume->extents = p_extents; - fog_volume->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); -} - -void RendererStorageRD::fog_volume_set_material(RID p_fog_volume, RID p_material) { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND(!fog_volume); - fog_volume->material = p_material; -} - -RID RendererStorageRD::fog_volume_get_material(RID p_fog_volume) const { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND_V(!fog_volume, RID()); - - return fog_volume->material; -} - -RS::FogVolumeShape RendererStorageRD::fog_volume_get_shape(RID p_fog_volume) const { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX); - - return fog_volume->shape; -} - -AABB RendererStorageRD::fog_volume_get_aabb(RID p_fog_volume) const { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND_V(!fog_volume, AABB()); - - switch (fog_volume->shape) { - case RS::FOG_VOLUME_SHAPE_ELLIPSOID: - case RS::FOG_VOLUME_SHAPE_CONE: - case RS::FOG_VOLUME_SHAPE_CYLINDER: - case RS::FOG_VOLUME_SHAPE_BOX: { - AABB aabb; - aabb.position = -fog_volume->extents; - aabb.size = fog_volume->extents * 2; - return aabb; - } - default: { - // Need some size otherwise will get culled - return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); - } - } - - return AABB(); -} - -Vector3 RendererStorageRD::fog_volume_get_extents(RID p_fog_volume) const { - const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); - ERR_FAIL_COND_V(!fog_volume, Vector3()); - return fog_volume->extents; -} - -/* VISIBILITY NOTIFIER */ - -RID RendererStorageRD::visibility_notifier_allocate() { - return visibility_notifier_owner.allocate_rid(); -} -void RendererStorageRD::visibility_notifier_initialize(RID p_notifier) { - visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier()); -} -void RendererStorageRD::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) { - VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); - ERR_FAIL_COND(!vn); - vn->aabb = p_aabb; - vn->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); -} -void RendererStorageRD::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) { - VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); - ERR_FAIL_COND(!vn); - vn->enter_callback = p_enter_callbable; - vn->exit_callback = p_exit_callable; -} - -AABB RendererStorageRD::visibility_notifier_get_aabb(RID p_notifier) const { - const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); - ERR_FAIL_COND_V(!vn, AABB()); - return vn->aabb; -} -void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) { - VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); - ERR_FAIL_COND(!vn); - - if (p_enter) { - if (!vn->enter_callback.is_null()) { - if (p_deferred) { - vn->enter_callback.call_deferred(nullptr, 0); - } else { - Variant r; - Callable::CallError ce; - vn->enter_callback.call(nullptr, 0, r, ce); - } - } - } else { - if (!vn->exit_callback.is_null()) { - if (p_deferred) { - vn->exit_callback.call_deferred(nullptr, 0); - } else { - Variant r; - Callable::CallError ce; - vn->exit_callback.call(nullptr, 0, r, ce); - } - } - } -} - -/* VOXEL GI */ - -RID RendererStorageRD::voxel_gi_allocate() { - return voxel_gi_owner.allocate_rid(); -} -void RendererStorageRD::voxel_gi_initialize(RID p_voxel_gi) { - voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI()); -} - -void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - if (voxel_gi->octree_buffer.is_valid()) { - RD::get_singleton()->free(voxel_gi->octree_buffer); - RD::get_singleton()->free(voxel_gi->data_buffer); - if (voxel_gi->sdf_texture.is_valid()) { - RD::get_singleton()->free(voxel_gi->sdf_texture); - } - - voxel_gi->sdf_texture = RID(); - voxel_gi->octree_buffer = RID(); - voxel_gi->data_buffer = RID(); - voxel_gi->octree_buffer_size = 0; - voxel_gi->data_buffer_size = 0; - voxel_gi->cell_count = 0; - } - - voxel_gi->to_cell_xform = p_to_cell_xform; - voxel_gi->bounds = p_aabb; - voxel_gi->octree_size = p_octree_size; - voxel_gi->level_counts = p_level_counts; - - if (p_octree_cells.size()) { - ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32 - - uint32_t cell_count = p_octree_cells.size() / 32; - - ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches - - voxel_gi->cell_count = cell_count; - voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells); - voxel_gi->octree_buffer_size = p_octree_cells.size(); - voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells); - voxel_gi->data_buffer_size = p_data_cells.size(); - - if (p_distance_field.size()) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = voxel_gi->octree_size.x; - tf.height = voxel_gi->octree_size.y; - tf.depth = voxel_gi->octree_size.z; - tf.texture_type = RD::TEXTURE_TYPE_3D; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - Vector<Vector<uint8_t>> s; - s.push_back(p_distance_field); - voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s); - } -#if 0 - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = voxel_gi->octree_size.x; - tf.height = voxel_gi->octree_size.y; - tf.depth = voxel_gi->octree_size.z; - tf.type = RD::TEXTURE_TYPE_3D; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; - tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM); - tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT); - voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } - RID shared_tex; - { - RD::TextureView tv; - tv.format_override = RD::DATA_FORMAT_R8_UINT; - shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture); - } - //update SDF texture - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 1; - u.append_id(voxel_gi->octree_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 2; - u.append_id(voxel_gi->data_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 3; - u.append_id(shared_tex); - uniforms.push_back(u); - } - - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0); - - { - uint32_t push_constant[4] = { 0, 0, 0, 0 }; - - for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) { - push_constant[0] += voxel_gi->level_counts[i]; - } - push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1]; - - print_line("offset: " + itos(push_constant[0])); - print_line("size: " + itos(push_constant[1])); - //create SDF - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4); - RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4); - RD::get_singleton()->compute_list_end(); - } - - RD::get_singleton()->free(uniform_set); - RD::get_singleton()->free(shared_tex); - } -#endif - } - - voxel_gi->version++; - voxel_gi->data_version++; - - voxel_gi->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); -} - -AABB RendererStorageRD::voxel_gi_get_bounds(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, AABB()); - - return voxel_gi->bounds; -} - -Vector3i RendererStorageRD::voxel_gi_get_octree_size(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, Vector3i()); - return voxel_gi->octree_size; -} - -Vector<uint8_t> RendererStorageRD::voxel_gi_get_octree_cells(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); - - if (voxel_gi->octree_buffer.is_valid()) { - return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer); - } - return Vector<uint8_t>(); -} - -Vector<uint8_t> RendererStorageRD::voxel_gi_get_data_cells(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); - - if (voxel_gi->data_buffer.is_valid()) { - return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer); - } - return Vector<uint8_t>(); -} - -Vector<uint8_t> RendererStorageRD::voxel_gi_get_distance_field(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); - - if (voxel_gi->data_buffer.is_valid()) { - return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0); - } - return Vector<uint8_t>(); -} - -Vector<int> RendererStorageRD::voxel_gi_get_level_counts(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, Vector<int>()); - - return voxel_gi->level_counts; -} - -Transform3D RendererStorageRD::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, Transform3D()); - - return voxel_gi->to_cell_xform; -} - -void RendererStorageRD::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->dynamic_range = p_range; - voxel_gi->version++; -} - -float RendererStorageRD::voxel_gi_get_dynamic_range(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - - return voxel_gi->dynamic_range; -} - -void RendererStorageRD::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->propagation = p_range; - voxel_gi->version++; -} - -float RendererStorageRD::voxel_gi_get_propagation(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->propagation; -} - -void RendererStorageRD::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->energy = p_energy; -} - -float RendererStorageRD::voxel_gi_get_energy(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->energy; -} - -void RendererStorageRD::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->bias = p_bias; -} - -float RendererStorageRD::voxel_gi_get_bias(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->bias; -} - -void RendererStorageRD::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->normal_bias = p_normal_bias; -} - -float RendererStorageRD::voxel_gi_get_normal_bias(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->normal_bias; -} - -void RendererStorageRD::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->anisotropy_strength = p_strength; -} - -float RendererStorageRD::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->anisotropy_strength; -} - -void RendererStorageRD::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->interior = p_enable; -} - -void RendererStorageRD::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND(!voxel_gi); - - voxel_gi->use_two_bounces = p_enable; - voxel_gi->version++; -} - -bool RendererStorageRD::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, false); - return voxel_gi->use_two_bounces; -} - -bool RendererStorageRD::voxel_gi_is_interior(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->interior; -} - -uint32_t RendererStorageRD::voxel_gi_get_version(RID p_voxel_gi) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->version; -} - -uint32_t RendererStorageRD::voxel_gi_get_data_version(RID p_voxel_gi) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, 0); - return voxel_gi->data_version; -} - -RID RendererStorageRD::voxel_gi_get_octree_buffer(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, RID()); - return voxel_gi->octree_buffer; -} - -RID RendererStorageRD::voxel_gi_get_data_buffer(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, RID()); - return voxel_gi->data_buffer; -} - -RID RendererStorageRD::voxel_gi_get_sdf_texture(RID p_voxel_gi) { - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_COND_V(!voxel_gi, RID()); - - return voxel_gi->sdf_texture; -} - -/* misc */ - -void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) { - if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_base)) { - RendererRD::Mesh *mesh = RendererRD::MeshStorage::get_singleton()->get_mesh(p_base); - p_instance->update_dependency(&mesh->dependency); - } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_base)) { - RendererRD::MultiMesh *multimesh = RendererRD::MeshStorage::get_singleton()->get_multimesh(p_base); - p_instance->update_dependency(&multimesh->dependency); - if (multimesh->mesh.is_valid()) { - base_update_dependency(multimesh->mesh, p_instance); - } - } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_base)) { - RendererRD::ReflectionProbe *rp = RendererRD::LightStorage::get_singleton()->get_reflection_probe(p_base); - p_instance->update_dependency(&rp->dependency); - } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_base)) { - RendererRD::Decal *decal = RendererRD::TextureStorage::get_singleton()->get_decal(p_base); - p_instance->update_dependency(&decal->dependency); - } else if (voxel_gi_owner.owns(p_base)) { - VoxelGI *gip = voxel_gi_owner.get_or_null(p_base); - p_instance->update_dependency(&gip->dependency); - } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_base)) { - RendererRD::Lightmap *lm = RendererRD::LightStorage::get_singleton()->get_lightmap(p_base); - p_instance->update_dependency(&lm->dependency); - } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_base)) { - RendererRD::Light *l = RendererRD::LightStorage::get_singleton()->get_light(p_base); - p_instance->update_dependency(&l->dependency); - } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_base)) { - RendererRD::Particles *p = RendererRD::ParticlesStorage::get_singleton()->get_particles(p_base); - p_instance->update_dependency(&p->dependency); - } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) { - RendererRD::ParticlesCollision *pc = RendererRD::ParticlesStorage::get_singleton()->get_particles_collision(p_base); - p_instance->update_dependency(&pc->dependency); - } else if (fog_volume_owner.owns(p_base)) { - FogVolume *fv = fog_volume_owner.get_or_null(p_base); - p_instance->update_dependency(&fv->dependency); - } else if (visibility_notifier_owner.owns(p_base)) { - VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_base); - p_instance->update_dependency(&vn->dependency); - } -} - -RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const { - if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) { - return RS::INSTANCE_MESH; - } - if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) { - return RS::INSTANCE_MULTIMESH; - } - if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) { - return RS::INSTANCE_REFLECTION_PROBE; - } - if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) { - return RS::INSTANCE_DECAL; - } - if (voxel_gi_owner.owns(p_rid)) { - return RS::INSTANCE_VOXEL_GI; - } - if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) { - return RS::INSTANCE_LIGHT; - } - if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) { - return RS::INSTANCE_LIGHTMAP; - } - if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) { - return RS::INSTANCE_PARTICLES; - } - if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) { - return RS::INSTANCE_PARTICLES_COLLISION; - } - if (fog_volume_owner.owns(p_rid)) { - return RS::INSTANCE_FOG_VOLUME; - } - if (visibility_notifier_owner.owns(p_rid)) { - return RS::INSTANCE_VISIBLITY_NOTIFIER; - } - - return RS::INSTANCE_NONE; -} - -void RendererStorageRD::update_dirty_resources() { - RendererRD::MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update - RendererRD::MaterialStorage::get_singleton()->_update_queued_materials(); - RendererRD::MeshStorage::get_singleton()->_update_dirty_multimeshes(); - RendererRD::MeshStorage::get_singleton()->_update_dirty_skeletons(); - RendererRD::TextureStorage::get_singleton()->update_decal_atlas(); -} - -bool RendererStorageRD::has_os_feature(const String &p_feature) const { - if (!RD::get_singleton()) { - return false; - } - - if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { - return true; - } - - if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { - return true; - } - - if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { - return true; - } - - if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { - return true; - } - - return false; -} - -bool RendererStorageRD::free(RID p_rid) { - if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) { - RendererRD::TextureStorage::get_singleton()->texture_free(p_rid); - } else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { - RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid); - } else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) { - RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid); - } else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) { - RendererRD::MaterialStorage::get_singleton()->material_free(p_rid); - } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) { - RendererRD::MeshStorage::get_singleton()->mesh_free(p_rid); - } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) { - RendererRD::MeshStorage::get_singleton()->mesh_instance_free(p_rid); - } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) { - RendererRD::MeshStorage::get_singleton()->multimesh_free(p_rid); - } else if (RendererRD::MeshStorage::get_singleton()->owns_skeleton(p_rid)) { - RendererRD::MeshStorage::get_singleton()->skeleton_free(p_rid); - } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) { - RendererRD::LightStorage::get_singleton()->reflection_probe_free(p_rid); - } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) { - RendererRD::TextureStorage::get_singleton()->decal_free(p_rid); - } else if (voxel_gi_owner.owns(p_rid)) { - voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate - VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid); - voxel_gi->dependency.deleted_notify(p_rid); - voxel_gi_owner.free(p_rid); - } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) { - RendererRD::LightStorage::get_singleton()->lightmap_free(p_rid); - } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) { - RendererRD::LightStorage::get_singleton()->light_free(p_rid); - } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) { - RendererRD::ParticlesStorage::get_singleton()->particles_free(p_rid); - } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) { - RendererRD::ParticlesStorage::get_singleton()->particles_collision_free(p_rid); - } else if (visibility_notifier_owner.owns(p_rid)) { - VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_rid); - vn->dependency.deleted_notify(p_rid); - visibility_notifier_owner.free(p_rid); - } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) { - RendererRD::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid); - } else if (fog_volume_owner.owns(p_rid)) { - FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid); - fog_volume->dependency.deleted_notify(p_rid); - fog_volume_owner.free(p_rid); - } else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) { - RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid); - } else { - return false; - } - - return true; -} - -void RendererStorageRD::init_effects(bool p_prefer_raster_effects) { - effects = memnew(EffectsRD(p_prefer_raster_effects)); -} - -EffectsRD *RendererStorageRD::get_effects() { - ERR_FAIL_NULL_V_MSG(effects, nullptr, "Effects haven't been initialised yet."); - return effects; -} - -void RendererStorageRD::capture_timestamps_begin() { - RD::get_singleton()->capture_timestamp("Frame Begin"); -} - -void RendererStorageRD::capture_timestamp(const String &p_name) { - RD::get_singleton()->capture_timestamp(p_name); -} - -uint32_t RendererStorageRD::get_captured_timestamps_count() const { - return RD::get_singleton()->get_captured_timestamps_count(); -} - -uint64_t RendererStorageRD::get_captured_timestamps_frame() const { - return RD::get_singleton()->get_captured_timestamps_frame(); -} - -uint64_t RendererStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const { - return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index); -} - -uint64_t RendererStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const { - return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index); -} - -String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const { - return RD::get_singleton()->get_captured_timestamp_name(p_index); -} - -void RendererStorageRD::update_memory_info() { - texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES); - buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS); - total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL); -} -uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) { - if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) { - return texture_mem_cache; - } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) { - return buffer_mem_cache; - } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) { - return total_mem_cache; - } - return 0; -} - -String RendererStorageRD::get_video_adapter_name() const { - return RenderingDevice::get_singleton()->get_device_name(); -} - -String RendererStorageRD::get_video_adapter_vendor() const { - return RenderingDevice::get_singleton()->get_device_vendor_name(); -} - -RenderingDevice::DeviceType RendererStorageRD::get_video_adapter_type() const { - return RenderingDevice::get_singleton()->get_device_type(); -} - -String RendererStorageRD::get_video_adapter_api_version() const { - return RenderingDevice::get_singleton()->get_device_api_version(); -} - -RendererStorageRD *RendererStorageRD::base_singleton = nullptr; - -RendererStorageRD::RendererStorageRD() { - base_singleton = this; -} - -RendererStorageRD::~RendererStorageRD() { - if (effects) { - memdelete(effects); - effects = nullptr; - } -} diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h deleted file mode 100644 index 07fae45a26..0000000000 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************/ -/* renderer_storage_rd.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RENDERING_SERVER_STORAGE_RD_H -#define RENDERING_SERVER_STORAGE_RD_H - -#include "core/templates/list.h" -#include "core/templates/local_vector.h" -#include "core/templates/rid_owner.h" -#include "servers/rendering/renderer_compositor.h" -#include "servers/rendering/renderer_rd/effects_rd.h" -#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h" -#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" -#include "servers/rendering/renderer_scene_render.h" -#include "servers/rendering/rendering_device.h" -#include "servers/rendering/shader_compiler.h" - -class RendererStorageRD : public RendererStorage { -public: - static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) { - p_array[0] = p_mtx.basis.rows[0][0]; - p_array[1] = p_mtx.basis.rows[1][0]; - p_array[2] = p_mtx.basis.rows[2][0]; - p_array[3] = 0; - p_array[4] = p_mtx.basis.rows[0][1]; - p_array[5] = p_mtx.basis.rows[1][1]; - p_array[6] = p_mtx.basis.rows[2][1]; - p_array[7] = 0; - p_array[8] = p_mtx.basis.rows[0][2]; - p_array[9] = p_mtx.basis.rows[1][2]; - p_array[10] = p_mtx.basis.rows[2][2]; - p_array[11] = 0; - p_array[12] = p_mtx.origin.x; - p_array[13] = p_mtx.origin.y; - p_array[14] = p_mtx.origin.z; - p_array[15] = 1; - } - - static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) { - p_array[0] = p_mtx.rows[0][0]; - p_array[1] = p_mtx.rows[1][0]; - p_array[2] = p_mtx.rows[2][0]; - p_array[3] = 0; - p_array[4] = p_mtx.rows[0][1]; - p_array[5] = p_mtx.rows[1][1]; - p_array[6] = p_mtx.rows[2][1]; - p_array[7] = 0; - p_array[8] = p_mtx.rows[0][2]; - p_array[9] = p_mtx.rows[1][2]; - p_array[10] = p_mtx.rows[2][2]; - p_array[11] = 0; - } - - static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) { - p_array[0] = p_mtx.rows[0][0]; - p_array[1] = p_mtx.rows[1][0]; - p_array[2] = p_mtx.rows[2][0]; - p_array[3] = 0; - p_array[4] = p_mtx.rows[0][1]; - p_array[5] = p_mtx.rows[1][1]; - p_array[6] = p_mtx.rows[2][1]; - p_array[7] = 0; - p_array[8] = p_mtx.rows[0][2]; - p_array[9] = p_mtx.rows[1][2]; - p_array[10] = p_mtx.rows[2][2]; - p_array[11] = 0; - } - - static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) { - p_array[0] = p_mtx.basis.rows[0][0]; - p_array[1] = p_mtx.basis.rows[0][1]; - p_array[2] = p_mtx.basis.rows[0][2]; - p_array[3] = p_mtx.origin.x; - p_array[4] = p_mtx.basis.rows[1][0]; - p_array[5] = p_mtx.basis.rows[1][1]; - p_array[6] = p_mtx.basis.rows[1][2]; - p_array[7] = p_mtx.origin.y; - p_array[8] = p_mtx.basis.rows[2][0]; - p_array[9] = p_mtx.basis.rows[2][1]; - p_array[10] = p_mtx.basis.rows[2][2]; - p_array[11] = p_mtx.origin.z; - } - - static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - p_array[i * 4 + j] = p_mtx.matrix[i][j]; - } - } - } - - static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) { - for (int i = 0; i < 128; i++) { - p_array[i] = p_kernel[i]; - } - } - -private: - /* FOG VOLUMES */ - - struct FogVolume { - RID material; - Vector3 extents = Vector3(1, 1, 1); - - RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX; - - Dependency dependency; - }; - - mutable RID_Owner<FogVolume, true> fog_volume_owner; - - /* visibility_notifier */ - - struct VisibilityNotifier { - AABB aabb; - Callable enter_callback; - Callable exit_callback; - Dependency dependency; - }; - - mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner; - - /* VOXEL GI */ - - struct VoxelGI { - RID octree_buffer; - RID data_buffer; - RID sdf_texture; - - uint32_t octree_buffer_size = 0; - uint32_t data_buffer_size = 0; - - Vector<int> level_counts; - - int cell_count = 0; - - Transform3D to_cell_xform; - AABB bounds; - Vector3i octree_size; - - float dynamic_range = 2.0; - float energy = 1.0; - float bias = 1.4; - float normal_bias = 0.0; - float propagation = 0.7; - bool interior = false; - bool use_two_bounces = false; - - float anisotropy_strength = 0.5; - - uint32_t version = 1; - uint32_t data_version = 1; - - Dependency dependency; - }; - - mutable RID_Owner<VoxelGI, true> voxel_gi_owner; - - /* EFFECTS */ - - EffectsRD *effects = nullptr; - -public: - //internal usage - - void base_update_dependency(RID p_base, DependencyTracker *p_instance); - - /* VOXEL GI API */ - - RID voxel_gi_allocate(); - void voxel_gi_initialize(RID p_voxel_gi); - - void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); - - AABB voxel_gi_get_bounds(RID p_voxel_gi) const; - Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const; - Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const; - Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const; - Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const; - - Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const; - Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const; - - void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range); - float voxel_gi_get_dynamic_range(RID p_voxel_gi) const; - - void voxel_gi_set_propagation(RID p_voxel_gi, float p_range); - float voxel_gi_get_propagation(RID p_voxel_gi) const; - - void voxel_gi_set_energy(RID p_voxel_gi, float p_energy); - float voxel_gi_get_energy(RID p_voxel_gi) const; - - void voxel_gi_set_bias(RID p_voxel_gi, float p_bias); - float voxel_gi_get_bias(RID p_voxel_gi) const; - - void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range); - float voxel_gi_get_normal_bias(RID p_voxel_gi) const; - - void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable); - bool voxel_gi_is_interior(RID p_voxel_gi) const; - - void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable); - bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const; - - void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength); - float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const; - - uint32_t voxel_gi_get_version(RID p_probe); - uint32_t voxel_gi_get_data_version(RID p_probe); - - RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const; - RID voxel_gi_get_data_buffer(RID p_voxel_gi) const; - - RID voxel_gi_get_sdf_texture(RID p_voxel_gi); - - /* FOG VOLUMES */ - - virtual RID fog_volume_allocate(); - virtual void fog_volume_initialize(RID p_rid); - - virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape); - virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents); - virtual void fog_volume_set_material(RID p_fog_volume, RID p_material); - virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const; - virtual RID fog_volume_get_material(RID p_fog_volume) const; - virtual AABB fog_volume_get_aabb(RID p_fog_volume) const; - virtual Vector3 fog_volume_get_extents(RID p_fog_volume) const; - - /* VISIBILITY NOTIFIER */ - - virtual RID visibility_notifier_allocate(); - virtual void visibility_notifier_initialize(RID p_notifier); - virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb); - virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable); - - virtual AABB visibility_notifier_get_aabb(RID p_notifier) const; - virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred); - - RS::InstanceType get_base_type(RID p_rid) const; - - bool free(RID p_rid); - - bool has_os_feature(const String &p_feature) const; - - void update_dirty_resources(); - - void set_debug_generate_wireframes(bool p_generate) {} - - //keep cached since it can be called form any thread - uint64_t texture_mem_cache = 0; - uint64_t buffer_mem_cache = 0; - uint64_t total_mem_cache = 0; - - virtual void update_memory_info(); - virtual uint64_t get_rendering_info(RS::RenderingInfo p_info); - - String get_video_adapter_name() const; - String get_video_adapter_vendor() const; - RenderingDevice::DeviceType get_video_adapter_type() const; - String get_video_adapter_api_version() const; - - virtual void capture_timestamps_begin(); - virtual void capture_timestamp(const String &p_name); - virtual uint32_t get_captured_timestamps_count() const; - virtual uint64_t get_captured_timestamps_frame() const; - virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const; - virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const; - virtual String get_captured_timestamp_name(uint32_t p_index) const; - - static RendererStorageRD *base_singleton; - - void init_effects(bool p_prefer_raster_effects); - EffectsRD *get_effects(); - - RendererStorageRD(); - ~RendererStorageRD(); -}; - -#endif // RASTERIZER_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub index acb843bfb6..d352743908 100644 --- a/servers/rendering/renderer_rd/shaders/SCsub +++ b/servers/rendering/renderer_rd/shaders/SCsub @@ -10,10 +10,11 @@ if "RD_GLSL" in env["BUILDERS"]: glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] # make sure we recompile shaders if include files change - env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files) + env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"]) # compile shaders for glsl_file in glsl_files: env.RD_GLSL(glsl_file) SConscript("effects/SCsub") +SConscript("environment/SCsub") diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub index fc513d3fb9..741da8fe69 100644 --- a/servers/rendering/renderer_rd/shaders/effects/SCsub +++ b/servers/rendering/renderer_rd/shaders/effects/SCsub @@ -10,7 +10,7 @@ if "RD_GLSL" in env["BUILDERS"]: glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] # make sure we recompile shaders if include files change - env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files) + env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"]) # compile shaders for glsl_file in glsl_files: diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl index e77d0de719..e77d0de719 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler.glsl index 63f0ce690e..63f0ce690e 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_inc.glsl index 641e0906f5..641e0906f5 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_inc.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl index 0828ffd921..0828ffd921 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl index 2a774b0eb4..2a774b0eb4 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl index 0990dc7c2f..0990dc7c2f 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl index 1d46f59408..1d46f59408 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl index 1bee428a6f..1bee428a6f 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl index c29accd8a7..c29accd8a7 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/effects/resolve.glsl index 0e086331c0..0e086331c0 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/resolve.glsl diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub new file mode 100644 index 0000000000..741da8fe69 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/environment/SCsub @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +Import("env") + +if "RD_GLSL" in env["BUILDERS"]: + # find all include files + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + + # find all shader code(all glsl files excluding our include files) + glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] + + # make sure we recompile shaders if include files change + env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"]) + + # compile shaders + for glsl_file in glsl_files: + env.RD_GLSL(glsl_file) diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl index 0c7f08813b..f687d50a2d 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl @@ -86,19 +86,29 @@ voxel_gi_instances; layout(set = 0, binding = 17) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; -layout(push_constant, std430) uniform Params { - ivec2 screen_size; - float z_near; - float z_far; +layout(set = 0, binding = 18, std140) uniform SceneData { + mat4x4 inv_projection[2]; + mat4x4 cam_transform; + vec4 eye_offset[2]; - vec4 proj_info; + ivec2 screen_size; + float pad1; + float pad2; +} +scene_data; +layout(push_constant, std430) uniform Params { + uint view_index; uint max_voxel_gi_instances; bool high_quality_vct; bool orthogonal; - uint pad; - mat3x4 cam_rotation; + vec4 proj_info; + + float z_near; + float z_far; + float pad1; + float pad2; } params; @@ -130,6 +140,16 @@ vec4 blend_color(vec4 src, vec4 dst) { } vec3 reconstruct_position(ivec2 screen_pos) { +#ifdef USE_MULTIVIEW + vec4 pos; + pos.xy = (2.0 * vec2(screen_pos) / vec2(scene_data.screen_size)) - 1.0; + pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r * 2.0 - 1.0; + pos.w = 1.0; + + pos = scene_data.inv_projection[params.view_index] * pos; + + return pos.xyz / pos.w; +#else vec3 pos; pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r; @@ -147,6 +167,7 @@ vec3 reconstruct_position(ivec2 screen_pos) { } return pos; +#endif } void sdfvoxel_gi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) { @@ -579,9 +600,10 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref if (normal.length() > 0.5) { //valid normal, can do GI float roughness = normal_roughness.w; - vertex = mat3(params.cam_rotation) * vertex; - normal = normalize(mat3(params.cam_rotation) * normal); - vec3 reflection = normalize(reflect(normalize(vertex), normal)); + vec3 view = -normalize(mat3(scene_data.cam_transform) * (vertex - scene_data.eye_offset[params.view_index].xyz)); + vertex = mat3(scene_data.cam_transform) * vertex; + normal = normalize(mat3(scene_data.cam_transform) * normal); + vec3 reflection = normalize(reflect(-view, normal)); #ifdef USE_SDFGI sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light); @@ -629,7 +651,7 @@ void main() { #ifdef MODE_HALF_RES pos <<= 1; #endif - if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(pos, scene_data.screen_size))) { //too large, do nothing return; } diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl index 802a410825..af5f7d0a58 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl @@ -40,10 +40,13 @@ layout(push_constant, std430) uniform Params { bool use_occlusion; float y_mult; - vec3 cam_extent; int probe_axis_size; + float z_near; + float reserved1; + float reserved2; mat4 cam_transform; + mat4 inv_projection; } params; @@ -81,8 +84,9 @@ void main() { { ray_pos = params.cam_transform[3].xyz; - ray_dir.xy = params.cam_extent.xy * ((vec2(screen_pos) / vec2(params.screen_size)) * 2.0 - 1.0); - ray_dir.z = params.cam_extent.z; + ray_dir.xy = ((vec2(screen_pos) / vec2(params.screen_size)) * 2.0 - 1.0); + ray_dir.z = params.z_near; + ray_dir = (params.inv_projection * vec4(ray_dir, 1.0)).xyz; ray_dir = normalize(mat3(params.cam_transform) * ray_dir); } diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl index e0be0bca12..75b1ad2130 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl @@ -2,13 +2,28 @@ #version 450 +#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) +#extension GL_EXT_multiview : enable +#endif + +#ifdef USE_MULTIVIEW +#ifdef has_VK_KHR_multiview +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +// !BAS! This needs to become an input once we implement our fallback! +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#else // USE_MULTIVIEW +// Set to zero, not supported in non stereo +#define ViewIndex 0 +#endif //USE_MULTIVIEW + #VERSION_DEFINES #define MAX_CASCADES 8 +#define MAX_VIEWS 2 layout(push_constant, std430) uniform Params { - mat4 projection; - uint band_power; uint sections_in_band; uint band_mask; @@ -68,6 +83,11 @@ cascades; layout(set = 0, binding = 4) uniform texture3D occlusion_texture; layout(set = 0, binding = 3) uniform sampler linear_sampler; +layout(set = 0, binding = 5, std140) uniform SceneData { + mat4 projection[MAX_VIEWS]; +} +scene_data; + void main() { #ifdef MODE_PROBES probe_index = gl_InstanceIndex; @@ -85,7 +105,7 @@ void main() { vertex += (cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size) / vec3(1.0, params.y_mult, 1.0); - gl_Position = params.projection * vec4(vertex, 1.0); + gl_Position = scene_data.projection[ViewIndex] * vec4(vertex, 1.0); #endif #ifdef MODE_VISIBILITY @@ -144,7 +164,7 @@ void main() { visibility = dot(texelFetch(sampler3D(occlusion_texture, linear_sampler), tex_pos, 0), layer_axis[occlusion_layer]); - gl_Position = params.projection * vec4(vertex, 1.0); + gl_Position = scene_data.projection[ViewIndex] * vec4(vertex, 1.0); #endif } @@ -153,16 +173,32 @@ void main() { #version 450 +#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) +#extension GL_EXT_multiview : enable +#endif + +#ifdef USE_MULTIVIEW +#ifdef has_VK_KHR_multiview +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +// !BAS! This needs to become an input once we implement our fallback! +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#else // USE_MULTIVIEW +// Set to zero, not supported in non stereo +#define ViewIndex 0 +#endif //USE_MULTIVIEW + #VERSION_DEFINES +#define MAX_VIEWS 2 + layout(location = 0) out vec4 frag_color; layout(set = 0, binding = 2) uniform texture2DArray lightprobe_texture; layout(set = 0, binding = 3) uniform sampler linear_sampler; layout(push_constant, std430) uniform Params { - mat4 projection; - uint band_power; uint sections_in_band; uint band_mask; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl index b95fad650e..b95fad650e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl index 9c03297f5c..9c03297f5c 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl index bce98f4054..bce98f4054 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl b/servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl index 577c6d0cd0..577c6d0cd0 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl index fd7a2bf8ad..fd7a2bf8ad 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_sdf.glsl index 47a611a543..47a611a543 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_sdf.glsl diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index b992e948c3..5947fc5351 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -96,6 +96,8 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms } material; #endif +float global_time; + #ifdef MODE_DUAL_PARABOLOID layout(location = 9) out float dp_clip; @@ -386,9 +388,12 @@ void main() { mat4 model_matrix = instances.data[instance_index].transform; #if defined(MOTION_VECTORS) + global_time = scene_data_block.prev_data.time; vertex_shader(instance_index, is_multimesh, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); + global_time = scene_data_block.data.time; vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position); #else + global_time = scene_data_block.data.time; vec4 screen_position; vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position); #endif @@ -486,6 +491,8 @@ layout(location = 10) in flat uint instance_index_interp; #define inv_projection_matrix scene_data.inv_projection_matrix #endif +#define global_time scene_data_block.data.time + #if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) //both required for transmittance to be enabled #define LIGHT_TRANSMITTANCE_USED @@ -1231,12 +1238,20 @@ void fragment_shader(in SceneData scene_data) { if (scene_data.gi_upscale_for_msaa) { vec2 base_coord = screen_uv; vec2 closest_coord = base_coord; +#ifdef USE_MULTIVIEW + float closest_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(base_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0); +#else // USE_MULTIVIEW float closest_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0.0).xyz * 2.0 - 1.0); +#endif // USE_MULTIVIEW for (int i = 0; i < 4; i++) { const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1)); vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size; +#ifdef USE_MULTIVIEW + float neighbour_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(neighbour_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0); +#else // USE_MULTIVIEW float neighbour_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0.0).xyz * 2.0 - 1.0); +#endif // USE_MULTIVIEW if (neighbour_ang > closest_ang) { closest_ang = neighbour_ang; closest_coord = neighbour_coord; @@ -1249,8 +1264,13 @@ void fragment_shader(in SceneData scene_data) { coord = screen_uv; } +#ifdef USE_MULTIVIEW + vec4 buffer_ambient = textureLod(sampler2DArray(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(coord, ViewIndex), 0.0); + vec4 buffer_reflection = textureLod(sampler2DArray(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(coord, ViewIndex), 0.0); +#else // USE_MULTIVIEW vec4 buffer_ambient = textureLod(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0); vec4 buffer_reflection = textureLod(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0); +#endif // USE_MULTIVIEW ambient_light = mix(ambient_light, buffer_ambient.rgb, buffer_ambient.a); specular_light = mix(specular_light, buffer_reflection.rgb, buffer_reflection.a); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index 32ea83397a..0c23de96c3 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -317,10 +317,16 @@ layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid; layout(set = 1, binding = 9) uniform texture2D depth_buffer; layout(set = 1, binding = 10) uniform texture2D color_buffer; +#ifdef USE_MULTIVIEW +layout(set = 1, binding = 11) uniform texture2DArray normal_roughness_buffer; +layout(set = 1, binding = 13) uniform texture2DArray ambient_buffer; +layout(set = 1, binding = 14) uniform texture2DArray reflection_buffer; +#else // USE_MULTIVIEW layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer; -layout(set = 1, binding = 12) uniform texture2D ao_buffer; layout(set = 1, binding = 13) uniform texture2D ambient_buffer; layout(set = 1, binding = 14) uniform texture2D reflection_buffer; +#endif +layout(set = 1, binding = 12) uniform texture2D ao_buffer; layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture; layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index cd94908c31..26d0de46c2 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -114,9 +114,9 @@ invariant gl_Position; #GLOBALS -void main() { - SceneData scene_data = scene_data_block.data; +#define scene_data scene_data_block.data +void main() { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; @@ -576,13 +576,14 @@ vec4 fog_process(vec3 vertex) { #endif //!MODE_RENDER DEPTH +#define scene_data scene_data_block.data + void main() { #ifdef MODE_DUAL_PARABOLOID if (dp_clip > 0.0) discard; #endif - SceneData scene_data = scene_data_block.data; //lay out everything, whatever is unused is optimized away anyway vec3 vertex = vertex_interp; diff --git a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl index a1a77b95aa..ddd984ad83 100644 --- a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl @@ -29,7 +29,8 @@ #VERSION_DEFINES -// Based on Spartan Engine's TAA implementation https://github.com/PanosK92/SpartanEngine/blob/master/Data/shaders/temporal_antialiasing.hlsl +// Based on Spartan Engine's TAA implementation (without TAA upscale). +// <https://github.com/PanosK92/SpartanEngine/blob/a8338d0609b85dc32f3732a5c27fb4463816a3b9/Data/shaders/temporal_antialiasing.hlsl> #define USE_SUBGROUPS diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl index 347fd13b28..fdbd7d3e35 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl @@ -53,7 +53,6 @@ layout(set = 0, binding = 7) uniform sampler linear_sampler; #ifdef MODE_DENSITY layout(rgba16f, set = 0, binding = 8) uniform restrict writeonly image3D density_map; -layout(rgba16f, set = 0, binding = 9) uniform restrict readonly image3D fog_map; //unused #endif #ifdef MODE_FOG diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 56a4525b8e..e65f676785 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -156,12 +156,12 @@ void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_ case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE: case RS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } break; case RS::LIGHT_PARAM_SIZE: { if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) { //changing from no size to size and the opposite - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR); } } break; default: { @@ -177,7 +177,7 @@ void LightStorage::light_set_shadow(RID p_light, bool p_enabled) { light->shadow = p_enabled; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } void LightStorage::light_set_projector(RID p_light, RID p_texture) { @@ -199,7 +199,7 @@ void LightStorage::light_set_projector(RID p_light, RID p_texture) { if (light->projector.is_valid()) { texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); } - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR); } } @@ -217,7 +217,7 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->cull_mask = p_mask; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) { @@ -237,7 +237,7 @@ void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) light->reverse_cull = p_enabled; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { @@ -247,7 +247,7 @@ void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mod light->bake_mode = p_bake_mode; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { @@ -257,7 +257,7 @@ void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) light->max_sdfgi_cascade = p_cascade; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { @@ -267,7 +267,7 @@ void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMo light->omni_shadow_mode = p_mode; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) { @@ -283,7 +283,7 @@ void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirec light->directional_shadow_mode = p_mode; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) { @@ -292,7 +292,7 @@ void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable light->directional_blend_splits = p_enable; light->version++; - light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT); + light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT); } bool LightStorage::light_directional_get_blend_splits(RID p_light) const { @@ -387,7 +387,7 @@ void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionP ERR_FAIL_COND(!reflection_probe); reflection_probe->update_mode = p_mode; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) { @@ -424,7 +424,7 @@ void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distan reflection_probe->max_distance = p_distance; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { @@ -435,7 +435,7 @@ void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_ex return; } reflection_probe->extents = p_extents; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { @@ -443,7 +443,7 @@ void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 ERR_FAIL_COND(!reflection_probe); reflection_probe->origin_offset = p_offset; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { @@ -451,7 +451,7 @@ void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) ERR_FAIL_COND(!reflection_probe); reflection_probe->interior = p_enable; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { @@ -466,7 +466,7 @@ void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enabl ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { @@ -474,7 +474,7 @@ void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers ERR_FAIL_COND(!reflection_probe); reflection_probe->cull_mask = p_layers; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) { @@ -491,7 +491,7 @@ void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ reflection_probe->mesh_lod_threshold = p_ratio; - reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE); + reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE); } AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const { diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 3cc455692d..fb25e4da7e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -35,6 +35,7 @@ #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" #include "servers/rendering/storage/light_storage.h" +#include "servers/rendering/storage/utilities.h" namespace RendererRD { @@ -61,7 +62,7 @@ struct Light { RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; uint64_t version = 0; - RendererStorage::Dependency dependency; + Dependency dependency; }; /* REFLECTION PROBE */ @@ -82,7 +83,7 @@ struct ReflectionProbe { uint32_t cull_mask = (1 << 20) - 1; float mesh_lod_threshold = 0.01; - RendererStorage::Dependency dependency; + Dependency dependency; }; /* LIGHTMAP */ @@ -104,7 +105,7 @@ struct Lightmap { int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; }; - RendererStorage::Dependency dependency; + Dependency dependency; }; class LightStorage : public RendererLightStorage { diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 096d371b8d..fcd25852eb 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -2346,7 +2346,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { for (Material *E : shader->owners) { Material *material = E; - material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); _material_queue_update(material, true, true); } } @@ -2436,7 +2436,7 @@ void MaterialStorage::_material_uniform_set_erased(void *p_material) { // if a texture is deleted, so re-create it. MaterialStorage::get_singleton()->_material_queue_update(material, false, true); } - material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); } } @@ -2466,7 +2466,7 @@ void MaterialStorage::_update_queued_materials() { if (uniforms_changed) { //some implementations such as 3D renderer cache the matreial uniform set, so update is required - material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); } } } @@ -2507,7 +2507,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) { } if (p_shader.is_null()) { - material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); material->shader_id = 0; return; } @@ -2530,7 +2530,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) { material->data->set_next_pass(material->next_pass); material->data->set_render_priority(material->priority); //updating happens later - material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); _material_queue_update(material, true, true); } @@ -2576,7 +2576,7 @@ void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material material->data->set_next_pass(p_next_material); } - material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); } void MaterialStorage::material_set_render_priority(RID p_material, int priority) { @@ -2626,7 +2626,7 @@ void MaterialStorage::material_get_instance_shader_parameters(RID p_material, Li } } -void MaterialStorage::material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) { +void MaterialStorage::material_update_dependency(RID p_material, DependencyTracker *p_instance) { Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); p_instance->update_dependency(&material->dependency); diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index f83df05355..e35d5e7669 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -31,12 +31,14 @@ #ifndef MATERIAL_STORAGE_RD_H #define MATERIAL_STORAGE_RD_H +#include "core/math/camera_matrix.h" #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" #include "servers/rendering/shader_compiler.h" #include "servers/rendering/shader_language.h" #include "servers/rendering/storage/material_storage.h" +#include "servers/rendering/storage/utilities.h" namespace RendererRD { @@ -125,7 +127,7 @@ struct Material { RID next_pass; SelfList<Material> update_element; - RendererStorage::Dependency dependency; + Dependency dependency; Material() : update_element(this) {} @@ -232,6 +234,86 @@ public: MaterialStorage(); virtual ~MaterialStorage(); + /* Helpers */ + + static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) { + p_array[0] = p_mtx.basis.rows[0][0]; + p_array[1] = p_mtx.basis.rows[1][0]; + p_array[2] = p_mtx.basis.rows[2][0]; + p_array[3] = 0; + p_array[4] = p_mtx.basis.rows[0][1]; + p_array[5] = p_mtx.basis.rows[1][1]; + p_array[6] = p_mtx.basis.rows[2][1]; + p_array[7] = 0; + p_array[8] = p_mtx.basis.rows[0][2]; + p_array[9] = p_mtx.basis.rows[1][2]; + p_array[10] = p_mtx.basis.rows[2][2]; + p_array[11] = 0; + p_array[12] = p_mtx.origin.x; + p_array[13] = p_mtx.origin.y; + p_array[14] = p_mtx.origin.z; + p_array[15] = 1; + } + + static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) { + p_array[0] = p_mtx.rows[0][0]; + p_array[1] = p_mtx.rows[1][0]; + p_array[2] = p_mtx.rows[2][0]; + p_array[3] = 0; + p_array[4] = p_mtx.rows[0][1]; + p_array[5] = p_mtx.rows[1][1]; + p_array[6] = p_mtx.rows[2][1]; + p_array[7] = 0; + p_array[8] = p_mtx.rows[0][2]; + p_array[9] = p_mtx.rows[1][2]; + p_array[10] = p_mtx.rows[2][2]; + p_array[11] = 0; + } + + static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) { + p_array[0] = p_mtx.rows[0][0]; + p_array[1] = p_mtx.rows[1][0]; + p_array[2] = p_mtx.rows[2][0]; + p_array[3] = 0; + p_array[4] = p_mtx.rows[0][1]; + p_array[5] = p_mtx.rows[1][1]; + p_array[6] = p_mtx.rows[2][1]; + p_array[7] = 0; + p_array[8] = p_mtx.rows[0][2]; + p_array[9] = p_mtx.rows[1][2]; + p_array[10] = p_mtx.rows[2][2]; + p_array[11] = 0; + } + + static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) { + p_array[0] = p_mtx.basis.rows[0][0]; + p_array[1] = p_mtx.basis.rows[0][1]; + p_array[2] = p_mtx.basis.rows[0][2]; + p_array[3] = p_mtx.origin.x; + p_array[4] = p_mtx.basis.rows[1][0]; + p_array[5] = p_mtx.basis.rows[1][1]; + p_array[6] = p_mtx.basis.rows[1][2]; + p_array[7] = p_mtx.origin.y; + p_array[8] = p_mtx.basis.rows[2][0]; + p_array[9] = p_mtx.basis.rows[2][1]; + p_array[10] = p_mtx.basis.rows[2][2]; + p_array[11] = p_mtx.origin.z; + } + + static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + p_array[i * 4 + j] = p_mtx.matrix[i][j]; + } + } + } + + static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) { + for (int i = 0; i < 128; i++) { + p_array[i] = p_kernel[i]; + } + } + /* Samplers */ _FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) { @@ -317,7 +399,7 @@ public: virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override; - virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override; + virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override; void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function); MaterialDataRequestFunction material_get_data_request_function(ShaderType p_shader_type); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 1e0d67f269..3875eb6615 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -210,6 +210,8 @@ void MeshStorage::mesh_free(RID p_rid) { mesh_clear(p_rid); mesh_set_shadow_mesh(p_rid, RID()); Mesh *mesh = mesh_owner.get_or_null(p_rid); + ERR_FAIL_COND(!mesh); + mesh->dependency.deleted_notify(p_rid); if (mesh->instances.size()) { ERR_PRINT("deleting mesh with active instances"); @@ -218,7 +220,7 @@ void MeshStorage::mesh_free(RID p_rid) { for (Mesh *E : mesh->shadow_owners) { Mesh *shadow_owner = E; shadow_owner->shadow_mesh = RID(); - shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); } } mesh_owner.free(p_rid); @@ -429,12 +431,12 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) _mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1); } - mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); for (Mesh *E : mesh->shadow_owners) { Mesh *shadow_owner = E; shadow_owner->shadow_mesh = RID(); - shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); } mesh->material_cache.clear(); @@ -501,7 +503,7 @@ void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_mat ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); mesh->surfaces[p_surface]->material = p_material; - mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); + mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL); mesh->material_cache.clear(); } @@ -692,7 +694,7 @@ void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { shadow_mesh->shadow_owners.insert(mesh); } - mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); } void MeshStorage::mesh_clear(RID p_mesh) { @@ -740,12 +742,12 @@ void MeshStorage::mesh_clear(RID p_mesh) { _mesh_instance_clear(mi); } mesh->has_bone_weights = false; - mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); for (Mesh *E : mesh->shadow_owners) { Mesh *shadow_owner = E; shadow_owner->shadow_mesh = RID(); - shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); } } @@ -1209,7 +1211,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS:: multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4); } - multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH); + multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH); } int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const { @@ -1243,7 +1245,7 @@ void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { } } - multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); + multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); } #define MULTIMESH_DIRTY_REGION_SIZE 512 @@ -1602,7 +1604,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b const float *data = p_buffer.ptr(); _multimesh_re_create_aabb(multimesh, data, multimesh->instances); - multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } } @@ -1644,7 +1646,7 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible multimesh->visible_instances = p_visible; - multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES); + multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES); } int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const { @@ -1703,7 +1705,7 @@ void MeshStorage::_update_dirty_multimeshes() { //aabb is dirty.. _multimesh_re_create_aabb(multimesh, data, visible_instances); multimesh->aabb_dirty = false; - multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } } @@ -1781,7 +1783,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_ } } - skeleton->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA); + skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_DATA); } int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const { @@ -1902,7 +1904,7 @@ void MeshStorage::_update_dirty_skeletons() { skeleton_dirty_list = skeleton->dirty_list; - skeleton->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES); + skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_BONES); skeleton->version++; @@ -1913,7 +1915,7 @@ void MeshStorage::_update_dirty_skeletons() { skeleton_dirty_list = nullptr; } -void MeshStorage::skeleton_update_dependency(RID p_skeleton, RendererStorage::DependencyTracker *p_instance) { +void MeshStorage::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) { Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND(!skeleton); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 7ce019cf98..9cdda6bfca 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -35,8 +35,8 @@ #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" #include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h" -#include "servers/rendering/renderer_storage.h" #include "servers/rendering/storage/mesh_storage.h" +#include "servers/rendering/storage/utilities.h" namespace RendererRD { @@ -143,7 +143,7 @@ struct Mesh { RID shadow_mesh; HashSet<Mesh *> shadow_owners; - RendererStorage::Dependency dependency; + Dependency dependency; }; /* Mesh Instance */ @@ -199,7 +199,7 @@ struct MultiMesh { bool dirty = false; MultiMesh *dirty_list = nullptr; - RendererStorage::Dependency dependency; + Dependency dependency; }; /* Skeleton */ @@ -256,7 +256,7 @@ struct Skeleton { uint64_t version = 1; - RendererStorage::Dependency dependency; + Dependency dependency; }; class MeshStorage : public RendererMeshStorage { @@ -672,7 +672,7 @@ public: virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override; - virtual void skeleton_update_dependency(RID p_skeleton, RendererStorage::DependencyTracker *p_instance) override; + virtual void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) override; void _update_dirty_skeletons(); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 58a96ed1f9..5200e0d318 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -30,7 +30,6 @@ #include "particles_storage.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/rendering_server_globals.h" #include "texture_storage.h" @@ -321,7 +320,7 @@ void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) { particles->prev_phase = 0; particles->clear = true; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); } void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) { @@ -356,7 +355,7 @@ void ParticlesStorage::particles_set_custom_aabb(RID p_particles, const AABB &p_ Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->custom_aabb = p_aabb; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void ParticlesStorage::particles_set_speed_scale(RID p_particles, double p_scale) { @@ -370,7 +369,7 @@ void ParticlesStorage::particles_set_use_local_coordinates(RID p_particles, bool ERR_FAIL_COND(!particles); particles->use_local_coords = p_enable; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); } void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) { @@ -386,7 +385,7 @@ void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) { particles->prev_phase = 0; particles->clear = true; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); } void ParticlesStorage::particles_set_interpolate(RID p_particles, bool p_enable) { @@ -419,7 +418,7 @@ void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, doub particles->prev_phase = 0; particles->clear = true; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); } void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) { @@ -436,7 +435,7 @@ void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vec particles->trail_bind_poses = p_bind_poses; particles->trail_bind_poses_dirty = true; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); } void ParticlesStorage::particles_set_collision_base_size(RID p_particles, real_t p_size) { @@ -458,7 +457,7 @@ void ParticlesStorage::particles_set_process_material(RID p_particles, RID p_mat ERR_FAIL_COND(!particles); particles->process_material = p_material; - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed } RID ParticlesStorage::particles_get_process_material(RID p_particles) const { @@ -545,7 +544,7 @@ void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_tran int32_t idx = particles->emission_buffer->particle_count; if (idx < particles->emission_buffer->particle_max) { - RendererStorageRD::store_transform(p_transform, particles->emission_buffer->data[idx].xform); + RendererRD::MaterialStorage::store_transform(p_transform, particles->emission_buffer->data[idx].xform); particles->emission_buffer->data[idx].velocity[0] = p_velocity.x; particles->emission_buffer->data[idx].velocity[1] = p_velocity.y; @@ -766,9 +765,9 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta frame_params.randomness = p_particles->randomness; if (p_particles->use_local_coords) { - RendererStorageRD::store_transform(Transform3D(), frame_params.emission_transform); + RendererRD::MaterialStorage::store_transform(Transform3D(), frame_params.emission_transform); } else { - RendererStorageRD::store_transform(p_particles->emission_transform, frame_params.emission_transform); + RendererRD::MaterialStorage::store_transform(p_particles->emission_transform, frame_params.emission_transform); } frame_params.cycle = p_particles->cycle_number; @@ -858,7 +857,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta ParticlesFrameParams::Attractor &attr = frame_params.attractors[frame_params.attractor_count]; - RendererStorageRD::store_transform(to_collider, attr.transform); + RendererRD::MaterialStorage::store_transform(to_collider, attr.transform); attr.strength = pc->attractor_strength; attr.attenuation = pc->attractor_attenuation; attr.directionality = pc->attractor_directionality; @@ -906,7 +905,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta ParticlesFrameParams::Collider &col = frame_params.colliders[frame_params.collider_count]; - RendererStorageRD::store_transform(to_collider, col.transform); + RendererRD::MaterialStorage::store_transform(to_collider, col.transform); switch (pc->type) { case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: { col.type = ParticlesFrameParams::COLLISION_TYPE_SPHERE; @@ -1203,7 +1202,7 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); - RendererStorageRD::base_singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount); + RendererCompositorRD::singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount); } copy_push_constant.total_particles *= copy_push_constant.total_particles; @@ -1383,7 +1382,7 @@ void ParticlesStorage::update_particles() { } for (int i = 0; i < particles->trail_bind_poses.size(); i++) { - RendererStorageRD::store_transform(particles->trail_bind_poses[i], &particles_shader.pose_update_buffer[i * 16]); + RendererRD::MaterialStorage::store_transform(particles->trail_bind_poses[i], &particles_shader.pose_update_buffer[i * 16]); } RD::get_singleton()->buffer_update(particles->trail_bind_pose_buffer, 0, particles->trail_bind_poses.size() * 16 * sizeof(float), particles_shader.pose_update_buffer.ptr()); @@ -1457,14 +1456,14 @@ void ParticlesStorage::update_particles() { // In local mode, particle positions are calculated locally (relative to the node position) // and they're also drawn locally. // It works as expected, so we just pass an identity transform. - RendererStorageRD::store_transform(Transform3D(), copy_push_constant.inv_emission_transform); + RendererRD::MaterialStorage::store_transform(Transform3D(), copy_push_constant.inv_emission_transform); } else { // In global mode, particle positions are calculated globally (relative to the canvas origin) // but they're drawn locally. // So, we need to pass the inverse of the emission transform to bring the // particles to local coordinates before drawing. Transform3D inv = particles->emission_transform.affine_inverse(); - RendererStorageRD::store_transform(inv, copy_push_constant.inv_emission_transform); + RendererRD::MaterialStorage::store_transform(inv, copy_push_constant.inv_emission_transform); } copy_push_constant.total_particles = total_amount; @@ -1500,7 +1499,7 @@ void ParticlesStorage::update_particles() { RD::get_singleton()->compute_list_end(); } - particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } } @@ -1756,7 +1755,7 @@ void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_co particles_collision->heightfield_texture = RID(); } particles_collision->type = p_type; - particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { @@ -1770,7 +1769,7 @@ void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_col ERR_FAIL_COND(!particles_collision); particles_collision->radius = p_radius; - particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { @@ -1778,7 +1777,7 @@ void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_colli ERR_FAIL_COND(!particles_collision); particles_collision->extents = p_extents; - particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void ParticlesStorage::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) { @@ -1812,7 +1811,7 @@ void ParticlesStorage::particles_collision_set_field_texture(RID p_particles_col void ParticlesStorage::particles_collision_height_field_update(RID p_particles_collision) { ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); - particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 115633d17a..70ac6f0349 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -37,9 +37,9 @@ #include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" -#include "servers/rendering/renderer_storage.h" #include "servers/rendering/shader_compiler.h" #include "servers/rendering/storage/particles_storage.h" +#include "servers/rendering/storage/utilities.h" namespace RendererRD { @@ -226,7 +226,7 @@ struct Particles { HashSet<RID> collisions; - RendererStorage::Dependency dependency; + Dependency dependency; double trail_length = 1.0; bool trails_enabled = false; @@ -254,7 +254,7 @@ struct ParticlesCollision { RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024; - RendererStorage::Dependency dependency; + Dependency dependency; }; struct ParticlesCollisionInstance { diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 329c23bad0..1109357a74 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1712,7 +1712,7 @@ void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) { Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->extents = p_extents; - decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { @@ -1736,7 +1736,7 @@ void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID texture_add_to_decal_atlas(decal->textures[p_type]); } - decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL); + decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL); } void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) { @@ -1761,7 +1761,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->cull_mask = p_layers; - decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB); + decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 901f764085..7a96e6c6ed 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -33,8 +33,8 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h" -#include "servers/rendering/renderer_storage.h" #include "servers/rendering/storage/texture_storage.h" +#include "servers/rendering/storage/utilities.h" namespace RendererRD { @@ -193,7 +193,7 @@ struct Decal { float distance_fade_length = 1; float normal_fade = 0.0; - RendererStorage::Dependency dependency; + Dependency dependency; }; struct RenderTarget { diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp new file mode 100644 index 0000000000..a1f62c16c7 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp @@ -0,0 +1,337 @@ +/*************************************************************************/ +/* utilities.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "utilities.h" +#include "../environment/fog.h" +#include "../environment/gi.h" +#include "light_storage.h" +#include "mesh_storage.h" +#include "particles_storage.h" +#include "texture_storage.h" + +using namespace RendererRD; + +Utilities *Utilities::singleton = nullptr; + +Utilities::Utilities() { + singleton = this; +} + +Utilities::~Utilities() { + singleton = nullptr; +} + +/* INSTANCES */ + +RS::InstanceType Utilities::get_base_type(RID p_rid) const { + if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) { + return RS::INSTANCE_MESH; + } + if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) { + return RS::INSTANCE_MULTIMESH; + } + if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) { + return RS::INSTANCE_REFLECTION_PROBE; + } + if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) { + return RS::INSTANCE_DECAL; + } + if (RendererRD::GI::get_singleton()->owns_voxel_gi(p_rid)) { + return RS::INSTANCE_VOXEL_GI; + } + if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) { + return RS::INSTANCE_LIGHT; + } + if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) { + return RS::INSTANCE_LIGHTMAP; + } + if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) { + return RS::INSTANCE_PARTICLES; + } + if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) { + return RS::INSTANCE_PARTICLES_COLLISION; + } + if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) { + return RS::INSTANCE_FOG_VOLUME; + } + if (owns_visibility_notifier(p_rid)) { + return RS::INSTANCE_VISIBLITY_NOTIFIER; + } + + return RS::INSTANCE_NONE; +} + +bool Utilities::free(RID p_rid) { + if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) { + RendererRD::TextureStorage::get_singleton()->texture_free(p_rid); + } else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { + RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid); + } else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) { + RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid); + } else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) { + RendererRD::MaterialStorage::get_singleton()->material_free(p_rid); + } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) { + RendererRD::MeshStorage::get_singleton()->mesh_free(p_rid); + } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) { + RendererRD::MeshStorage::get_singleton()->mesh_instance_free(p_rid); + } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) { + RendererRD::MeshStorage::get_singleton()->multimesh_free(p_rid); + } else if (RendererRD::MeshStorage::get_singleton()->owns_skeleton(p_rid)) { + RendererRD::MeshStorage::get_singleton()->skeleton_free(p_rid); + } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) { + RendererRD::LightStorage::get_singleton()->reflection_probe_free(p_rid); + } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) { + RendererRD::TextureStorage::get_singleton()->decal_free(p_rid); + } else if (RendererRD::GI::get_singleton()->owns_voxel_gi(p_rid)) { + RendererRD::GI::get_singleton()->voxel_gi_free(p_rid); + } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) { + RendererRD::LightStorage::get_singleton()->lightmap_free(p_rid); + } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) { + RendererRD::LightStorage::get_singleton()->light_free(p_rid); + } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) { + RendererRD::ParticlesStorage::get_singleton()->particles_free(p_rid); + } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) { + RendererRD::ParticlesStorage::get_singleton()->particles_collision_free(p_rid); + } else if (owns_visibility_notifier(p_rid)) { + visibility_notifier_free(p_rid); + } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) { + RendererRD::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid); + } else if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) { + RendererRD::Fog::get_singleton()->fog_free(p_rid); + } else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) { + RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid); + } else { + return false; + } + + return true; +} + +/* DEPENDENCIES */ + +void Utilities::base_update_dependency(RID p_base, DependencyTracker *p_instance) { + if (MeshStorage::get_singleton()->owns_mesh(p_base)) { + Mesh *mesh = MeshStorage::get_singleton()->get_mesh(p_base); + p_instance->update_dependency(&mesh->dependency); + } else if (MeshStorage::get_singleton()->owns_multimesh(p_base)) { + MultiMesh *multimesh = MeshStorage::get_singleton()->get_multimesh(p_base); + p_instance->update_dependency(&multimesh->dependency); + if (multimesh->mesh.is_valid()) { + base_update_dependency(multimesh->mesh, p_instance); + } + } else if (LightStorage::get_singleton()->owns_reflection_probe(p_base)) { + ReflectionProbe *rp = LightStorage::get_singleton()->get_reflection_probe(p_base); + p_instance->update_dependency(&rp->dependency); + } else if (TextureStorage::get_singleton()->owns_decal(p_base)) { + Decal *decal = TextureStorage::get_singleton()->get_decal(p_base); + p_instance->update_dependency(&decal->dependency); + } else if (GI::get_singleton()->owns_voxel_gi(p_base)) { + GI::VoxelGI *gip = GI::get_singleton()->get_voxel_gi(p_base); + p_instance->update_dependency(&gip->dependency); + } else if (LightStorage::get_singleton()->owns_lightmap(p_base)) { + Lightmap *lm = LightStorage::get_singleton()->get_lightmap(p_base); + p_instance->update_dependency(&lm->dependency); + } else if (LightStorage::get_singleton()->owns_light(p_base)) { + Light *l = LightStorage::get_singleton()->get_light(p_base); + p_instance->update_dependency(&l->dependency); + } else if (ParticlesStorage::get_singleton()->owns_particles(p_base)) { + Particles *p = ParticlesStorage::get_singleton()->get_particles(p_base); + p_instance->update_dependency(&p->dependency); + } else if (ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) { + ParticlesCollision *pc = ParticlesStorage::get_singleton()->get_particles_collision(p_base); + p_instance->update_dependency(&pc->dependency); + } else if (Fog::get_singleton()->owns_fog_volume(p_base)) { + Fog::FogVolume *fv = Fog::get_singleton()->get_fog_volume(p_base); + p_instance->update_dependency(&fv->dependency); + } else if (owns_visibility_notifier(p_base)) { + VisibilityNotifier *vn = get_visibility_notifier(p_base); + p_instance->update_dependency(&vn->dependency); + } +} + +/* VISIBILITY NOTIFIER */ + +RID Utilities::visibility_notifier_allocate() { + return visibility_notifier_owner.allocate_rid(); +} + +void Utilities::visibility_notifier_initialize(RID p_notifier) { + visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier()); +} + +void Utilities::visibility_notifier_free(RID p_notifier) { + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); + vn->dependency.deleted_notify(p_notifier); + visibility_notifier_owner.free(p_notifier); +} + +void Utilities::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) { + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); + ERR_FAIL_COND(!vn); + vn->aabb = p_aabb; + vn->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); +} + +void Utilities::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) { + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); + ERR_FAIL_COND(!vn); + vn->enter_callback = p_enter_callbable; + vn->exit_callback = p_exit_callable; +} + +AABB Utilities::visibility_notifier_get_aabb(RID p_notifier) const { + const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); + ERR_FAIL_COND_V(!vn, AABB()); + return vn->aabb; +} + +void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) { + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); + ERR_FAIL_COND(!vn); + + if (p_enter) { + if (!vn->enter_callback.is_null()) { + if (p_deferred) { + vn->enter_callback.call_deferred(nullptr, 0); + } else { + Variant r; + Callable::CallError ce; + vn->enter_callback.call(nullptr, 0, r, ce); + } + } + } else { + if (!vn->exit_callback.is_null()) { + if (p_deferred) { + vn->exit_callback.call_deferred(nullptr, 0); + } else { + Variant r; + Callable::CallError ce; + vn->exit_callback.call(nullptr, 0, r, ce); + } + } + } +} + +/* TIMING */ + +void Utilities::capture_timestamps_begin() { + RD::get_singleton()->capture_timestamp("Frame Begin"); +} + +void Utilities::capture_timestamp(const String &p_name) { + RD::get_singleton()->capture_timestamp(p_name); +} + +uint32_t Utilities::get_captured_timestamps_count() const { + return RD::get_singleton()->get_captured_timestamps_count(); +} + +uint64_t Utilities::get_captured_timestamps_frame() const { + return RD::get_singleton()->get_captured_timestamps_frame(); +} + +uint64_t Utilities::get_captured_timestamp_gpu_time(uint32_t p_index) const { + return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index); +} + +uint64_t Utilities::get_captured_timestamp_cpu_time(uint32_t p_index) const { + return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index); +} + +String Utilities::get_captured_timestamp_name(uint32_t p_index) const { + return RD::get_singleton()->get_captured_timestamp_name(p_index); +} + +/* MISC */ + +void Utilities::update_dirty_resources() { + MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update + MaterialStorage::get_singleton()->_update_queued_materials(); + MeshStorage::get_singleton()->_update_dirty_multimeshes(); + MeshStorage::get_singleton()->_update_dirty_skeletons(); + TextureStorage::get_singleton()->update_decal_atlas(); +} + +bool Utilities::has_os_feature(const String &p_feature) const { + if (!RD::get_singleton()) { + return false; + } + + if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { + return true; + } + + if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { + return true; + } + + if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { + return true; + } + + if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { + return true; + } + + return false; +} + +void Utilities::update_memory_info() { + texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES); + buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS); + total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL); +} + +uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) { + if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) { + return texture_mem_cache; + } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) { + return buffer_mem_cache; + } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) { + return total_mem_cache; + } + return 0; +} + +String Utilities::get_video_adapter_name() const { + return RenderingDevice::get_singleton()->get_device_name(); +} + +String Utilities::get_video_adapter_vendor() const { + return RenderingDevice::get_singleton()->get_device_vendor_name(); +} + +RenderingDevice::DeviceType Utilities::get_video_adapter_type() const { + return RenderingDevice::get_singleton()->get_device_type(); +} + +String Utilities::get_video_adapter_api_version() const { + return RenderingDevice::get_singleton()->get_device_api_version(); +} diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.h b/servers/rendering/renderer_rd/storage_rd/utilities.h new file mode 100644 index 0000000000..979e984546 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/utilities.h @@ -0,0 +1,122 @@ +/*************************************************************************/ +/* utilities.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef UTILITIES_RD_H +#define UTILITIES_RD_H + +#include "core/templates/rid_owner.h" +#include "servers/rendering/storage/utilities.h" + +namespace RendererRD { + +/* VISIBILITY NOTIFIER */ + +struct VisibilityNotifier { + AABB aabb; + Callable enter_callback; + Callable exit_callback; + Dependency dependency; +}; + +class Utilities : public RendererUtilities { +private: + static Utilities *singleton; + + /* VISIBILITY NOTIFIER */ + + mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner; + + /* MISC */ + + //keep cached since it can be called form any thread + uint64_t texture_mem_cache = 0; + uint64_t buffer_mem_cache = 0; + uint64_t total_mem_cache = 0; + +public: + static Utilities *get_singleton() { return singleton; } + + Utilities(); + virtual ~Utilities() override; + + /* INSTANCES */ + + virtual RS::InstanceType get_base_type(RID p_rid) const override; + virtual bool free(RID p_rid) override; + + /* DEPENDENCIES */ + + virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override; + + /* VISIBILITY NOTIFIER */ + + VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); }; + bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); }; + + virtual RID visibility_notifier_allocate() override; + virtual void visibility_notifier_initialize(RID p_notifier) override; + virtual void visibility_notifier_free(RID p_notifier) override; + + virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override; + virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override; + + virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override; + virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override; + + /* TIMING */ + + virtual void capture_timestamps_begin() override; + virtual void capture_timestamp(const String &p_name) override; + virtual uint32_t get_captured_timestamps_count() const override; + virtual uint64_t get_captured_timestamps_frame() const override; + virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override; + virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override; + virtual String get_captured_timestamp_name(uint32_t p_index) const override; + + /* MISC */ + + virtual void update_dirty_resources() override; + virtual void set_debug_generate_wireframes(bool p_generate) override {} + + virtual bool has_os_feature(const String &p_feature) const override; + + virtual void update_memory_info() override; + + virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override; + + virtual String get_video_adapter_name() const override; + virtual String get_video_adapter_vendor() const override; + virtual RenderingDevice::DeviceType get_video_adapter_type() const override; + virtual String get_video_adapter_api_version() const override; +}; + +} // namespace RendererRD + +#endif // !UTILITIES_RD_H |