diff options
author | Juan Linietsky <reduzio@gmail.com> | 2019-10-05 10:27:43 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-02-11 12:03:49 +0100 |
commit | 6ee2f5e6b6663f5a4987954d43bb6df6d1f62d2a (patch) | |
tree | bef9b4f01f535c8736874199b2fbd928e1000d73 | |
parent | 6075c5f9bf6cf3362c51e0915555361d34954215 (diff) |
More GIProbe work and fixes
22 files changed, 233 insertions, 113 deletions
diff --git a/core/engine.cpp b/core/engine.cpp index 1772cc7c48..85ad175f38 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -214,6 +214,9 @@ Engine *Engine::get_singleton() { return singleton; } +bool Engine::is_abort_on_gpu_errors_enabled() const { + return abort_on_gpu_errors; +} Engine::Engine() { singleton = this; @@ -232,4 +235,5 @@ Engine::Engine() { _frame_ticks = 0; _frame_step = 0; editor_hint = false; + abort_on_gpu_errors = false; } diff --git a/core/engine.h b/core/engine.h index 1aab907ac8..cfe3a918fc 100644 --- a/core/engine.h +++ b/core/engine.h @@ -64,6 +64,7 @@ private: bool _pixel_snap; uint64_t _physics_frames; float _physics_interpolation_fraction; + bool abort_on_gpu_errors; uint64_t _idle_frames; bool _in_physics; @@ -126,6 +127,8 @@ public: Dictionary get_license_info() const; String get_license_text() const; + bool is_abort_on_gpu_errors_enabled() const; + Engine(); virtual ~Engine() {} }; diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index f644acc3be..16e25039f8 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1250,7 +1250,7 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, allocInfo.pUserData = NULL; VkResult err = vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &p_buffer->buffer, &p_buffer->allocation, NULL); - ERR_FAIL_COND_V(err, ERR_CANT_CREATE); + ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "Can't create buffer of size: " + itos(p_size)); p_buffer->size = p_size; p_buffer->buffer_info.buffer = p_buffer->buffer; p_buffer->buffer_info.offset = 0; @@ -1857,6 +1857,8 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID p_with_texture) { + _THREAD_SAFE_METHOD_ + Texture *src_texture = texture_owner.getornull(p_with_texture); ERR_FAIL_COND_V(!src_texture, RID()); @@ -1938,6 +1940,8 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { + _THREAD_SAFE_METHOD_ + Texture *src_texture = texture_owner.getornull(p_with_texture); ERR_FAIL_COND_V(!src_texture, RID()); @@ -2314,6 +2318,9 @@ PoolVector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture } PoolVector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t p_layer) { + + _THREAD_SAFE_METHOD_ + Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, PoolVector<uint8_t>()); @@ -2416,6 +2423,10 @@ PoolVector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint3 { + //despite textures being in block sizes, spec requiers they are in pixel sizes (?) + uint32_t computed_w = tex->width; + uint32_t computed_h = tex->height; + for (uint32_t i = 0; i < tex->mipmaps; i++) { uint32_t mm_width, mm_height, mm_depth; @@ -2438,11 +2449,14 @@ PoolVector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint3 image_copy_region.dstOffset.y = 0; image_copy_region.dstOffset.z = 0; - image_copy_region.extent.width = mm_width; - image_copy_region.extent.height = mm_height; - image_copy_region.extent.depth = mm_depth; + image_copy_region.extent.width = computed_w; + image_copy_region.extent.height = computed_h; + image_copy_region.extent.depth = mm_depth; //block is only x,y so this is fine anyway vkCmdCopyImage(command_buffer, tex->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy_region); + + computed_w = MAX(1, computed_w >> 1); + computed_h = MAX(1, computed_h >> 1); } } @@ -2500,6 +2514,8 @@ PoolVector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint3 } bool RenderingDeviceVulkan::texture_is_shared(RID p_texture) { + _THREAD_SAFE_METHOD_ + Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, false); return tex->owner.is_valid(); @@ -2511,6 +2527,8 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) { Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw) { + _THREAD_SAFE_METHOD_ + Texture *src_tex = texture_owner.getornull(p_from_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); @@ -2681,6 +2699,8 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) { + _THREAD_SAFE_METHOD_ + Texture *src_tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); @@ -4010,6 +4030,8 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages } uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_shader) { + _THREAD_SAFE_METHOD_ + const Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND_V(!shader, 0); return shader->vertex_input_mask; @@ -4690,6 +4712,8 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint PoolVector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { + _THREAD_SAFE_METHOD_ + Buffer *buffer = NULL; if (vertex_buffer_owner.owns(p_buffer)) { buffer = vertex_buffer_owner.getornull(p_buffer); @@ -6077,7 +6101,7 @@ void RenderingDeviceVulkan::draw_list_end() { // To ensure proper synchronization, we must make sure rendering is done before: // * Some buffer is copied // * Another render pass happens (since we may be done - _memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, true); + _memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, true); } /***********************/ @@ -6284,9 +6308,12 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t ComputeList *cl = compute_list; #ifdef DEBUG_ENABLED - ERR_FAIL_COND(p_x_groups > limits.maxComputeWorkGroupCount[0]); - ERR_FAIL_COND(p_y_groups > limits.maxComputeWorkGroupCount[1]); - ERR_FAIL_COND(p_z_groups > limits.maxComputeWorkGroupCount[2]); + ERR_FAIL_COND_MSG(p_x_groups > limits.maxComputeWorkGroupCount[0], + "Dispatch amount of X compute groups (" + itos(p_x_groups) + ") is larger than device limit (" + itos(limits.maxComputeWorkGroupCount[0]) + ")"); + ERR_FAIL_COND_MSG(p_y_groups > limits.maxComputeWorkGroupCount[1], + "Dispatch amount of Y compute groups (" + itos(p_x_groups) + ") is larger than device limit (" + itos(limits.maxComputeWorkGroupCount[0]) + ")"); + ERR_FAIL_COND_MSG(p_z_groups > limits.maxComputeWorkGroupCount[2], + "Dispatch amount of Z compute groups (" + itos(p_x_groups) + ") is larger than device limit (" + itos(limits.maxComputeWorkGroupCount[0]) + ")"); ERR_FAIL_COND_MSG(!cl->validation.active, "Submitted Compute Lists can no longer be modified."); #endif @@ -6500,24 +6527,75 @@ void RenderingDeviceVulkan::free(RID p_id) { _free_dependencies(p_id); //recursively erase dependencies first, to avoid potential API problems _free_internal(p_id); } - -void RenderingDeviceVulkan::finalize_frame() { +void RenderingDeviceVulkan::swap_buffers() { _THREAD_SAFE_METHOD_ - if (draw_list) { - ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); - } + { //finalize frame - if (compute_list) { - ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work)."); + if (draw_list) { + ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); + } + + if (compute_list) { + ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work)."); + } + + { //complete the setup buffer (that needs to be processed before anything else) + vkEndCommandBuffer(frames[frame].setup_command_buffer); + vkEndCommandBuffer(frames[frame].draw_command_buffer); + } + screen_prepared = false; } - { //complete the setup buffer (that needs to be processed before anything else) - vkEndCommandBuffer(frames[frame].setup_command_buffer); - vkEndCommandBuffer(frames[frame].draw_command_buffer); + //swap buffers + context->swap_buffers(); + + { //advance frame + + frame = (frame + 1) % frame_count; + + //erase pending resources + _free_pending_resources(frame); + + //create setup command buffer and set as the setup buffer + + { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = NULL; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = NULL; + + VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0); + ERR_FAIL_COND(err); + + err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND(err); + context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else + err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND(err); + context->append_command_buffer(frames[frame].draw_command_buffer); + } + + //advance current frame + frames_drawn++; + //advance staging buffer if used + if (staging_buffer_used) { + staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size(); + staging_buffer_used = false; + } + + if (frames[frame].timestamp_count) { + vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); + SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); + SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); + } + + frames[frame].timestamp_result_count = frames[frame].timestamp_count; + frames[frame].timestamp_count = 0; + frames[frame].index = Engine::get_singleton()->get_frames_drawn(); } - screen_prepared = false; } void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { @@ -6630,55 +6708,6 @@ void RenderingDeviceVulkan::prepare_screen_for_drawing() { screen_prepared = true; } -void RenderingDeviceVulkan::advance_frame() { - - _THREAD_SAFE_METHOD_ - - //advance the frame - frame = (frame + 1) % frame_count; - - //erase pending resources - _free_pending_resources(frame); - - //create setup command buffer and set as the setup buffer - - { - VkCommandBufferBeginInfo cmdbuf_begin; - cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmdbuf_begin.pNext = NULL; - cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - cmdbuf_begin.pInheritanceInfo = NULL; - - VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0); - ERR_FAIL_COND(err); - - err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND(err); - context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else - err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND(err); - context->append_command_buffer(frames[frame].draw_command_buffer); - } - - //advance current frame - frames_drawn++; - //advance staging buffer if used - if (staging_buffer_used) { - staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size(); - staging_buffer_used = false; - } - - if (frames[frame].timestamp_count) { - vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); - SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); - SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); - } - - frames[frame].timestamp_result_count = frames[frame].timestamp_count; - frames[frame].timestamp_count = 0; - frames[frame].index = Engine::get_singleton()->get_frames_drawn(); -} - uint32_t RenderingDeviceVulkan::get_frame_delay() const { return frame_count; } @@ -6793,7 +6822,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context) { { //begin the first command buffer for the first frame, so - //setting up things can be done in the meantime until finalize_frame(), which is called before advance. + //setting up things can be done in the meantime until swap_buffers(), which is called before advance. VkCommandBufferBeginInfo cmdbuf_begin; cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cmdbuf_begin.pNext = NULL; @@ -6957,6 +6986,14 @@ int RenderingDeviceVulkan::limit_get(Limit p_limit) { case LIMIT_MAX_VERTEX_INPUT_BINDINGS: return limits.maxVertexInputBindings; case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: return limits.maxVertexInputBindingStride; case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: return limits.minUniformBufferOffsetAlignment; + case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X: return limits.maxComputeWorkGroupCount[0]; + case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y: return limits.maxComputeWorkGroupCount[1]; + case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z: return limits.maxComputeWorkGroupCount[2]; + case LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS: return limits.maxComputeWorkGroupInvocations; + case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X: return limits.maxComputeWorkGroupSize[0]; + case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y: return limits.maxComputeWorkGroupSize[1]; + case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z: return limits.maxComputeWorkGroupSize[2]; + default: ERR_FAIL_V(0); } diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index d487f4612e..6b7d9e7c98 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1116,8 +1116,7 @@ public: void initialize(VulkanContext *p_context); void finalize(); - virtual void finalize_frame(); - virtual void advance_frame(); + virtual void swap_buffers(); virtual uint32_t get_frame_delay() const; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 34ce79ab02..b6edf5f079 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "vulkan_context.h" +#include "core/engine.h" #include "core/print_string.h" #include "core/project_settings.h" #include "core/version.h" @@ -36,6 +37,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #define VULKAN_DEBUG(m_text) print_line(m_text) #define APP_SHORT_NAME "GodotEngine" @@ -121,7 +123,9 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU free(message); - // abort(); + if (Engine::get_singleton()->is_abort_on_gpu_errors_enabled()) { + abort(); + } // Don't bail out, but keep going. return false; } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index c3f548493c..74190e32c5 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2767,7 +2767,8 @@ void SpatialEditorViewport::_menu_option(int p_option) { case VIEW_DISPLAY_DEBUG_SHADOW_ATLAS: case VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS: case VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO: - case VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING: { + case VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING: + case VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION: { static const int display_options[] = { VIEW_DISPLAY_NORMAL, @@ -2780,6 +2781,7 @@ void SpatialEditorViewport::_menu_option(int p_option) { VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS, VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO, VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING, + VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION, VIEW_MAX }; static const Viewport::DebugDraw debug_draw_modes[] = { @@ -2792,7 +2794,8 @@ void SpatialEditorViewport::_menu_option(int p_option) { Viewport::DEBUG_DRAW_SHADOW_ATLAS, Viewport::DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, Viewport::DEBUG_DRAW_GI_PROBE_ALBEDO, - Viewport::DEBUG_DRAW_GI_PROBE_LIGHTING + Viewport::DEBUG_DRAW_GI_PROBE_LIGHTING, + Viewport::DEBUG_DRAW_GI_PROBE_EMISSION }; int idx = 0; @@ -3635,6 +3638,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("GIProbe Lighting"), VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING); display_submenu->add_radio_check_item(TTR("GIProbe Albedo"), VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO); + display_submenu->add_radio_check_item(TTR("GIProbe Emission"), VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION); display_submenu->set_name("display_advanced"); view_menu->get_popup()->add_submenu_item(TTR("Display Advanced..."), "display_advanced"); view_menu->get_popup()->add_separator(); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 7bd8ffa54c..8f09bdfece 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -172,6 +172,7 @@ class SpatialEditorViewport : public Control { VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS, VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO, VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING, + VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION, VIEW_LOCK_ROTATION, VIEW_CINEMATIC_PREVIEW, VIEW_MAX diff --git a/main/main.cpp b/main/main.cpp index fdc94fd896..1b8b95c4c3 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -286,6 +286,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n"); OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n"); + OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n"); OS::get_singleton()->print(" --remote-debug <address> Remote debug (<host/IP>:<port> address).\n"); #if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED) OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n"); @@ -548,6 +549,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window init_windowed = true; + } else if (I->get() == "--gpu-abort") { // force windowed window + + Engine::singleton->abort_on_gpu_errors = true; } else if (I->get() == "-t" || I->get() == "--always-on-top") { // force always-on-top window init_always_on_top = true; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index e19e808df1..338194fcae 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -872,7 +872,6 @@ void OS_X11::finalize() { if (context_gles2) memdelete(context_gles2); - } #endif #if defined(VULKAN_ENABLED) @@ -3146,11 +3145,12 @@ void OS_X11::swap_buffers() { context_gles2->swap_buffers(); } #endif + /* not needed for now #if defined(VULKAN_ENABLED) if (video_driver_index == VIDEO_DRIVER_VULKAN) { context_vulkan->swap_buffers(); } -#endif +#endif*/ } void OS_X11::alert(const String &p_alert, const String &p_title) { diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 22b453f837..5d9a791e80 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -1144,7 +1144,7 @@ void CPUParticles::_update_render_thread() { update_mutex->lock(); #endif if (can_update) { - VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); + //VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); can_update = false; //wait for next time } diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 32afcc7935..52c4efb7f1 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -409,6 +409,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { probe_data->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_giprobe_octree_size(), baker.get_giprobe_octree_cells(), baker.get_giprobe_data_cells(), baker.get_giprobe_level_cell_count()); set_probe_data(probe_data); + probe_data->set_edited(true); //so it gets saved } if (bake_end_function) { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 7399898a51..87bb8344b9 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -133,6 +133,7 @@ public: DEBUG_DRAW_WIREFRAME, DEBUG_DRAW_GI_PROBE_ALBEDO, DEBUG_DRAW_GI_PROBE_LIGHTING, + DEBUG_DRAW_GI_PROBE_EMISSION, DEBUG_DRAW_SHADOW_ATLAS, DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_rd.cpp index fc38b90b88..89465b580c 100644 --- a/servers/visual/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_rd.cpp @@ -84,12 +84,10 @@ void RasterizerRD::begin_frame(double frame_step) { void RasterizerRD::end_frame(bool p_swap_buffers) { - RD::get_singleton()->finalize_frame(); #ifndef _MSC_VER -#warning not swapping buffers likely not an option for now, find another way +#warning TODO: likely passa bool to swap buffers to avoid display? #endif - OS::get_singleton()->swap_buffers(); //probably should pass some bool to avoid display? - RD::get_singleton()->advance_frame(); //advance frame here, so any new call happens on new frame + RD::get_singleton()->swap_buffers(); //probably should pass some bool to avoid display? } void RasterizerRD::initialize() { diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp index 502ac9196f..55974846f2 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp @@ -1899,7 +1899,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co _fill_instances(render_list.elements, render_list.element_count); bool can_continue = true; //unless the middle buffers are needed - bool debug_giprobes = debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING; + bool debug_giprobes = debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION; bool using_separate_specular = false; bool depth_pre_pass = depth_framebuffer.is_valid(); @@ -1930,7 +1930,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); for (int i = 0; i < p_gi_probe_cull_count; i++) { - _debug_giprobe(p_gi_probe_cull_result[i], draw_list, opaque_framebuffer, cm, debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, 1.0); + _debug_giprobe(p_gi_probe_cull_result[i], draw_list, opaque_framebuffer, cm, debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, debug_draw == VS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0); } RD::get_singleton()->draw_list_end(); } @@ -2204,10 +2204,15 @@ void RasterizerSceneForwardRD::_update_render_base_uniform_set() { } else { u.ids.resize(slot_count); } + + print_line("updating slots, probe count: " + itos(slot_count)); for (int i = 0; i < slot_count; i++) { RID probe = gi_probe_get_slots()[i]; + if (probe.is_valid()) { + print_line("probe valid: " + itos(i)); + } if (gi_probe_is_anisotropic()) { if (probe.is_null()) { RID empty_tex = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp index 1b7d5a8e47..f039bae766 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp @@ -1439,6 +1439,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, const Vector<RID> &p_light_ } gi_probe->last_probe_data_version = data_version; + gi_probe_slots_dirty = true; } // UDPDATE TIME @@ -1510,6 +1511,8 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, const Vector<RID> &p_light_ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int passes = storage->gi_probe_is_using_two_bounces(gi_probe->probe) ? 2 : 1; + int wg_size = 64; + int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); for (int pass = 0; pass < passes; pass++) { @@ -1532,9 +1535,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, const Vector<RID> &p_light_ push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset; push_constant.cell_count = gi_probe->mipmaps[i].cell_count; - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant)); - - RD::get_singleton()->compute_list_dispatch(compute_list, (gi_probe->mipmaps[i].cell_count - 1) / 64 + 1, 1, 1); + int wg_todo = (gi_probe->mipmaps[i].cell_count - 1) / wg_size + 1; + while (wg_todo) { + int wg_count = MIN(wg_todo, wg_limit_x); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); + wg_todo -= wg_count; + push_constant.cell_offset += wg_count * wg_size; + } } RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done @@ -1548,9 +1556,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, const Vector<RID> &p_light_ push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset; push_constant.cell_count = gi_probe->mipmaps[i].cell_count; - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant)); - - RD::get_singleton()->compute_list_dispatch(compute_list, (gi_probe->mipmaps[i].cell_count - 1) / 64 + 1, 1, 1); + int wg_todo = (gi_probe->mipmaps[i].cell_count - 1) / wg_size + 1; + while (wg_todo) { + int wg_count = MIN(wg_todo, wg_limit_x); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); + wg_todo -= wg_count; + push_constant.cell_offset += wg_count * wg_size; + } } } @@ -1560,7 +1573,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, const Vector<RID> &p_light_ gi_probe->last_probe_version = storage->gi_probe_get_version(gi_probe->probe); } -void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, float p_alpha) { +void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -1631,7 +1644,7 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis } giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_debug_shader_version_shaders[0], 0); - RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, giprobe_debug_shader_version_pipelines[p_lighting ? GI_PROBE_DEBUG_LIGHT : GI_PROBE_DEBUG_COLOR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); + RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, giprobe_debug_shader_version_pipelines[p_emission ? GI_PROBE_DEBUG_EMISSION : p_lighting ? GI_PROBE_DEBUG_LIGHT : GI_PROBE_DEBUG_COLOR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, giprobe_debug_uniform_set, 0); RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant)); RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36); @@ -2007,6 +2020,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { Vector<String> versions; versions.push_back("\n#define MODE_DEBUG_COLOR\n"); versions.push_back("\n#define MODE_DEBUG_LIGHT\n"); + versions.push_back("\n#define MODE_DEBUG_EMISSION\n"); giprobe_debug_shader.initialize(versions, defines); giprobe_debug_shader_version = giprobe_debug_shader.version_create(); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h index 7acb66c587..d05c9a9328 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h @@ -27,7 +27,7 @@ protected: virtual void _render_scene(RenderBufferData *p_buffer_data, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip) = 0; - virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, float p_alpha); + virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); private: int roughness_layers; @@ -210,6 +210,7 @@ private: enum { GI_PROBE_DEBUG_COLOR, GI_PROBE_DEBUG_LIGHT, + GI_PROBE_DEBUG_EMISSION, GI_PROBE_DEBUG_MAX }; diff --git a/servers/visual/rasterizer_rd/shaders/giprobe.glsl b/servers/visual/rasterizer_rd/shaders/giprobe.glsl index 35b8d6ba6b..a723490e8b 100644 --- a/servers/visual/rasterizer_rd/shaders/giprobe.glsl +++ b/servers/visual/rasterizer_rd/shaders/giprobe.glsl @@ -248,7 +248,7 @@ void main() { vec3 pos = vec3(posu) + vec3(0.5); - vec3 emission = vec3(ivec3(cell_data.data[cell_index].emission&0x3FF,(cell_data.data[cell_index].emission>>10)&0x7FF,cell_data.data[cell_index].emission>>21)) * params.emission_scale; + vec3 emission = vec3(uvec3(cell_data.data[cell_index].emission & 0x1ff,(cell_data.data[cell_index].emission >> 9) & 0x1ff,(cell_data.data[cell_index].emission >> 18) & 0x1ff)) * pow(2.0, float(cell_data.data[cell_index].emission >> 27) - 15.0 - 9.0); vec4 normal = unpackSnorm4x8(cell_data.data[cell_index].normal); #ifdef MODE_ANISOTROPIC @@ -271,8 +271,8 @@ void main() { float distance = length(light_dir); light_dir=normalize(light_dir); - if (length(normal.xyz) > 0.2 && dot(normal.xyz,light_dir)>=0) { - continue; //not facing the light + if (attenuation < 0.01 || (length(normal.xyz) > 0.2 && dot(normal.xyz,light_dir)>=0)) { + continue; //not facing the light, or attenuation is near zero } if (lights.data[i].has_shadow) { @@ -299,11 +299,11 @@ void main() { #ifdef MODE_ANISOTROPIC for(uint j=0;j<6;j++) { - accum[j]+=max(0.0,dot(accum_dirs[j],-light_dir))*light+emission; + accum[j]+=max(0.0,dot(accum_dirs[j],-light_dir))*light; } #else if (length(normal.xyz) > 0.2) { - accum+=max(0.0,dot(normal.xyz,-light_dir))*light+emission; + accum+=max(0.0,dot(normal.xyz,-light_dir))*light; } else { //all directions accum+=light+emission; @@ -314,14 +314,14 @@ void main() { #ifdef MODE_ANISOTROPIC - outputs.data[cell_index*6+0]=vec4(accum[0],0.0); - outputs.data[cell_index*6+1]=vec4(accum[1],0.0); - outputs.data[cell_index*6+2]=vec4(accum[2],0.0); - outputs.data[cell_index*6+3]=vec4(accum[3],0.0); - outputs.data[cell_index*6+4]=vec4(accum[4],0.0); - outputs.data[cell_index*6+5]=vec4(accum[5],0.0); + outputs.data[cell_index*6+0]=vec4(accum[0] + emission,0.0); + outputs.data[cell_index*6+1]=vec4(accum[1] + emission,0.0); + outputs.data[cell_index*6+2]=vec4(accum[2] + emission,0.0); + outputs.data[cell_index*6+3]=vec4(accum[3] + emission,0.0); + outputs.data[cell_index*6+4]=vec4(accum[4] + emission,0.0); + outputs.data[cell_index*6+5]=vec4(accum[5] + emission,0.0); #else - outputs.data[cell_index]=vec4(accum,0.0); + outputs.data[cell_index]=vec4(accum + emission,0.0); #endif @@ -420,7 +420,7 @@ void main() { } } - color *= cone_weights[i] * params.dynamic_range; //restore range + color *= cone_weights[i] * vec4(albedo.rgb,1.0) * params.dynamic_range; //restore range #ifdef MODE_ANISOTROPIC for(uint j=0;j<6;j++) { diff --git a/servers/visual/rasterizer_rd/shaders/giprobe_debug.glsl b/servers/visual/rasterizer_rd/shaders/giprobe_debug.glsl index deaeb771b9..71ecaffde7 100644 --- a/servers/visual/rasterizer_rd/shaders/giprobe_debug.glsl +++ b/servers/visual/rasterizer_rd/shaders/giprobe_debug.glsl @@ -85,9 +85,14 @@ void main() { uvec3 posu = uvec3(cell_data.data[cell_index].position&0x7FF,(cell_data.data[cell_index].position>>11)&0x3FF,cell_data.data[cell_index].position>>21); +#ifdef MODE_DEBUG_EMISSION + color_interp.xyz = vec3(uvec3(cell_data.data[cell_index].emission & 0x1ff,(cell_data.data[cell_index].emission >> 9) & 0x1ff,(cell_data.data[cell_index].emission >> 18) & 0x1ff)) * pow(2.0, float(cell_data.data[cell_index].emission >> 27) - 15.0 - 9.0); +#endif + #ifdef MODE_DEBUG_COLOR color_interp.xyz = unpackUnorm4x8(cell_data.data[cell_index].albedo).xyz; #endif + #ifdef MODE_DEBUG_LIGHT #ifdef USE_ANISOTROPY diff --git a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl index 2070df3952..a54a84536a 100644 --- a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl +++ b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl @@ -326,9 +326,9 @@ layout(location =8) in float dp_clip; //defines to keep compatibility with vertex -#define world_matrix instances.data[instance_index].transform; -#define world_normal_matrix instances.data[instance_index].normal_transform; -#define projection_matrix scene_data.projection_matrix; +#define world_matrix instances.data[instance_index].transform +#define world_normal_matrix instances.data[instance_index].normal_transform +#define projection_matrix scene_data.projection_matrix #ifdef USE_MATERIAL_UNIFORMS layout(set = 3, binding = 0, std140) uniform MaterialUniforms { diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h index f5a212b076..75eaab796a 100644 --- a/servers/visual/rendering_device.h +++ b/servers/visual/rendering_device.h @@ -1002,14 +1002,23 @@ public: LIMIT_MAX_VERTEX_INPUT_BINDINGS, LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE, LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT, + LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE, + LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X, + LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y, + LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z, + LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS, + LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X, + LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y, + LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z, }; virtual int limit_get(Limit p_limit) = 0; //methods below not exposed, used by RenderingDeviceRD virtual void prepare_screen_for_drawing() = 0; - virtual void finalize_frame() = 0; - virtual void advance_frame() = 0; + + virtual void swap_buffers() = 0; + virtual uint32_t get_frame_delay() const = 0; static RenderingDevice *get_singleton(); diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index f7b118bfe5..8d38cf02b3 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -345,7 +345,11 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { case VS::INSTANCE_LIGHT: { InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); - +#ifdef DEBUG_ENABLED + if (light->geometries.size()) { + ERR_PRINT("BUG, indexing did not unpair geometries from light."); + } +#endif if (instance->scenario && light->D) { instance->scenario->directional_lights.erase(light->D); light->D = NULL; @@ -371,7 +375,16 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { case VS::INSTANCE_GI_PROBE: { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); - +#ifdef DEBUG_ENABLED + if (gi_probe->geometries.size()) { + ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe."); + } +#endif +#ifdef DEBUG_ENABLED + if (gi_probe->lights.size()) { + ERR_PRINT("BUG, indexing did not unpair lights from GIProbe."); + } +#endif if (gi_probe->update_element.in_list()) { gi_probe_update_list.remove(&gi_probe->update_element); } @@ -490,7 +503,11 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { case VS::INSTANCE_LIGHT: { InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); - +#ifdef DEBUG_ENABLED + if (light->geometries.size()) { + ERR_PRINT("BUG, indexing did not unpair geometries from light."); + } +#endif if (light->D) { instance->scenario->directional_lights.erase(light->D); light->D = NULL; @@ -504,6 +521,18 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { case VS::INSTANCE_GI_PROBE: { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); + +#ifdef DEBUG_ENABLED + if (gi_probe->geometries.size()) { + ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe."); + } +#endif +#ifdef DEBUG_ENABLED + if (gi_probe->lights.size()) { + ERR_PRINT("BUG, indexing did not unpair lights from GIProbe."); + } +#endif + if (gi_probe->update_element.in_list()) { gi_probe_update_list.remove(&gi_probe->update_element); } diff --git a/servers/visual_server.h b/servers/visual_server.h index 5408ad665b..3523afc305 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -652,6 +652,7 @@ public: VIEWPORT_DEBUG_DRAW_WIREFRAME, VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO, VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, + VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS, VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, |