Path: blob/master/servers/rendering/renderer_rd/cluster_builder_rd.cpp
10279 views
/**************************************************************************/1/* cluster_builder_rd.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "cluster_builder_rd.h"31#include "servers/rendering/rendering_device.h"32#include "servers/rendering/rendering_server_globals.h"3334ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {35RD::VertexFormatID vertex_format;3637{38Vector<RD::VertexAttribute> attributes;39{40RD::VertexAttribute va;41va.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;42va.stride = sizeof(float) * 3;43attributes.push_back(va);44}45vertex_format = RD::get_singleton()->vertex_format_create(attributes);46}4748{49RD::FramebufferFormatID fb_format;50RD::PipelineColorBlendState blend_state;51RD::PipelineRasterizationState rasterization_state;52RD::PipelineMultisampleState ms;53rasterization_state.enable_depth_clamp = true;54ms.sample_count = RD::TEXTURE_SAMPLES_4;5556Vector<String> variants;57variants.push_back("");58variants.push_back("\n#define USE_ATTACHMENT\n");59variants.push_back("\n#define MOLTENVK_USED\n#define NO_IMAGE_ATOMICS\n");60variants.push_back("\n#define USE_ATTACHMENT\n#define MOLTENVK_USED\n#define NO_IMAGE_ATOMICS\n");61variants.push_back("\n#define NO_IMAGE_ATOMICS\n");62variants.push_back("\n#define MOLTENVK_USED\n#define NO_IMAGE_ATOMICS\n");6364ClusterRender::ShaderVariant shader_variant;65RenderingDevice *rd = RD::get_singleton();66if (rd->has_feature(RD::SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS)) {67fb_format = rd->framebuffer_format_create_empty();68blend_state = RD::PipelineColorBlendState::create_disabled();69#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))70if (rd->get_device_capabilities().device_family == RDD::DEVICE_VULKAN) {71shader_variant = ClusterRender::SHADER_NORMAL_MOLTENVK;72} else if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {73shader_variant = ClusterRender::SHADER_NORMAL;74} else {75shader_variant = ClusterRender::SHADER_NORMAL_NO_ATOMICS;76}77#else78if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {79shader_variant = ClusterRender::SHADER_NORMAL;80} else {81shader_variant = ClusterRender::SHADER_NORMAL_NO_ATOMICS;82}83#endif84} else {85Vector<RD::AttachmentFormat> afs;86afs.push_back(RD::AttachmentFormat());87afs.write[0].usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;88fb_format = rd->framebuffer_format_create(afs);89blend_state = RD::PipelineColorBlendState::create_blend();90#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))91if (rd->get_device_capabilities().device_family == RDD::DEVICE_VULKAN) {92shader_variant = ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK;93} else if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {94shader_variant = ClusterRender::SHADER_USE_ATTACHMENT;95} else {96shader_variant = ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS;97}98#else99if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {100shader_variant = ClusterRender::SHADER_USE_ATTACHMENT;101} else {102shader_variant = ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS;103}104#endif105}106107cluster_render.cluster_render_shader.initialize(variants);108#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))109if (rd->get_device_capabilities().device_family == RDD::DEVICE_VULKAN) {110cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL, false);111cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT, false);112cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_NO_ATOMICS, false);113cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS, false);114} else if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {115cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);116cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);117cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_NO_ATOMICS, false);118cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS, false);119} else {120cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL, false);121cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT, false);122cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);123cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);124}125#else126if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {127cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);128cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);129cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_NO_ATOMICS, false);130cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS, false);131} else {132cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL, false);133cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT, false);134cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);135cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);136}137#endif138cluster_render.shader_version = cluster_render.cluster_render_shader.version_create();139cluster_render.shader = cluster_render.cluster_render_shader.version_get_shader(cluster_render.shader_version, shader_variant);140cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, rasterization_state, RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);141cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, rasterization_state, ms, RD::PipelineDepthStencilState(), blend_state, 0);142}143{144Vector<String> versions;145versions.push_back("");146cluster_store.cluster_store_shader.initialize(versions);147cluster_store.shader_version = cluster_store.cluster_store_shader.version_create();148cluster_store.shader = cluster_store.cluster_store_shader.version_get_shader(cluster_store.shader_version, 0);149cluster_store.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_store.shader);150}151{152Vector<String> versions;153versions.push_back("");154cluster_debug.cluster_debug_shader.initialize(versions);155cluster_debug.shader_version = cluster_debug.cluster_debug_shader.version_create();156cluster_debug.shader = cluster_debug.cluster_debug_shader.version_get_shader(cluster_debug.shader_version, 0);157cluster_debug.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_debug.shader);158}159160{ // Sphere mesh data.161static const uint32_t icosphere_vertex_count = 42;162static const float icosphere_vertices[icosphere_vertex_count * 3] = {1630, 0, -1, 0.7236073, -0.5257253, -0.4472195, -0.276388, -0.8506492, -0.4472199, -0.8944262, 0, -0.4472156, -0.276388, 0.8506492, -0.4472199, 0.7236073, 0.5257253, -0.4472195, 0.276388, -0.8506492, 0.4472199, -0.7236073, -0.5257253, 0.4472195, -0.7236073, 0.5257253, 0.4472195, 0.276388, 0.8506492, 0.4472199, 0.8944262, 0, 0.4472156, 0, 0, 1, -0.1624555, -0.4999952, -0.8506544, 0.4253227, -0.3090114, -0.8506542, 0.2628688, -0.8090116, -0.5257377, 0.8506479, 0, -0.5257359, 0.4253227, 0.3090114, -0.8506542, -0.5257298, 0, -0.8506517, -0.6881894, -0.4999969, -0.5257362, -0.1624555, 0.4999952, -0.8506544, -0.6881894, 0.4999969, -0.5257362, 0.2628688, 0.8090116, -0.5257377, 0.9510579, -0.3090126, 0, 0.9510579, 0.3090126, 0, 0, -1, 0, 0.5877856, -0.8090167, 0, -0.9510579, -0.3090126, 0, -0.5877856, -0.8090167, 0, -0.5877856, 0.8090167, 0, -0.9510579, 0.3090126, 0, 0.5877856, 0.8090167, 0, 0, 1, 0, 0.6881894, -0.4999969, 0.5257362, -0.2628688, -0.8090116, 0.5257377, -0.8506479, 0, 0.5257359, -0.2628688, 0.8090116, 0.5257377, 0.6881894, 0.4999969, 0.5257362, 0.1624555, -0.4999952, 0.8506544, 0.5257298, 0, 0.8506517, -0.4253227, -0.3090114, 0.8506542, -0.4253227, 0.3090114, 0.8506542, 0.1624555, 0.4999952, 0.8506544164};165static const uint32_t icosphere_triangle_count = 80;166static const uint16_t icosphere_triangle_indices[icosphere_triangle_count * 3] = {1670, 13, 12, 1, 13, 15, 0, 12, 17, 0, 17, 19, 0, 19, 16, 1, 15, 22, 2, 14, 24, 3, 18, 26, 4, 20, 28, 5, 21, 30, 1, 22, 25, 2, 24, 27, 3, 26, 29, 4, 28, 31, 5, 30, 23, 6, 32, 37, 7, 33, 39, 8, 34, 40, 9, 35, 41, 10, 36, 38, 38, 41, 11, 38, 36, 41, 36, 9, 41, 41, 40, 11, 41, 35, 40, 35, 8, 40, 40, 39, 11, 40, 34, 39, 34, 7, 39, 39, 37, 11, 39, 33, 37, 33, 6, 37, 37, 38, 11, 37, 32, 38, 32, 10, 38, 23, 36, 10, 23, 30, 36, 30, 9, 36, 31, 35, 9, 31, 28, 35, 28, 8, 35, 29, 34, 8, 29, 26, 34, 26, 7, 34, 27, 33, 7, 27, 24, 33, 24, 6, 33, 25, 32, 6, 25, 22, 32, 22, 10, 32, 30, 31, 9, 30, 21, 31, 21, 4, 31, 28, 29, 8, 28, 20, 29, 20, 3, 29, 26, 27, 7, 26, 18, 27, 18, 2, 27, 24, 25, 6, 24, 14, 25, 14, 1, 25, 22, 23, 10, 22, 15, 23, 15, 5, 23, 16, 21, 5, 16, 19, 21, 19, 4, 21, 19, 20, 4, 19, 17, 20, 17, 3, 20, 17, 18, 3, 17, 12, 18, 12, 2, 18, 15, 16, 5, 15, 13, 16, 13, 0, 16, 12, 14, 2, 12, 13, 14, 13, 1, 14168};169170Vector<uint8_t> vertex_data;171vertex_data.resize(sizeof(float) * icosphere_vertex_count * 3);172memcpy(vertex_data.ptrw(), icosphere_vertices, vertex_data.size());173174sphere_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);175176Vector<uint8_t> index_data;177index_data.resize(sizeof(uint16_t) * icosphere_triangle_count * 3);178memcpy(index_data.ptrw(), icosphere_triangle_indices, index_data.size());179180sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);181182Vector<RID> buffers;183buffers.push_back(sphere_vertex_buffer);184185sphere_vertex_array = RD::get_singleton()->vertex_array_create(icosphere_vertex_count, vertex_format, buffers);186187sphere_index_array = RD::get_singleton()->index_array_create(sphere_index_buffer, 0, icosphere_triangle_count * 3);188189float min_d = 1e20;190for (uint32_t i = 0; i < icosphere_triangle_count; i++) {191Vector3 vertices[3];192for (uint32_t j = 0; j < 3; j++) {193uint32_t index = icosphere_triangle_indices[i * 3 + j];194for (uint32_t k = 0; k < 3; k++) {195vertices[j][k] = icosphere_vertices[index * 3 + k];196}197}198Plane p(vertices[0], vertices[1], vertices[2]);199min_d = MIN(Math::abs(p.d), min_d);200}201sphere_overfit = 1.0 / min_d;202}203204{ // Cone mesh data.205static const uint32_t cone_vertex_count = 99;206static const float cone_vertices[cone_vertex_count * 3] = {2070, 1, -1, 0.1950903, 0.9807853, -1, 0.3826835, 0.9238795, -1, 0.5555703, 0.8314696, -1, 0.7071068, 0.7071068, -1, 0.8314697, 0.5555702, -1, 0.9238795, 0.3826834, -1, 0.9807853, 0.1950903, -1, 1, 0, -1, 0.9807853, -0.1950902, -1, 0.9238796, -0.3826833, -1, 0.8314697, -0.5555702, -1, 0.7071068, -0.7071068, -1, 0.5555702, -0.8314697, -1, 0.3826833, -0.9238796, -1, 0.1950901, -0.9807853, -1, -3.25841e-7, -1, -1, -0.1950907, -0.9807852, -1, -0.3826839, -0.9238793, -1, -0.5555707, -0.8314693, -1, -0.7071073, -0.7071063, -1, -0.83147, -0.5555697, -1, -0.9238799, -0.3826827, -1, 0, 0, 0, -0.9807854, -0.1950894, -1, -1, 9.65599e-7, -1, -0.9807851, 0.1950913, -1, -0.9238791, 0.3826845, -1, -0.8314689, 0.5555713, -1, -0.7071059, 0.7071077, -1, -0.5555691, 0.8314704, -1, -0.3826821, 0.9238801, -1, -0.1950888, 0.9807856, -1208};209static const uint32_t cone_triangle_count = 62;210static const uint16_t cone_triangle_indices[cone_triangle_count * 3] = {2110, 23, 1, 1, 23, 2, 2, 23, 3, 3, 23, 4, 4, 23, 5, 5, 23, 6, 6, 23, 7, 7, 23, 8, 8, 23, 9, 9, 23, 10, 10, 23, 11, 11, 23, 12, 12, 23, 13, 13, 23, 14, 14, 23, 15, 15, 23, 16, 16, 23, 17, 17, 23, 18, 18, 23, 19, 19, 23, 20, 20, 23, 21, 21, 23, 22, 22, 23, 24, 24, 23, 25, 25, 23, 26, 26, 23, 27, 27, 23, 28, 28, 23, 29, 29, 23, 30, 30, 23, 31, 31, 23, 32, 32, 23, 0, 7, 15, 24, 32, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 3, 6, 7, 3, 7, 8, 9, 9, 10, 7, 10, 11, 7, 11, 12, 15, 12, 13, 15, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 24, 20, 21, 24, 21, 22, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 1, 3, 15, 17, 24, 17, 19, 24, 24, 26, 32, 26, 28, 32, 28, 30, 32, 32, 3, 7, 7, 11, 15, 32, 7, 24212};213214Vector<uint8_t> vertex_data;215vertex_data.resize(sizeof(float) * cone_vertex_count * 3);216memcpy(vertex_data.ptrw(), cone_vertices, vertex_data.size());217218cone_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);219220Vector<uint8_t> index_data;221index_data.resize(sizeof(uint16_t) * cone_triangle_count * 3);222memcpy(index_data.ptrw(), cone_triangle_indices, index_data.size());223224cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);225226Vector<RID> buffers;227buffers.push_back(cone_vertex_buffer);228229cone_vertex_array = RD::get_singleton()->vertex_array_create(cone_vertex_count, vertex_format, buffers);230231cone_index_array = RD::get_singleton()->index_array_create(cone_index_buffer, 0, cone_triangle_count * 3);232233float min_d = 1e20;234for (uint32_t i = 0; i < cone_triangle_count; i++) {235Vector3 vertices[3];236int32_t zero_index = -1;237for (uint32_t j = 0; j < 3; j++) {238uint32_t index = cone_triangle_indices[i * 3 + j];239for (uint32_t k = 0; k < 3; k++) {240vertices[j][k] = cone_vertices[index * 3 + k];241}242if (vertices[j] == Vector3()) {243zero_index = j;244}245}246247if (zero_index != -1) {248Vector3 a = vertices[(zero_index + 1) % 3];249Vector3 b = vertices[(zero_index + 2) % 3];250Vector3 c = a + Vector3(0, 0, 1);251Plane p(a, b, c);252min_d = MIN(Math::abs(p.d), min_d);253}254}255cone_overfit = 1.0 / min_d;256}257258{ // Box mesh data.259static const uint32_t box_vertex_count = 8;260static const float box_vertices[box_vertex_count * 3] = {261-1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1262};263static const uint32_t box_triangle_count = 12;264static const uint16_t box_triangle_indices[box_triangle_count * 3] = {2651, 2, 0, 3, 6, 2, 7, 4, 6, 5, 0, 4, 6, 0, 2, 3, 5, 7, 1, 3, 2, 3, 7, 6, 7, 5, 4, 5, 1, 0, 6, 4, 0, 3, 1, 5266};267268Vector<uint8_t> vertex_data;269vertex_data.resize(sizeof(float) * box_vertex_count * 3);270memcpy(vertex_data.ptrw(), box_vertices, vertex_data.size());271272box_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);273274Vector<uint8_t> index_data;275index_data.resize(sizeof(uint16_t) * box_triangle_count * 3);276memcpy(index_data.ptrw(), box_triangle_indices, index_data.size());277278box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);279280Vector<RID> buffers;281buffers.push_back(box_vertex_buffer);282283box_vertex_array = RD::get_singleton()->vertex_array_create(box_vertex_count, vertex_format, buffers);284285box_index_array = RD::get_singleton()->index_array_create(box_index_buffer, 0, box_triangle_count * 3);286}287}288ClusterBuilderSharedDataRD::~ClusterBuilderSharedDataRD() {289RD::get_singleton()->free(sphere_vertex_buffer);290RD::get_singleton()->free(sphere_index_buffer);291RD::get_singleton()->free(cone_vertex_buffer);292RD::get_singleton()->free(cone_index_buffer);293RD::get_singleton()->free(box_vertex_buffer);294RD::get_singleton()->free(box_index_buffer);295296cluster_render.cluster_render_shader.version_free(cluster_render.shader_version);297cluster_store.cluster_store_shader.version_free(cluster_store.shader_version);298cluster_debug.cluster_debug_shader.version_free(cluster_debug.shader_version);299}300301/////////////////////////////302303void ClusterBuilderRD::_clear() {304if (cluster_buffer.is_null()) {305return;306}307308RD::get_singleton()->free(cluster_buffer);309RD::get_singleton()->free(cluster_render_buffer);310RD::get_singleton()->free(element_buffer);311cluster_buffer = RID();312cluster_render_buffer = RID();313element_buffer = RID();314315memfree(render_elements);316317render_elements = nullptr;318render_element_max = 0;319render_element_count = 0;320321RD::get_singleton()->free(framebuffer);322framebuffer = RID();323324cluster_render_uniform_set = RID();325cluster_store_uniform_set = RID();326}327328void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer) {329ERR_FAIL_COND(p_max_elements == 0);330ERR_FAIL_COND(p_screen_size.x < 1);331ERR_FAIL_COND(p_screen_size.y < 1);332333_clear();334335screen_size = p_screen_size;336337cluster_screen_size.width = Math::division_round_up((uint32_t)p_screen_size.width, cluster_size);338cluster_screen_size.height = Math::division_round_up((uint32_t)p_screen_size.height, cluster_size);339340max_elements_by_type = p_max_elements;341if (max_elements_by_type % 32) { // Needs to be aligned to 32.342max_elements_by_type += 32 - (max_elements_by_type % 32);343}344345cluster_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (max_elements_by_type / 32 + 32) * ELEMENT_TYPE_MAX * 4;346347render_element_max = max_elements_by_type * ELEMENT_TYPE_MAX;348349uint32_t element_tag_bits_size = render_element_max / 32;350uint32_t element_tag_depth_bits_size = render_element_max;351352cluster_render_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (element_tag_bits_size + element_tag_depth_bits_size) * 4; // Tag bits (element was used) and tag depth (depth range in which it was used).353354cluster_render_buffer = RD::get_singleton()->storage_buffer_create(cluster_render_buffer_size);355cluster_buffer = RD::get_singleton()->storage_buffer_create(cluster_buffer_size);356357render_elements = static_cast<RenderElementData *>(memalloc(sizeof(RenderElementData) * render_element_max));358render_element_count = 0;359360element_buffer = RD::get_singleton()->storage_buffer_create(sizeof(RenderElementData) * render_element_max);361362uint32_t div_value = 1 << divisor;363if (use_msaa) {364framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value, RD::TEXTURE_SAMPLES_4);365} else {366framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value);367}368369{370Vector<RD::Uniform> uniforms;371{372RD::Uniform u;373u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;374u.binding = 1;375u.append_id(state_uniform);376uniforms.push_back(u);377}378{379RD::Uniform u;380u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;381u.binding = 2;382u.append_id(element_buffer);383uniforms.push_back(u);384}385{386RD::Uniform u;387u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;388u.binding = 3;389u.append_id(cluster_render_buffer);390uniforms.push_back(u);391}392393cluster_render_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_render.shader, 0);394}395396{397Vector<RD::Uniform> uniforms;398{399RD::Uniform u;400u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;401u.binding = 1;402u.append_id(cluster_render_buffer);403uniforms.push_back(u);404}405{406RD::Uniform u;407u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;408u.binding = 2;409u.append_id(cluster_buffer);410uniforms.push_back(u);411}412413{414RD::Uniform u;415u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;416u.binding = 3;417u.append_id(element_buffer);418uniforms.push_back(u);419}420421cluster_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_store.shader, 0);422}423424if (p_color_buffer.is_valid()) {425Vector<RD::Uniform> uniforms;426{427RD::Uniform u;428u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;429u.binding = 1;430u.append_id(cluster_buffer);431uniforms.push_back(u);432}433{434RD::Uniform u;435u.uniform_type = RD::UNIFORM_TYPE_IMAGE;436u.binding = 2;437u.append_id(p_color_buffer);438uniforms.push_back(u);439}440441{442RD::Uniform u;443u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;444u.binding = 3;445u.append_id(p_depth_buffer);446uniforms.push_back(u);447}448{449RD::Uniform u;450u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;451u.binding = 4;452u.append_id(p_depth_buffer_sampler);453uniforms.push_back(u);454}455456debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_debug.shader, 0);457} else {458debug_uniform_set = RID();459}460}461462void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y) {463view_xform = p_view_transform.affine_inverse();464projection = p_cam_projection;465z_near = projection.get_z_near();466z_far = projection.get_z_far();467camera_orthogonal = p_cam_projection.is_orthogonal();468adjusted_projection = projection;469if (!camera_orthogonal) {470adjusted_projection.adjust_perspective_znear(0.0001);471}472473Projection correction;474correction.set_depth_correction(p_flip_y);475projection = correction * projection;476adjusted_projection = correction * adjusted_projection;477478// Reset counts.479render_element_count = 0;480for (uint32_t i = 0; i < ELEMENT_TYPE_MAX; i++) {481cluster_count_by_type[i] = 0;482}483}484485void ClusterBuilderRD::bake_cluster() {486RENDER_TIMESTAMP("> Bake 3D Cluster");487488RD::get_singleton()->draw_command_begin_label("Bake Light Cluster");489490// Clear cluster buffer.491RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size);492493if (render_element_count > 0) {494// Clear render buffer.495RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size);496497{ // Fill state uniform.498499StateUniform state;500501RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection);502state.inv_z_far = 1.0 / z_far;503state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);504state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less505506state.cluster_screen_width = cluster_screen_size.x;507state.cluster_depth_offset = (render_element_max / 32);508state.cluster_data_size = state.cluster_depth_offset + render_element_max;509510RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state);511}512513// Update instances.514515RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements);516517RENDER_TIMESTAMP("Render 3D Cluster Elements");518519// Render elements.520{521RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);522ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {};523524RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shared->cluster_render.shader_pipelines[use_msaa ? ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_MSAA : ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_NORMAL]);525RD::get_singleton()->draw_list_bind_uniform_set(draw_list, cluster_render_uniform_set, 0);526527for (uint32_t i = 0; i < render_element_count;) {528push_constant.base_index = i;529switch (render_elements[i].type) {530case ELEMENT_TYPE_OMNI_LIGHT: {531RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);532RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);533} break;534case ELEMENT_TYPE_SPOT_LIGHT: {535// If the spot angle is above a certain threshold, use a sphere instead of a cone for building the clusters536// since the cone gets too flat/large (spot angle close to 90 degrees) or537// can't even cover the affected area of the light (spot angle above 90 degrees).538if (render_elements[i].has_wide_spot_angle) {539RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);540RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);541} else {542RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array);543RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array);544}545} break;546case ELEMENT_TYPE_DECAL:547case ELEMENT_TYPE_REFLECTION_PROBE: {548RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->box_vertex_array);549RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->box_index_array);550} break;551}552553RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterRender::PushConstant));554555uint32_t instances = 1;556RD::get_singleton()->draw_list_draw(draw_list, true, instances);557i += instances;558}559RD::get_singleton()->draw_list_end();560}561// Store elements.562RENDER_TIMESTAMP("Pack 3D Cluster Elements");563564{565RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();566RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_store.shader_pipeline);567RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cluster_store_uniform_set, 0);568569ClusterBuilderSharedDataRD::ClusterStore::PushConstant push_constant;570push_constant.cluster_render_data_size = render_element_max / 32 + render_element_max;571push_constant.max_render_element_count_div_32 = render_element_max / 32;572push_constant.cluster_screen_size[0] = cluster_screen_size.x;573push_constant.cluster_screen_size[1] = cluster_screen_size.y;574575push_constant.render_element_count_div_32 = Math::division_round_up(render_element_count, 32U);576push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;577push_constant.pad1 = 0;578push_constant.pad2 = 0;579580RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterStore::PushConstant));581582RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1);583584RD::get_singleton()->compute_list_end();585}586}587RENDER_TIMESTAMP("< Bake 3D Cluster");588RD::get_singleton()->draw_command_end_label();589}590591void ClusterBuilderRD::debug(ElementType p_element) {592ERR_FAIL_COND(debug_uniform_set.is_null());593RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();594RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_debug.shader_pipeline);595RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0);596597ClusterBuilderSharedDataRD::ClusterDebug::PushConstant push_constant;598push_constant.screen_size[0] = screen_size.x;599push_constant.screen_size[1] = screen_size.y;600push_constant.cluster_screen_size[0] = cluster_screen_size.x;601push_constant.cluster_screen_size[1] = cluster_screen_size.y;602push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size);603push_constant.cluster_type = p_element;604push_constant.orthogonal = camera_orthogonal;605push_constant.z_far = z_far;606push_constant.z_near = z_near;607push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;608609RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterDebug::PushConstant));610611RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1);612613RD::get_singleton()->compute_list_end();614}615616RID ClusterBuilderRD::get_cluster_buffer() const {617return cluster_buffer;618}619620uint32_t ClusterBuilderRD::get_cluster_size() const {621return cluster_size;622}623624uint32_t ClusterBuilderRD::get_max_cluster_elements() const {625return max_elements_by_type;626}627628void ClusterBuilderRD::set_shared(ClusterBuilderSharedDataRD *p_shared) {629shared = p_shared;630}631632ClusterBuilderRD::ClusterBuilderRD() {633state_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(StateUniform));634}635636ClusterBuilderRD::~ClusterBuilderRD() {637_clear();638RD::get_singleton()->free(state_uniform);639}640641642