diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index af3b6d443666..50f86ef05795 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -1573,12 +1573,6 @@ RDD::TextureID RenderingDeviceDriverD3D12::texture_create(const TextureFormat &p tex_info->view_descs.srv = srv_desc; tex_info->view_descs.uav = uav_desc; - if (!barrier_capabilities.enhanced_barriers_supported && (p_format.usage_bits & (TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_COLOR_ATTACHMENT_BIT))) { - // Fallback to clear resources when they're first used in a uniform set. Not necessary if enhanced barriers - // are supported, as the discard flag will be used instead when transitioning from an undefined layout. - textures_pending_clear.add(&tex_info->pending_clear); - } - return TextureID(tex_info); } @@ -3055,7 +3049,7 @@ D3D12_UNORDERED_ACCESS_VIEW_DESC RenderingDeviceDriverD3D12::_make_ranged_uav_fo } break; case D3D12_UAV_DIMENSION_TEXTURE3D: { uav_desc.Texture3D.MipSlice = mip; - uav_desc.Texture3D.WSize >>= p_mipmap_offset; + uav_desc.Texture3D.WSize = MAX(uav_desc.Texture3D.WSize >> p_mipmap_offset, 1U); } break; default: break; @@ -3643,21 +3637,6 @@ void RenderingDeviceDriverD3D12::command_uniform_set_prepare_for_use(CommandBuff return; } - // Perform pending blackouts. - { - SelfList *E = textures_pending_clear.first(); - while (E) { - TextureSubresourceRange subresources; - subresources.layer_count = E->self()->layers; - subresources.mipmap_count = E->self()->mipmaps; - command_clear_color_texture(p_cmd_buffer, TextureID(E->self()), TEXTURE_LAYOUT_UNDEFINED, Color(), subresources); - - SelfList *next = E->next(); - E->remove_from_list(); - E = next; - } - } - CommandBufferInfo *cmd_buf_info = (CommandBufferInfo *)p_cmd_buffer.id; const UniformSetInfo *uniform_set_info = (const UniformSetInfo *)p_uniform_set.id; const ShaderInfo *shader_info_in = (const ShaderInfo *)p_shader.id; @@ -4571,8 +4550,7 @@ void RenderingDeviceDriverD3D12::command_begin_render_pass(CommandBufferID p_cmd p_rect.position.y, p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y); - cmd_buf_info->render_pass_state.region_is_all = !( - cmd_buf_info->render_pass_state.region_rect.left == 0 && + cmd_buf_info->render_pass_state.region_is_all = (cmd_buf_info->render_pass_state.region_rect.left == 0 && cmd_buf_info->render_pass_state.region_rect.top == 0 && cmd_buf_info->render_pass_state.region_rect.right == fb_info->size.x && cmd_buf_info->render_pass_state.region_rect.bottom == fb_info->size.y); @@ -4616,7 +4594,6 @@ void RenderingDeviceDriverD3D12::command_begin_render_pass(CommandBufferID p_cmd if (pass_info->attachments[i].load_op == ATTACHMENT_LOAD_OP_CLEAR) { clear.aspect.set_flag(TEXTURE_ASPECT_COLOR_BIT); clear.color_attachment = i; - tex_info->pending_clear.remove_from_list(); } } else if ((tex_info->desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) { if (pass_info->attachments[i].load_op == ATTACHMENT_LOAD_OP_CLEAR) { @@ -5799,6 +5776,8 @@ uint64_t RenderingDeviceDriverD3D12::api_trait_get(ApiTrait p_trait) { return true; case API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS: return !barrier_capabilities.enhanced_barriers_supported; + case API_TRAIT_TEXTURE_OUTPUTS_REQUIRE_CLEARS: + return true; default: return RenderingDeviceDriver::api_trait_get(p_trait); } @@ -5807,7 +5786,7 @@ uint64_t RenderingDeviceDriverD3D12::api_trait_get(ApiTrait p_trait) { bool RenderingDeviceDriverD3D12::has_feature(Features p_feature) { switch (p_feature) { case SUPPORTS_HALF_FLOAT: - return shader_capabilities.native_16bit_ops && storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported; + return shader_capabilities.native_16bit_ops; case SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS: return true; case SUPPORTS_BUFFER_DEVICE_ADDRESS: @@ -6037,7 +6016,6 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() { subgroup_capabilities.wave_ops_supported = false; shader_capabilities.shader_model = (D3D_SHADER_MODEL)0; shader_capabilities.native_16bit_ops = false; - storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false; format_capabilities.relaxed_casting_supported = false; { @@ -6078,9 +6056,8 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() { D3D12_FEATURE_DATA_D3D12_OPTIONS options = {}; res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); - if (SUCCEEDED(res)) { - storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = options.TypedUAVLoadAdditionalFormats; - } + ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_UNAVAILABLE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); + ERR_FAIL_COND_V_MSG(!options.TypedUAVLoadAdditionalFormats, ERR_UNAVAILABLE, "No support for Typed UAV Load Additional Formats has been found."); D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1 = {}; res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1)); diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 602c4d48f235..e90a3867a5d5 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -114,10 +114,6 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { bool native_16bit_ops = false; }; - struct StorageBufferCapabilities { - bool storage_buffer_16_bit_access_is_supported = false; - }; - struct FormatCapabilities { bool relaxed_casting_supported = false; }; @@ -143,7 +139,6 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { FragmentShadingRateCapabilities fsr_capabilities; FragmentDensityMapCapabilities fdm_capabilities; ShaderCapabilities shader_capabilities; - StorageBufferCapabilities storage_buffer_capabilities; FormatCapabilities format_capabilities; BarrierCapabilities barrier_capabilities; MiscFeaturesSupport misc_features_support; @@ -360,12 +355,10 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { TextureInfo *main_texture = nullptr; UINT mapped_subresource = UINT_MAX; - SelfList pending_clear{ this }; #ifdef DEBUG_ENABLED bool created_from_extension = false; #endif }; - SelfList::List textures_pending_clear; HashMap format_sample_counts_mask_cache; Mutex format_sample_counts_mask_cache_mutex; diff --git a/drivers/d3d12/rendering_shader_container_d3d12.cpp b/drivers/d3d12/rendering_shader_container_d3d12.cpp index 1b484e24d718..a951393f272b 100644 --- a/drivers/d3d12/rendering_shader_container_d3d12.cpp +++ b/drivers/d3d12/rendering_shader_container_d3d12.cpp @@ -99,28 +99,26 @@ uint32_t RenderingDXIL::patch_specialization_constant( const uint64_t (&p_stages_bit_offsets)[D3D12_BITCODE_OFFSETS_NUM_STAGES], HashMap> &r_stages_bytecodes, bool p_is_first_patch) { - uint32_t patch_val = 0; + int64_t patch_val = 0; switch (p_type) { case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT: { - uint32_t int_value = *((const int *)p_value); - ERR_FAIL_COND_V(int_value & (1 << 31), 0); - patch_val = int_value; + patch_val = *((const int32_t *)p_value); } break; case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL: { bool bool_value = *((const bool *)p_value); - patch_val = (uint32_t)bool_value; + patch_val = (int32_t)bool_value; } break; case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT: { - uint32_t int_value = *((const int *)p_value); - ERR_FAIL_COND_V(int_value & (1 << 31), 0); - patch_val = (int_value >> 1); + patch_val = *((const int32_t *)p_value); } break; } - // For VBR encoding to encode the number of bits we expect (32), we need to set the MSB unconditionally. - // However, signed VBR moves the MSB to the LSB, so setting the MSB to 1 wouldn't help. Therefore, - // the bit we set to 1 is the one at index 30. - patch_val |= (1 << 30); - patch_val <<= 1; // What signed VBR does. + + // Encode to signed VBR. + if (patch_val >= 0) { + patch_val <<= 1; + } else { + patch_val = ((-patch_val) << 1) | 1; + } auto tamper_bits = [](uint8_t *p_start, uint64_t p_bit_offset, uint64_t p_tb_value) -> uint64_t { uint64_t original = 0; @@ -174,13 +172,13 @@ uint32_t RenderingDXIL::patch_specialization_constant( Vector &bytecode = r_stages_bytecodes[(RenderingDeviceCommons::ShaderStage)stage]; #ifdef DEV_ENABLED - uint64_t orig_patch_val = tamper_bits(bytecode.ptrw(), offset, patch_val); + uint64_t orig_patch_val = tamper_bits(bytecode.ptrw(), offset, (uint64_t)patch_val); // Checking against the value the NIR patch should have set. DEV_ASSERT(!p_is_first_patch || ((orig_patch_val >> 1) & GODOT_NIR_SC_SENTINEL_MAGIC_MASK) == GODOT_NIR_SC_SENTINEL_MAGIC); - uint64_t readback_patch_val = tamper_bits(bytecode.ptrw(), offset, patch_val); - DEV_ASSERT(readback_patch_val == patch_val); + uint64_t readback_patch_val = tamper_bits(bytecode.ptrw(), offset, (uint64_t)patch_val); + DEV_ASSERT(readback_patch_val == (uint64_t)patch_val); #else - tamper_bits(bytecode.ptrw(), offset, patch_val); + tamper_bits(bytecode.ptrw(), offset, (uint64_t)patch_val); #endif stages_patched_mask |= (1 << stage); @@ -319,10 +317,6 @@ bool RenderingShaderContainerD3D12::_convert_spirv_to_nir(const Vectorsize) { diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 2814f41c3767..d99fd5563cc2 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1022,12 +1022,6 @@ uniform highp mat4 world_transform; uniform highp uint instance_offset; uniform highp uint model_flags; -/* clang-format off */ - -#GLOBALS - -/* clang-format on */ - #define LIGHT_BAKE_DISABLED 0u #define LIGHT_BAKE_STATIC 1u #define LIGHT_BAKE_DYNAMIC 2u @@ -1268,6 +1262,12 @@ layout(location = 0) out vec4 frag_color; #endif // !RENDER_MATERIAL +/* clang-format off */ + +#GLOBALS + +/* clang-format on */ + vec3 F0(float metallic, float specular, vec3 albedo) { float dielectric = 0.16 * specular * specular; // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 5c50aed954b7..98d41704301f 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -232,7 +232,7 @@ Config::Config() { //https://github.com/godotengine/godot/issues/92662#issuecomment-2161199477 //disable_particles_workaround = false; } - } else if (rendering_device_name == "PowerVR Rogue GE8320") { + } else if (rendering_device_name.contains("PowerVR")) { disable_transform_feedback_shader_cache = true; } diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index f58f769b3e46..767dd86c3223 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -350,7 +350,14 @@ AABB LightStorage::light_get_aabb(RID p_light) const { switch (light->type) { case RS::LIGHT_SPOT: { float len = light->param[RS::LIGHT_PARAM_RANGE]; - float size = Math::tan(Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len; + float angle = Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE]); + + if (angle > Math::PI * 0.5) { + // Light casts backwards as well. + return AABB(Vector3(-1, -1, -1) * len, Vector3(2, 2, 2) * len); + } + + float size = Math::sin(angle) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); }; case RS::LIGHT_OMNI: { @@ -807,6 +814,9 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ ERR_FAIL_NULL_V(atlas, false); + ERR_FAIL_COND_V_MSG(atlas->size < 4, false, "Attempted to render to a reflection atlas of invalid resolution."); + ERR_FAIL_COND_V_MSG(atlas->count < 1, false, "Attempted to render to a reflection atlas of size < 1."); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_NULL_V(rpi, false); diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 565678479387..747c45d84124 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -2265,6 +2265,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { } if (shader->data) { + shader->data->set_path_hint(shader->path_hint); shader->data->set_code(p_code); } diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.cpp b/drivers/gles3/storage/render_scene_buffers_gles3.cpp index 1ad5dc6bcbad..e0a426de9b2b 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.cpp +++ b/drivers/gles3/storage/render_scene_buffers_gles3.cpp @@ -200,6 +200,10 @@ void RenderSceneBuffersGLES3::_check_render_buffers() { uint32_t depth_format_size = 4; bool use_multiview = view_count > 1; + if (!use_internal_buffer && internal3d.color != 0) { + _clear_intermediate_buffers(); + } + if ((!use_internal_buffer || internal3d.color != 0) && (msaa3d.mode == RS::VIEWPORT_MSAA_DISABLED || msaa3d.color != 0)) { // already setup! return; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 7cc27c2167c9..231ed930481b 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -1535,6 +1535,14 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t const uint32_t reset_descriptor_pool_fixed_driver_begin = VK_MAKE_VERSION(512u, 671u, 0u); linear_descriptor_pools_enabled = physical_device_properties.driverVersion < reset_descriptor_pool_broken_driver_begin || physical_device_properties.driverVersion > reset_descriptor_pool_fixed_driver_begin; } + + // Workaround a driver bug on Adreno 5XX GPUs that causes a crash when + // there are empty descriptor set layouts placed between non-empty ones. + adreno_5xx_empty_descriptor_set_layout_workaround = + physical_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM && + physical_device_properties.deviceID >= 0x5000000 && + physical_device_properties.deviceID < 0x6000000; + frame_count = p_frame_count; // Copy the queue family properties the context already retrieved. @@ -3713,6 +3721,13 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Re // Descriptor sets. if (error_text.is_empty()) { + // For Adreno 5XX driver bug. + VkDescriptorSetLayoutBinding placeholder_binding = {}; + placeholder_binding.binding = 0; + placeholder_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + placeholder_binding.descriptorCount = 1; + placeholder_binding.stageFlags = VK_SHADER_STAGE_ALL; + for (uint32_t i = 0; i < shader_refl.uniform_sets.size(); i++) { // Empty ones are fine if they were not used according to spec (binding count will be 0). VkDescriptorSetLayoutCreateInfo layout_create_info = {}; @@ -3720,6 +3735,12 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Re layout_create_info.bindingCount = vk_set_bindings[i].size(); layout_create_info.pBindings = vk_set_bindings[i].ptr(); + // ...not so fine on Adreno 5XX. + if (adreno_5xx_empty_descriptor_set_layout_workaround && layout_create_info.bindingCount == 0) { + layout_create_info.bindingCount = 1; + layout_create_info.pBindings = &placeholder_binding; + } + VkDescriptorSetLayout layout = VK_NULL_HANDLE; res = vkCreateDescriptorSetLayout(vk_device, &layout_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT), &layout); if (res) { @@ -3801,21 +3822,7 @@ void RenderingDeviceDriverVulkan::shader_destroy_modules(ShaderID p_shader) { /*********************/ /**** UNIFORM SET ****/ /*********************/ -VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it, int p_linear_pool_index) { - bool linear_pool = p_linear_pool_index >= 0; - DescriptorSetPools::Iterator pool_sets_it = linear_pool ? linear_descriptor_set_pools[p_linear_pool_index].find(p_key) : descriptor_set_pools.find(p_key); - - if (pool_sets_it) { - for (KeyValue &E : pool_sets_it->value) { - if (E.value < max_descriptor_sets_per_pool) { - *r_pool_sets_it = pool_sets_it; - return E.key; - } - } - } - - // Create a new one. - +VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_create(const DescriptorSetPoolKey &p_key, bool p_linear_pool) { // Here comes more vulkan API strangeness. VkDescriptorPoolSize *vk_sizes = ALLOCA_ARRAY(VkDescriptorPoolSize, UNIFORM_TYPE_MAX); uint32_t vk_sizes_count = 0; @@ -3889,7 +3896,7 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat VkDescriptorPoolCreateInfo descriptor_set_pool_create_info = {}; descriptor_set_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - if (linear_descriptor_pools_enabled && linear_pool) { + if (linear_descriptor_pools_enabled && p_linear_pool) { descriptor_set_pool_create_info.flags = 0; } else { descriptor_set_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; // Can't think how somebody may NOT need this flag. @@ -3904,18 +3911,6 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateDescriptorPool failed with error " + itos(res) + "."); } - // Bookkeep. - - if (!pool_sets_it) { - if (linear_pool) { - pool_sets_it = linear_descriptor_set_pools[p_linear_pool_index].insert(p_key, HashMap()); - } else { - pool_sets_it = descriptor_set_pools.insert(p_key, HashMap()); - } - } - HashMap &pool_rcs = pool_sets_it->value; - pool_rcs.insert(vk_pool, 0); - *r_pool_sets_it = pool_sets_it; return vk_pool; } @@ -3949,25 +3944,28 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewvalue[vk_pool]++; + bool linear_pool = p_linear_pool_index >= 0; + DescriptorSetPools::Iterator pool_sets_it = linear_pool ? linear_descriptor_set_pools[p_linear_pool_index].find(pool_key) : descriptor_set_pools.find(pool_key); + if (!pool_sets_it) { + if (linear_pool) { + pool_sets_it = linear_descriptor_set_pools[p_linear_pool_index].insert(pool_key, HashMap()); + } else { + pool_sets_it = descriptor_set_pools.insert(pool_key, HashMap()); + } + } VkDescriptorSetAllocateInfo descriptor_set_allocate_info = {}; descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - descriptor_set_allocate_info.descriptorPool = vk_pool; descriptor_set_allocate_info.descriptorSetCount = 1; const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id; descriptor_set_allocate_info.pSetLayouts = &shader_info->vk_descriptor_set_layouts[p_set_index]; VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE; + for (KeyValue &E : pool_sets_it->value) { + if (E.value < max_descriptor_sets_per_pool) { + descriptor_set_allocate_info.descriptorPool = E.key; + VkResult res = vkAllocateDescriptorSets(vk_device, &descriptor_set_allocate_info, &vk_descriptor_set); - VkResult res = vkAllocateDescriptorSets(vk_device, &descriptor_set_allocate_info, &vk_descriptor_set); - if (res) { - _descriptor_set_pool_unreference(pool_sets_it, vk_pool, p_linear_pool_index); - ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + "."); + // Break early on success. + if (res == VK_SUCCESS) { + break; + } + + // "Fragmented pool" and "out of memory pool" errors are handled by creating more pools. Any other error is unexpected. + if (res != VK_ERROR_FRAGMENTED_POOL && res != VK_ERROR_OUT_OF_POOL_MEMORY) { + ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + "."); + } + } + } + + // Create a new pool when no allocations could be made from the existing pools. + if (vk_descriptor_set == VK_NULL_HANDLE) { + descriptor_set_allocate_info.descriptorPool = _descriptor_set_pool_create(pool_key, linear_pool); + VkResult res = vkAllocateDescriptorSets(vk_device, &descriptor_set_allocate_info, &vk_descriptor_set); + + // All errors are unexpected at this stage. + if (res) { + vkDestroyDescriptorPool(vk_device, descriptor_set_allocate_info.descriptorPool, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL)); + ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + "."); + } } + DEV_ASSERT(descriptor_set_allocate_info.descriptorPool != VK_NULL_HANDLE && vk_descriptor_set != VK_NULL_HANDLE); + pool_sets_it->value[descriptor_set_allocate_info.descriptorPool]++; + for (uint32_t i = 0; i < writes_amount; i++) { vk_writes[i].dstSet = vk_descriptor_set; } @@ -4146,9 +4173,9 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView(resources_allocator); usi->vk_descriptor_set = vk_descriptor_set; if (p_linear_pool_index >= 0) { - usi->vk_linear_descriptor_pool = vk_pool; + usi->vk_linear_descriptor_pool = descriptor_set_allocate_info.descriptorPool; } else { - usi->vk_descriptor_pool = vk_pool; + usi->vk_descriptor_pool = descriptor_set_allocate_info.descriptorPool; } usi->pool_sets_it = pool_sets_it; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index 90868a15781d..c2638a0b77ce 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -460,7 +460,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { HashMap linear_descriptor_set_pools; bool linear_descriptor_pools_enabled = true; - VkDescriptorPool _descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it, int p_linear_pool_index); + VkDescriptorPool _descriptor_set_pool_create(const DescriptorSetPoolKey &p_key, bool p_linear_pool); void _descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool, int p_linear_pool_index); // Global flag to toggle usage of immutable sampler when creating pipeline layouts. @@ -474,6 +474,8 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { DescriptorSetPools::Iterator pool_sets_it; }; + bool adreno_5xx_empty_descriptor_set_layout_workaround = false; + public: virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index, int p_linear_pool_index) override final; virtual void linear_uniform_set_pools_reset(int p_linear_pool_index) override final; diff --git a/editor/export/editor_export_platform_apple_embedded.cpp b/editor/export/editor_export_platform_apple_embedded.cpp index 02c7f9334407..29de9267c973 100644 --- a/editor/export/editor_export_platform_apple_embedded.cpp +++ b/editor/export/editor_export_platform_apple_embedded.cpp @@ -52,7 +52,8 @@ void EditorExportPlatformAppleEmbedded::get_preset_features(const Refpush_back("etc2"); r_features->push_back("astc"); - if (p_preset->get("shader_baker/enabled")) { + if (!p_preset->is_dedicated_server() && p_preset->get("shader_baker/enabled")) { + // Don't use the shader baker if exporting as a dedicated server, as no rendering is performed. r_features->push_back("shader_baker"); } diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp index 2a2983d4337e..9ad8acce5657 100644 --- a/editor/export/editor_export_platform_pc.cpp +++ b/editor/export/editor_export_platform_pc.cpp @@ -42,7 +42,8 @@ void EditorExportPlatformPC::get_preset_features(const Ref & r_features->push_back("etc2"); r_features->push_back("astc"); } - if (p_preset->get("shader_baker/enabled")) { + if (!p_preset->is_dedicated_server() && p_preset->get("shader_baker/enabled")) { + // Don't use the shader baker if exporting as a dedicated server, as no rendering is performed. r_features->push_back("shader_baker"); } // PC platforms only have one architecture per export, since diff --git a/editor/export/shader_baker_export_plugin.cpp b/editor/export/shader_baker_export_plugin.cpp index 9dc0f067a2ce..b1f86544e71d 100644 --- a/editor/export/shader_baker_export_plugin.cpp +++ b/editor/export/shader_baker_export_plugin.cpp @@ -426,23 +426,27 @@ void ShaderBakerExportPlugin::_process_work_item(WorkItem p_work_item) { if (!tasks_cancelled) { // Only process the item if the tasks haven't been cancelled by the user yet. Vector spirv_data = ShaderRD::compile_stages(p_work_item.stage_sources); - ERR_FAIL_COND_MSG(spirv_data.is_empty(), "Unable to retrieve SPIR-V data for shader"); - - RD::ShaderReflection shader_refl; - Error err = RenderingDeviceCommons::reflect_spirv(spirv_data, shader_refl); - ERR_FAIL_COND_MSG(err != OK, "Unable to reflect SPIR-V data that was compiled"); - - Ref shader_container = shader_container_format->create_container(); - shader_container->set_from_shader_reflection(p_work_item.shader_name, shader_refl); - - // Compile shader binary from SPIR-V. - bool code_compiled = shader_container->set_code_from_spirv(spirv_data); - ERR_FAIL_COND_MSG(!code_compiled, vformat("Failed to compile code to native for SPIR-V.")); - - PackedByteArray shader_bytes = shader_container->to_bytes(); - { - MutexLock lock(shader_work_results_mutex); - shader_work_results[p_work_item.cache_path].variant_data.ptrw()[p_work_item.variant] = shader_bytes; + if (unlikely(spirv_data.is_empty())) { + ERR_PRINT("Unable to retrieve SPIR-V data for shader."); + } else { + RD::ShaderReflection shader_refl; + Error err = RenderingDeviceCommons::reflect_spirv(spirv_data, shader_refl); + ERR_FAIL_COND_MSG(err != OK, "Unable to reflect SPIR-V data that was compiled"); + + Ref shader_container = shader_container_format->create_container(); + shader_container->set_from_shader_reflection(p_work_item.shader_name, shader_refl); + + // Compile shader binary from SPIR-V. + bool code_compiled = shader_container->set_code_from_spirv(spirv_data); + if (unlikely(!code_compiled)) { + ERR_PRINT("Failed to compile code to native for SPIR-V."); + } else { + PackedByteArray shader_bytes = shader_container->to_bytes(); + { + MutexLock lock(shader_work_results_mutex); + shader_work_results[p_work_item.cache_path].variant_data.ptrw()[p_work_item.variant] = shader_bytes; + } + } } } diff --git a/editor/scene/3d/node_3d_editor_plugin.cpp b/editor/scene/3d/node_3d_editor_plugin.cpp index 7415c9125000..a4bfc291feb1 100644 --- a/editor/scene/3d/node_3d_editor_plugin.cpp +++ b/editor/scene/3d/node_3d_editor_plugin.cpp @@ -703,9 +703,9 @@ void Node3DEditorViewport::cancel_transform() { } void Node3DEditorViewport::_update_shrink() { - bool shrink = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); - subviewport_container->set_stretch_shrink(shrink ? 2 : 1); - subviewport_container->set_texture_filter(shrink ? TEXTURE_FILTER_NEAREST : TEXTURE_FILTER_PARENT_NODE); + const float scaling_3d_scale = GLOBAL_GET("rendering/scaling_3d/scale"); + const float shrink_factor = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)) ? 0.5 : 1.0; + viewport->set_scaling_3d_scale(MAX(0.25, scaling_3d_scale * shrink_factor)); } float Node3DEditorViewport::get_znear() const { @@ -729,11 +729,11 @@ Vector3 Node3DEditorViewport::_get_camera_position() const { } Point2 Node3DEditorViewport::point_to_screen(const Vector3 &p_point) { - return camera->unproject_position(p_point) * subviewport_container->get_stretch_shrink(); + return camera->unproject_position(p_point); } Vector3 Node3DEditorViewport::get_ray_pos(const Vector2 &p_pos) const { - return camera->project_ray_origin(p_pos / subviewport_container->get_stretch_shrink()); + return camera->project_ray_origin(p_pos); } Vector3 Node3DEditorViewport::_get_camera_normal() const { @@ -741,7 +741,7 @@ Vector3 Node3DEditorViewport::_get_camera_normal() const { } Vector3 Node3DEditorViewport::get_ray(const Vector2 &p_pos) const { - return camera->project_ray_normal(p_pos / subviewport_container->get_stretch_shrink()); + return camera->project_ray_normal(p_pos); } void Node3DEditorViewport::_clear_selected() { @@ -826,7 +826,7 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) { ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const { Vector3 ray = get_ray(p_pos); Vector3 pos = get_ray_pos(p_pos); - Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink(); + Vector2 shrinked_pos = p_pos; if (viewport->get_debug_draw() == Viewport::DEBUG_DRAW_SDFGI_PROBES) { RS::get_singleton()->sdfgi_set_debug_probe_select(pos, ray); @@ -2985,8 +2985,6 @@ void Node3DEditorViewport::_project_settings_changed() { viewport->set_positional_shadow_atlas_quadrant_subdiv(2, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q2)); viewport->set_positional_shadow_atlas_quadrant_subdiv(3, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q3)); - _update_shrink(); - // Update MSAA, screen-space AA and debanding if changed const int msaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/msaa_3d"); @@ -3014,8 +3012,7 @@ void Node3DEditorViewport::_project_settings_changed() { const Viewport::Scaling3DMode scaling_3d_mode = Viewport::Scaling3DMode(int(GLOBAL_GET("rendering/scaling_3d/mode"))); viewport->set_scaling_3d_mode(scaling_3d_mode); - const float scaling_3d_scale = GLOBAL_GET("rendering/scaling_3d/scale"); - viewport->set_scaling_3d_scale(scaling_3d_scale); + _update_shrink(); const float fsr_sharpness = GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"); viewport->set_fsr_sharpness(fsr_sharpness); @@ -3259,7 +3256,7 @@ void Node3DEditorViewport::_notification(int p_what) { } if (show_info) { - const String viewport_size = vformat(U"%d × %d", viewport->get_size().x, viewport->get_size().y); + const String viewport_size = vformat(U"%d × %d", viewport->get_size().x * viewport->get_scaling_3d_scale(), viewport->get_size().y * viewport->get_scaling_3d_scale()); String text; text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1)); text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1)); @@ -3268,7 +3265,7 @@ void Node3DEditorViewport::_notification(int p_what) { text += vformat( TTR("Size: %s (%.1fMP)\n"), viewport_size, - viewport->get_size().x * viewport->get_size().y * 0.000001); + viewport->get_size().x * viewport->get_size().y * Math::pow(viewport->get_scaling_3d_scale(), 2) * 0.000001); text += "\n"; text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME)); @@ -4279,8 +4276,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { const int viewport_base_height = 400 * MAX(1, EDSCALE); gizmo_scale = (gizmo_size / Math::abs(dd)) * MAX(1, EDSCALE) * - MIN(viewport_base_height, subviewport_container->get_size().height) / viewport_base_height / - subviewport_container->get_stretch_shrink(); + MIN(viewport_base_height, subviewport_container->get_size().height) / viewport_base_height; Vector3 scale = Vector3(1, 1, 1) * gizmo_scale; // if the determinant is zero, we should disable the gizmo from being rendered @@ -4512,7 +4508,7 @@ Dictionary Node3DEditorViewport::get_state() const { d["grid"] = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_GRID)); d["information"] = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_INFORMATION)); d["frame_time"] = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_FRAME_TIME)); - d["half_res"] = subviewport_container->get_stretch_shrink() > 1; + d["half_res"] = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); d["cinematic_preview"] = view_display_menu->get_popup()->is_item_checked(view_display_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW)); if (previewing) { d["previewing"] = EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing); diff --git a/editor/scene/material_editor_plugin.cpp b/editor/scene/material_editor_plugin.cpp index f4b2281e154f..6e7c81f86609 100644 --- a/editor/scene/material_editor_plugin.cpp +++ b/editor/scene/material_editor_plugin.cpp @@ -456,7 +456,6 @@ bool StandardMaterial3DConversionPlugin::handles(const Ref &p_resource Ref StandardMaterial3DConversionPlugin::convert(const Ref &p_resource) const { Ref mat = p_resource; ERR_FAIL_COND_V(mat.is_null(), Ref()); - ERR_FAIL_COND_V(!mat->_is_initialized(), Ref()); Ref smat; smat.instantiate(); @@ -503,7 +502,6 @@ bool ORMMaterial3DConversionPlugin::handles(const Ref &p_resource) con Ref ORMMaterial3DConversionPlugin::convert(const Ref &p_resource) const { Ref mat = p_resource; ERR_FAIL_COND_V(mat.is_null(), Ref()); - ERR_FAIL_COND_V(!mat->_is_initialized(), Ref()); Ref smat; smat.instantiate(); @@ -550,7 +548,6 @@ bool ParticleProcessMaterialConversionPlugin::handles(const Ref &p_res Ref ParticleProcessMaterialConversionPlugin::convert(const Ref &p_resource) const { Ref mat = p_resource; ERR_FAIL_COND_V(mat.is_null(), Ref()); - ERR_FAIL_COND_V(!mat->_is_initialized(), Ref()); Ref smat; smat.instantiate(); diff --git a/editor/shader/visual_shader_editor_plugin.cpp b/editor/shader/visual_shader_editor_plugin.cpp index 33b6088a1126..bab5d6fa611c 100644 --- a/editor/shader/visual_shader_editor_plugin.cpp +++ b/editor/shader/visual_shader_editor_plugin.cpp @@ -538,7 +538,7 @@ void VisualShaderGraphPlugin::update_frames(VisualShader::Type p_type, int p_nod void VisualShaderGraphPlugin::set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position) { if (editor->get_current_shader_type() == p_type && links.has(p_id)) { - links[p_id].graph_element->set_position_offset(p_position); + links[p_id].graph_element->set_position_offset(p_position * editor->cached_theme_base_scale); } } @@ -735,7 +735,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool expression = expression_node->get_expression(); } - node->set_position_offset(visual_shader->get_node_position(p_type, p_id)); + node->set_position_offset(visual_shader->get_node_position(p_type, p_id) * editor->cached_theme_base_scale); node->connect("dragged", callable_mp(editor, &VisualShaderEditor::_node_dragged).bind(p_id)); @@ -3840,6 +3840,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector &p_ops, cons position /= EDSCALE; } position /= graph->get_zoom(); + position /= cached_theme_base_scale; saved_node_pos_dirty = false; int id_to_use = visual_shader->get_valid_node_id(type); @@ -4166,7 +4167,7 @@ void VisualShaderEditor::_update_varyings() { void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) { VisualShader::Type type = get_current_shader_type(); - drag_buffer.push_back({ type, p_node, p_from, p_to }); + drag_buffer.push_back({ type, p_node, p_from / cached_theme_base_scale, p_to / cached_theme_base_scale }); if (!drag_dirty) { callable_mp(this, &VisualShaderEditor::_nodes_dragged).call_deferred(); } @@ -5340,6 +5341,8 @@ void VisualShaderEditor::_notification(int p_what) { tools->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); preview_tools->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); + cached_theme_base_scale = get_theme_default_base_scale(); + if (is_visible_in_tree()) { _update_graph(); } diff --git a/editor/shader/visual_shader_editor_plugin.h b/editor/shader/visual_shader_editor_plugin.h index dc3dad38b6a9..28a3589a0ac7 100644 --- a/editor/shader/visual_shader_editor_plugin.h +++ b/editor/shader/visual_shader_editor_plugin.h @@ -289,6 +289,8 @@ class VisualShaderEditor : public ShaderEditor { VBoxContainer *param_vbox = nullptr; VBoxContainer *param_vbox2 = nullptr; + float cached_theme_base_scale = 1.0f; + enum ShaderModeFlags { MODE_FLAGS_SPATIAL_CANVASITEM = 1, MODE_FLAGS_SKY = 2, diff --git a/main/main.cpp b/main/main.cpp index 62dafe881d4a..7ab3b8360387 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -633,7 +633,7 @@ void Main::print_help(const char *p_binary) { #ifdef DEBUG_ENABLED print_help_option("--gpu-abort", "Abort on graphics API usage errors (usually validation layer errors). May help see the problem if your system freezes.\n", CLI_OPTION_AVAILABILITY_TEMPLATE_DEBUG); #endif - print_help_option("--generate-spirv-debug-info", "Generate SPIR-V debug information. This allows source-level shader debugging with RenderDoc.\n"); + print_help_option("--generate-spirv-debug-info", "Generate SPIR-V debug information (Vulkan only). This allows source-level shader debugging with RenderDoc.\n"); #if defined(DEBUG_ENABLED) || defined(DEV_ENABLED) print_help_option("--extra-gpu-memory-tracking", "Enables additional memory tracking (see class reference for `RenderingDevice.get_driver_and_device_memory_report()` and linked methods). Currently only implemented for Vulkan. Enabling this feature may cause crashes on some systems due to buggy drivers or bugs in the Vulkan Loader. See https://github.com/godotengine/godot/issues/95967\n"); print_help_option("--accurate-breadcrumbs", "Force barriers between breadcrumbs. Useful for narrowing down a command causing GPU resets. Currently only implemented for Vulkan.\n"); diff --git a/misc/scripts/install_d3d12_sdk_windows.py b/misc/scripts/install_d3d12_sdk_windows.py index 41ab2bb93afd..ee5ac778006c 100755 --- a/misc/scripts/install_d3d12_sdk_windows.py +++ b/misc/scripts/install_d3d12_sdk_windows.py @@ -32,7 +32,7 @@ # Mesa NIR # Check for latest version: https://github.com/godotengine/godot-nir-static/releases/latest -mesa_version = "23.1.9-1" +mesa_version = "23.1.9-2" # WinPixEventRuntime # Check for latest version: https://www.nuget.org/api/v2/package/WinPixEventRuntime (check downloaded filename) pix_version = "1.0.240308001" diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index 764d339bac70..22ef1bb01b03 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -31,6 +31,7 @@ #include "register_types.h" #include "core/config/engine.h" +#include "core/os/os.h" #include "shader_compile.h" #include @@ -67,8 +68,16 @@ Vector compile_glslang_shader(RenderingDeviceCommons::ShaderStage p_sta shader.setPreamble(preamble.c_str()); } + bool generate_spirv_debug_info = Engine::get_singleton()->is_generate_spirv_debug_info_enabled(); +#ifdef D3D12_ENABLED + if (OS::get_singleton()->get_current_rendering_driver_name() == "d3d12") { + // SPIRV to DXIL conversion does not support debug info. + generate_spirv_debug_info = false; + } +#endif + EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); - if (Engine::get_singleton()->is_generate_spirv_debug_info_enabled()) { + if (generate_spirv_debug_info) { messages = (EShMessages)(messages | EShMsgDebugInfo); } const int DefaultVersion = 100; @@ -103,7 +112,7 @@ Vector compile_glslang_shader(RenderingDeviceCommons::ShaderStage p_sta spv::SpvBuildLogger logger; glslang::SpvOptions spvOptions; - if (Engine::get_singleton()->is_generate_spirv_debug_info_enabled()) { + if (generate_spirv_debug_info) { spvOptions.generateDebugInfo = true; spvOptions.emitNonSemanticShaderDebugInfo = true; spvOptions.emitNonSemanticShaderDebugSource = true; diff --git a/modules/openxr/extensions/openxr_visibility_mask_extension.cpp b/modules/openxr/extensions/openxr_visibility_mask_extension.cpp index 3e193d7d500d..71153f7c1d8d 100644 --- a/modules/openxr/extensions/openxr_visibility_mask_extension.cpp +++ b/modules/openxr/extensions/openxr_visibility_mask_extension.cpp @@ -100,9 +100,6 @@ void OpenXRVisibilityMaskExtension::on_session_created(const XrSession p_instanc rendering_server->material_set_shader(material, shader); rendering_server->material_set_render_priority(material, 99); - // Create our mesh. - mesh = rendering_server->mesh_create(); - // Get our initial mesh data. mesh_count = openxr_api->get_view_count(); // We need a mesh for each view. for (uint32_t i = 0; i < mesh_count; i++) { @@ -237,6 +234,16 @@ void OpenXRVisibilityMaskExtension::_update_mesh() { index_count += mesh_data[i].indices.size(); } + if (vertice_count == 0 || index_count == 0) { + // Free our mesh if we have one. + if (mesh.is_valid()) { + rendering_server->free(mesh); + mesh = RID(); + } + + return; + } + vertices.resize(vertice_count); indices.resize(index_count); uint64_t offset = 0; @@ -263,6 +270,11 @@ void OpenXRVisibilityMaskExtension::_update_mesh() { offset += mesh_data[i].vertices.size(); } + // Create our mesh if we don't have one yet. + if (mesh.is_null()) { + mesh = rendering_server->mesh_create(); + } + // Update our mesh. Array arr; arr.resize(RS::ARRAY_MAX); diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml index a6b392610bfe..5db594d09763 100644 --- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml +++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml @@ -627,6 +627,7 @@ If [code]true[/code], shaders will be compiled and embedded in the application. This option is only supported when using the Forward+ or Mobile renderers. + [b]Note:[/b] When exporting as a dedicated server, the shader baker is always disabled since no rendering is performed. If [code]true[/code], allows the application to participate in the backup and restore infrastructure. diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 4bb7263db45d..0f8173b0b72d 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1995,7 +1995,8 @@ void EditorExportPlatformAndroid::get_preset_features(const Refpush_back("etc2"); r_features->push_back("astc"); - if (p_preset->get("shader_baker/enabled")) { + if (!p_preset->is_dedicated_server() && p_preset->get("shader_baker/enabled")) { + // Don't use the shader baker if exporting as a dedicated server, as no rendering is performed. r_features->push_back("shader_baker"); } diff --git a/platform/ios/doc_classes/EditorExportPlatformIOS.xml b/platform/ios/doc_classes/EditorExportPlatformIOS.xml index e22850bc9a77..17388d1c9c9c 100644 --- a/platform/ios/doc_classes/EditorExportPlatformIOS.xml +++ b/platform/ios/doc_classes/EditorExportPlatformIOS.xml @@ -730,6 +730,7 @@ If [code]true[/code], shaders will be compiled and embedded in the application. This option is only supported when using the Forward+ or Mobile renderers. + [b]Note:[/b] When exporting as a dedicated server, the shader baker is always disabled since no rendering is performed. A custom background color of the storyboard launch screen. diff --git a/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml b/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml index 7425f49b1b60..3a7f086cb165 100644 --- a/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml +++ b/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml @@ -28,6 +28,7 @@ If [code]true[/code], shaders will be compiled and embedded in the application. This option is only supported when using the Forward+ or Mobile renderers. + [b]Note:[/b] When exporting as a dedicated server, the shader baker is always disabled since no rendering is performed. Script code to execute on the remote host when app is finished. diff --git a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml index 5b93a4a3c553..c14dc0dff8a3 100644 --- a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml +++ b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml @@ -699,6 +699,7 @@ If [code]true[/code], shaders will be compiled and embedded in the application. This option is only supported when using the Forward+ or Mobile renderers. + [b]Note:[/b] When exporting as a dedicated server, the shader baker is always disabled since no rendering is performed. Script code to execute on the remote host when app is finished. diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index 25f3926ae3ac..d6e70244ae78 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -63,7 +63,8 @@ void EditorExportPlatformMacOS::get_preset_features(const Refget("shader_baker/enabled")) { + if (!p_preset->is_dedicated_server() && p_preset->get("shader_baker/enabled")) { + // Don't use the shader baker if exporting as a dedicated server, as no rendering is performed. r_features->push_back("shader_baker"); } diff --git a/platform/visionos/doc_classes/EditorExportPlatformVisionOS.xml b/platform/visionos/doc_classes/EditorExportPlatformVisionOS.xml index 255c46e2858e..36de17b94b3b 100644 --- a/platform/visionos/doc_classes/EditorExportPlatformVisionOS.xml +++ b/platform/visionos/doc_classes/EditorExportPlatformVisionOS.xml @@ -582,6 +582,7 @@ If [code]true[/code], shaders will be compiled and embedded in the application. This option is only supported when using the Forward+ and Mobile renderers. + [b]Note:[/b] When exporting as a dedicated server, the shader baker is always disabled since no rendering is performed. If [code]true[/code], the app "Documents" folder can be accessed via "Files" app. See [url=https://developer.apple.com/documentation/bundleresources/information_property_list/lssupportsopeningdocumentsinplace]LSSupportsOpeningDocumentsInPlace[/url]. diff --git a/platform/windows/doc_classes/EditorExportPlatformWindows.xml b/platform/windows/doc_classes/EditorExportPlatformWindows.xml index 3faf75bf3931..5c263d95a2a0 100644 --- a/platform/windows/doc_classes/EditorExportPlatformWindows.xml +++ b/platform/windows/doc_classes/EditorExportPlatformWindows.xml @@ -100,6 +100,7 @@ If [code]true[/code], shaders will be compiled and embedded in the application. This option is only supported when using the Forward+ and Mobile renderers. + [b]Note:[/b] When exporting as a dedicated server, the shader baker is always disabled since no rendering is performed. Script code to execute on the remote host when app is finished. diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 12fd33ffba6b..9ff730b73b0e 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -827,7 +827,7 @@ void CPUParticles3D::_particles_process(double p_delta) { tex_anim_offset = curve_parameters[PARAM_ANGLE]->sample(tv); } - p.seed = seed + uint32_t(1) + i + cycle; + p.seed = seed + uint32_t(1) + i + cycle * pcount; rng->set_seed(p.seed); p.angle_rand = rng->randf(); p.scale_rand = rng->randf(); diff --git a/scene/3d/xr/xr_body_modifier_3d.cpp b/scene/3d/xr/xr_body_modifier_3d.cpp index ca68b5a01157..942af82c7a99 100644 --- a/scene/3d/xr/xr_body_modifier_3d.cpp +++ b/scene/3d/xr/xr_body_modifier_3d.cpp @@ -66,6 +66,10 @@ StringName XRBodyModifier3D::get_body_tracker() const { void XRBodyModifier3D::set_body_update(BitField p_body_update) { body_update = p_body_update; + + if (is_inside_tree()) { + _get_joint_data(); + } } BitField XRBodyModifier3D::get_body_update() const { diff --git a/scene/3d/xr/xr_face_modifier_3d.cpp b/scene/3d/xr/xr_face_modifier_3d.cpp index ff2b9ace858c..6b8580aaecce 100644 --- a/scene/3d/xr/xr_face_modifier_3d.cpp +++ b/scene/3d/xr/xr_face_modifier_3d.cpp @@ -504,6 +504,10 @@ void XRFaceModifier3D::_bind_methods() { void XRFaceModifier3D::set_face_tracker(const StringName &p_tracker_name) { tracker_name = p_tracker_name; + + if (is_inside_tree()) { + _get_blend_data(); + } } StringName XRFaceModifier3D::get_face_tracker() const { diff --git a/scene/3d/xr/xr_hand_modifier_3d.cpp b/scene/3d/xr/xr_hand_modifier_3d.cpp index 872e169fa14f..5b59f3a05191 100644 --- a/scene/3d/xr/xr_hand_modifier_3d.cpp +++ b/scene/3d/xr/xr_hand_modifier_3d.cpp @@ -50,6 +50,10 @@ void XRHandModifier3D::_bind_methods() { void XRHandModifier3D::set_hand_tracker(const StringName &p_tracker_name) { tracker_name = p_tracker_name; + + if (is_inside_tree()) { + _get_joint_data(); + } } StringName XRHandModifier3D::get_hand_tracker() const { diff --git a/scene/main/scene_tree_fti.cpp b/scene/main/scene_tree_fti.cpp index c7503e1610f6..7ac6266beaf7 100644 --- a/scene/main/scene_tree_fti.cpp +++ b/scene/main/scene_tree_fti.cpp @@ -286,7 +286,7 @@ void SceneTreeFTI::_create_depth_lists() { // This shouldn't happen, but wouldn't be terrible if it did. DEV_ASSERT(depth >= 0); - depth = MIN(depth, (int32_t)data.scene_tree_depth_limit); + depth = MIN(depth, (int32_t)data.scene_tree_depth_limit - 1); LocalVector &dest_list = data.dirty_node_depth_lists[depth]; #ifdef GODOT_SCENE_TREE_FTI_EXTRA_CHECKS diff --git a/scene/main/scene_tree_fti.h b/scene/main/scene_tree_fti.h index cdea9be1b8b6..9997ff8cfc01 100644 --- a/scene/main/scene_tree_fti.h +++ b/scene/main/scene_tree_fti.h @@ -77,7 +77,7 @@ class SceneTreeFTI { }; struct Data { - static const uint32_t scene_tree_depth_limit = 32; + static const uint32_t scene_tree_depth_limit = 48; // Prev / Curr lists of Node3Ds having local xforms pumped. LocalVector tick_xform_list[2]; diff --git a/scene/resources/compositor.cpp b/scene/resources/compositor.cpp index d9fdb93c5d32..40c7e7626c69 100644 --- a/scene/resources/compositor.cpp +++ b/scene/resources/compositor.cpp @@ -186,7 +186,7 @@ CompositorEffect::CompositorEffect() { RenderingServer *rs = RenderingServer::get_singleton(); if (rs != nullptr) { rid = rs->compositor_effect_create(); - rs->compositor_effect_set_callback(rid, RenderingServer::CompositorEffectCallbackType(effect_callback_type), Callable(this, "_render_callback")); + rs->compositor_effect_set_callback(rid, RenderingServer::CompositorEffectCallbackType(effect_callback_type), callable_mp(this, &CompositorEffect::_call_render_callback)); } } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index cd42fd1e0642..cb53dd61eb92 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1357,7 +1357,7 @@ void vertex() {)"; if (flags[FLAG_FIXED_SIZE]) { code += R"( // Fixed Size: Enabled - if (PROJECTION_MATRIX[3][3] != 0.0) { + if (PROJECTION_MATRIX[2][3] == 0.0) { // Orthogonal matrix; try to do about the same with viewport size. float h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1])); // Consistent with vertical FOV (Keep Height). @@ -1367,7 +1367,7 @@ void vertex() {)"; MODELVIEW_MATRIX[2] *= sc; } else { // Scale by depth. - float sc = -(MODELVIEW_MATRIX)[3].z; + float sc = length((MODELVIEW_MATRIX)[3].xyz); MODELVIEW_MATRIX[0] *= sc; MODELVIEW_MATRIX[1] *= sc; MODELVIEW_MATRIX[2] *= sc; @@ -1841,7 +1841,8 @@ void fragment() {)"; code += R"( // Proximity Fade: Enabled float proximity_depth_tex = textureLod(depth_texture, SCREEN_UV, 0.0).r; - vec4 proximity_view_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, proximity_depth_tex, 1.0); + vec4 ndc = OUTPUT_IS_SRGB ? vec4(vec3(SCREEN_UV, proximity_depth_tex) * 2.0 - 1.0, 1.0) : vec4(SCREEN_UV * 2.0 - 1.0, proximity_depth_tex, 1.0); + vec4 proximity_view_pos = INV_PROJECTION_MATRIX * ndc; proximity_view_pos.xyz /= proximity_view_pos.w; ALPHA *= clamp(1.0 - smoothstep(proximity_view_pos.z + proximity_fade_distance, proximity_view_pos.z, VERTEX.z), 0.0, 1.0); )"; diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index a660a5444519..0871c91ade58 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -69,7 +69,11 @@ class MeshStorage : public RendererMeshStorage { virtual void mesh_initialize(RID p_rid) override; virtual void mesh_free(RID p_rid) override; - virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {} + virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(m); + m->blend_shape_count = p_blend_shape_count; + } virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; } virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override { @@ -95,10 +99,23 @@ class MeshStorage : public RendererMeshStorage { m->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH); } - virtual int mesh_get_blend_shape_count(RID p_mesh) const override { return 0; } + virtual int mesh_get_blend_shape_count(RID p_mesh) const override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL_V(m, 0); + return m->blend_shape_count; + } + + virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(m); + m->blend_shape_mode = p_mode; + } - virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {} - virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { return RS::BLEND_SHAPE_MODE_NORMALIZED; } + virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL_V(m, RS::BLEND_SHAPE_MODE_NORMALIZED); + return m->blend_shape_mode; + } virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override {} virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector &p_data) override {} diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 3b91bace7e1c..42ba93c0f2e5 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -107,50 +107,57 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas } } -void RendererCanvasCull::_collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z) { +void RendererCanvasCull::_collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int &r_ysort_children_count, int p_z, uint32_t p_canvas_cull_mask) { int child_item_count = p_canvas_item->child_items.size(); RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { if (child_items[i]->visible) { - // To y-sort according to the item's final position, physics interpolation - // and transform snapping need to be applied before y-sorting. - Transform2D child_xform; - if (!_interpolation_data.interpolation_enabled || !child_items[i]->interpolated) { - child_xform = child_items[i]->xform_curr; - } else { - real_t f = Engine::get_singleton()->get_physics_interpolation_fraction(); - TransformInterpolator::interpolate_transform_2d(child_items[i]->xform_prev, child_items[i]->xform_curr, child_xform, f); - } + if (child_items[i]->visibility_layer & p_canvas_cull_mask) { + // To y-sort according to the item's final position, physics interpolation + // and transform snapping need to be applied before y-sorting. + Transform2D child_xform; + if (!_interpolation_data.interpolation_enabled || !child_items[i]->interpolated) { + child_xform = child_items[i]->xform_curr; + } else { + real_t f = Engine::get_singleton()->get_physics_interpolation_fraction(); + TransformInterpolator::interpolate_transform_2d(child_items[i]->xform_prev, child_items[i]->xform_curr, child_xform, f); + } - if (snapping_2d_transforms_to_pixel) { - child_xform.columns[2] = (child_xform.columns[2] + Point2(0.5, 0.5)).floor(); - } + if (snapping_2d_transforms_to_pixel) { + child_xform.columns[2] = (child_xform.columns[2] + Point2(0.5, 0.5)).floor(); + } - r_items[r_index] = child_items[i]; - child_items[i]->ysort_xform = p_canvas_item->ysort_xform * child_xform; - child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr; - child_items[i]->ysort_modulate = p_modulate; - child_items[i]->ysort_index = r_index; - child_items[i]->ysort_parent_abs_z_index = p_z; - - if (!child_items[i]->repeat_source) { - child_items[i]->repeat_size = p_canvas_item->repeat_size; - child_items[i]->repeat_times = p_canvas_item->repeat_times; - child_items[i]->repeat_source_item = p_canvas_item->repeat_source_item; - } + r_items[r_index] = child_items[i]; + child_items[i]->ysort_xform = p_canvas_item->ysort_xform * child_xform; + child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr; + child_items[i]->ysort_modulate = p_modulate; + child_items[i]->ysort_index = r_index; + child_items[i]->ysort_parent_abs_z_index = p_z; + + if (!child_items[i]->repeat_source) { + child_items[i]->repeat_size = p_canvas_item->repeat_size; + child_items[i]->repeat_times = p_canvas_item->repeat_times; + child_items[i]->repeat_source_item = p_canvas_item->repeat_source_item; + } - // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items. - int abs_z = 0; - if (child_items[i]->z_relative) { - abs_z = CLAMP(p_z + child_items[i]->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX); - } else { - abs_z = child_items[i]->z_index; - } + // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items. + int abs_z = 0; + if (child_items[i]->z_relative) { + abs_z = CLAMP(p_z + child_items[i]->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX); + } else { + abs_z = child_items[i]->z_index; + } - r_index++; + r_index++; - if (child_items[i]->sort_y) { - _collect_ysort_children(child_items[i], child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, abs_z); + if (child_items[i]->sort_y) { + _collect_ysort_children(child_items[i], child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, r_ysort_children_count, abs_z, p_canvas_cull_mask); + } + } else { + r_ysort_children_count--; + if (child_items[i]->sort_y) { + r_ysort_children_count -= child_items[i]->ysort_children_count; + } } } } @@ -164,7 +171,10 @@ int RendererCanvasCull::_count_ysort_children(RendererCanvasCull::Item *p_canvas if (child_items[i]->visible) { ysort_children_count++; if (child_items[i]->sort_y) { - ysort_children_count += _count_ysort_children(child_items[i]); + if (child_items[i]->ysort_children_count == -1) { + child_items[i]->ysort_children_count = _count_ysort_children(child_items[i]); + } + ysort_children_count += child_items[i]->ysort_children_count; } } } @@ -439,7 +449,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 ci->ysort_parent_abs_z_index = parent_z; child_items[0] = ci; int i = 1; - _collect_ysort_children(ci, p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z); + _collect_ysort_children(ci, p_material_owner, Color(1, 1, 1, 1), child_items, i, child_item_count, p_z, p_canvas_cull_mask); SortArray sorter; sorter.sort(child_items, child_item_count); diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 1f01bbce11a2..c83fa1fb66ee 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -207,7 +207,7 @@ class RendererCanvasCull { void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info = nullptr); void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_parent_xform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool p_is_already_y_sorted, uint32_t p_canvas_cull_mask, const Point2 &p_repeat_size, int p_repeat_times, RendererCanvasRender::Item *p_repeat_source_item); - void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z); + void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int &r_ysort_children_count, int p_z, uint32_t p_canvas_cull_mask); int _count_ysort_children(RendererCanvasCull::Item *p_canvas_item); void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner); diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index a3a873a2d175..8c6d9f0691a1 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -401,6 +401,8 @@ void CopyEffects::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panoram copy.push_constant.target[1] = 0; copy.push_constant.camera_z_far = p_lod; + copy.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0; + // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index caf0e8466ae5..aaf83b3148e2 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -138,7 +138,7 @@ class CopyEffects { int32_t section[4]; int32_t target[2]; uint32_t flags; - uint32_t pad; + float luminance_multiplier; // Glow. float glow_strength; float glow_bloom; 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 3fe0542bd4d5..9be147caa1f0 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -931,7 +931,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con float fade_alpha = 1.0; if (inst->fade_near || inst->fade_far) { - float fade_dist = inst->transform.origin.distance_to(p_render_data->scene_data->cam_transform.origin); + float fade_dist = inst->transformed_aabb.get_center().distance_to(p_render_data->scene_data->cam_transform.origin); // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. if (inst->fade_far && fade_dist > inst->fade_far_begin) { fade_alpha = Math::smoothstep(0.0f, 1.0f, 1.0f - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin)); 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 98ab09a1629b..cc78121192e3 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 @@ -290,7 +290,8 @@ class SceneShaderForwardMobile { } _FORCE_INLINE_ bool uses_shared_shadow_material() const { - return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && !uses_world_coordinates && !wireframe && !stencil_enabled; + bool backface_culling = cull_mode == RS::CULL_MODE_BACK; + return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && !uses_point_size && !uses_world_coordinates && !wireframe && !stencil_enabled && backface_culling; } virtual void set_code(const String &p_Code); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index f21815b303a9..a773672de2d1 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -335,9 +335,13 @@ void RendererSceneRenderRD::_render_buffers_ensure_screen_texture(const RenderDa if (reuse_blur_texture) { rb->allocate_blur_textures(); } else { - uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; - usage_bits |= can_use_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - rb->create_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_COLOR, rb->get_base_data_format(), usage_bits); + if (!rb->has_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_COLOR)) { + uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + usage_bits |= can_use_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + // This needs to have mipmaps if any shader needs textureLod to work on screen_texture + uint32_t mipmaps_required = Image::get_image_required_mipmaps(size.x, size.y, Image::FORMAT_RGBAH); + rb->create_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_COLOR, rb->get_base_data_format(), usage_bits, RenderingDeviceCommons::TEXTURE_SAMPLES_1, { 0, 0 }, 0U, mipmaps_required); + } } } diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl index debf6b736739..fa8e0590fc9c 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl @@ -20,7 +20,7 @@ layout(push_constant, std430) uniform Params { ivec4 section; ivec2 target; uint flags; - uint pad; + float luminance_multiplier; // Glow. float glow_strength; float glow_bloom; @@ -276,7 +276,7 @@ void main() { #else vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne #endif - imageStore(dest_buffer, pos + params.target, color); + imageStore(dest_buffer, pos + params.target, color * params.luminance_multiplier); #endif // defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) #ifdef MODE_SET_COLOR diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index d2122e0a3489..47c991292f37 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -559,7 +559,7 @@ void main() { vec4 v = vec4(view_pos, 1.0); vec4 splane = (spot_lights.data[light_index].shadow_matrix * v); - splane.z -= spot_lights.data[light_index].shadow_bias / (d * spot_lights.data[light_index].inv_radius); + splane.z -= spot_lights.data[light_index].shadow_bias; splane /= splane.w; vec3 pos = vec3(splane.xy * spot_lights.data[light_index].atlas_rect.zw + spot_lights.data[light_index].atlas_rect.xy, splane.z); diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 170aa77a430e..af1c6e7e41bb 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -529,7 +529,9 @@ void vertex_shader(vec3 vertex_input, vec2 clip_pos = clamp((gl_Position.xy / gl_Position.w) * 0.5 + 0.5, 0.0, 1.0); #endif - uvec2 cluster_pos = uvec2(clip_pos / scene_data.screen_pixel_size) >> implementation_data.cluster_shift; + uvec2 screen_size = uvec2(1.0 / scene_data.screen_pixel_size); + uvec2 screen_pixel = clamp(uvec2(clip_pos * vec2(screen_size)), uvec2(0), screen_size - uvec2(1)); + uvec2 cluster_pos = screen_pixel >> implementation_data.cluster_shift; uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32); uint cluster_z = uint(clamp((-vertex_interp.z / scene_data.z_far) * 32.0, 0.0, 31.0)); @@ -2845,6 +2847,10 @@ void fragment_shader(in SceneData scene_data) { frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); #endif //!FOG_DISABLED +#if defined(PREMUL_ALPHA_USED) && !defined(MODE_RENDER_DEPTH) + frag_color.rgb *= premul_alpha; +#endif //PREMUL_ALPHA_USED + #endif //MODE_SEPARATE_SPECULAR #endif //MODE_RENDER_DEPTH @@ -2857,10 +2863,6 @@ void fragment_shader(in SceneData scene_data) { motion_vector = prev_position_uv - position_uv; #endif - -#if defined(PREMUL_ALPHA_USED) && !defined(MODE_RENDER_DEPTH) - frag_color.rgb *= premul_alpha; -#endif //PREMUL_ALPHA_USED } void main() { diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 8f319d430aa2..39dbe5b870a6 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -432,7 +432,14 @@ AABB LightStorage::light_get_aabb(RID p_light) const { switch (light->type) { case RS::LIGHT_SPOT: { float len = light->param[RS::LIGHT_PARAM_RANGE]; - float size = Math::tan(Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len; + float angle = Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE]); + + if (angle > Math::PI * 0.5) { + // Light casts backwards as well. + return AABB(Vector3(-1, -1, -1) * len, Vector3(2, 2, 2) * len); + } + + float size = Math::sin(angle) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); }; case RS::LIGHT_OMNI: { @@ -1486,6 +1493,9 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ ERR_FAIL_NULL_V(atlas, false); + ERR_FAIL_COND_V_MSG(atlas->size < 2, false, "Attempted to render to a reflection atlas of invalid resolution."); + ERR_FAIL_COND_V_MSG(atlas->count < 1, false, "Attempted to render to a reflection atlas of size < 1."); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_NULL_V(rpi, false); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index eb7d27e4a639..2419a0195b25 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -1038,6 +1038,11 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture texture.allowed_shared_formats = format.shareable_formats; texture.has_initial_data = !data.is_empty(); + if (driver->api_trait_get(RDD::API_TRAIT_TEXTURE_OUTPUTS_REQUIRE_CLEARS)) { + // Check if a clear for this texture must be performed the first time it's used if the driver requires explicit clears after initialization. + texture.pending_clear = !texture.has_initial_data && (format.usage_bits & (TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)); + } + if ((format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT); texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT); @@ -1595,6 +1600,9 @@ Error RenderingDevice::texture_update(RID p_texture, uint32_t p_layer, const Vec ERR_FAIL_COND_V_MSG(required_size != (uint32_t)p_data.size(), ERR_INVALID_PARAMETER, "Required size for texture update (" + itos(required_size) + ") does not match data supplied size (" + itos(p_data.size()) + ")."); + // Clear the texture if the driver requires it during its first use. + _texture_check_pending_clear(p_texture, texture); + _check_transfer_worker_texture(texture); uint32_t block_w, block_h; @@ -1901,6 +1909,50 @@ uint32_t RenderingDevice::_texture_vrs_method_to_usage_bits() const { } } +void RenderingDevice::_texture_check_pending_clear(RID p_texture_rid, Texture *p_texture) { + DEV_ASSERT(p_texture != nullptr); + + if (!p_texture->pending_clear) { + return; + } + + bool clear = true; + p_texture->pending_clear = false; + + if (p_texture->owner.is_valid()) { + // Check the owner texture instead if it exists. + p_texture_rid = p_texture->owner; + p_texture = texture_owner.get_or_null(p_texture_rid); + clear = p_texture->pending_clear; + } + + if (p_texture != nullptr && clear) { + _texture_clear(p_texture_rid, p_texture, Color(), 0, p_texture->mipmaps, 0, p_texture->layers); + p_texture->pending_clear = false; + } +} + +void RenderingDevice::_texture_clear(RID p_texture_rid, Texture *p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers) { + _check_transfer_worker_texture(p_texture); + + RDD::TextureSubresourceRange range; + range.aspect = p_texture->read_aspect_flags; + range.base_mipmap = p_texture->base_mipmap + p_base_mipmap; + range.mipmap_count = p_mipmaps; + range.base_layer = p_texture->base_layer + p_base_layer; + range.layer_count = p_layers; + + // Indicate the texture will get modified for the shared texture fallback. + _texture_update_shared_fallback(p_texture_rid, p_texture, true); + + if (_texture_make_mutable(p_texture, p_texture_rid)) { + // The texture must be mutable to be used as a clear destination. + draw_graph.add_synchronization(); + } + + draw_graph.add_texture_clear(p_texture->driver_id, p_texture->draw_tracker, p_color, range); +} + Vector RenderingDevice::_texture_get_data(Texture *tex, uint32_t p_layer, bool p_2d) { uint32_t width, height, depth; uint32_t tight_mip_size = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, tex->mipmaps, &width, &height, &depth); @@ -1979,6 +2031,9 @@ Vector RenderingDevice::texture_get_data(RID p_texture, uint32_t p_laye ERR_FAIL_COND_V(p_layer >= tex->layers, Vector()); + // Clear the texture if the driver requires it during its first use. + _texture_check_pending_clear(p_texture, tex); + _check_transfer_worker_texture(tex); if (tex->usage_flags & TEXTURE_USAGE_CPU_READ_BIT) { @@ -2092,6 +2147,9 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c ERR_FAIL_COND_V_MSG(!(tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER, "Texture requires the `RenderingDevice.TEXTURE_USAGE_CAN_COPY_FROM_BIT` to be set to be retrieved."); ERR_FAIL_COND_V(p_layer >= tex->layers, ERR_INVALID_PARAMETER); + // Clear the texture if the driver requires it during its first use. + _texture_check_pending_clear(p_texture, tex); + _check_transfer_worker_texture(tex); thread_local LocalVector mip_layouts; @@ -2301,6 +2359,10 @@ Error RenderingDevice::texture_copy(RID p_from_texture, RID p_to_texture, const ERR_FAIL_COND_V_MSG(src_tex->read_aspect_flags != dst_tex->read_aspect_flags, ERR_INVALID_PARAMETER, "Source and destination texture must be of the same type (color or depth)."); + // Clear the textures if the driver requires it during its first use. + _texture_check_pending_clear(p_from_texture, src_tex); + _texture_check_pending_clear(p_to_texture, dst_tex); + _check_transfer_worker_texture(src_tex); _check_transfer_worker_texture(dst_tex); @@ -2368,6 +2430,10 @@ Error RenderingDevice::texture_resolve_multisample(RID p_from_texture, RID p_to_ // Indicate the texture will get modified for the shared texture fallback. _texture_update_shared_fallback(p_to_texture, dst_tex, true); + // Clear the textures if the driver requires it during its first use. + _texture_check_pending_clear(p_from_texture, src_tex); + _texture_check_pending_clear(p_to_texture, dst_tex); + _check_transfer_worker_texture(src_tex); _check_transfer_worker_texture(dst_tex); @@ -2427,24 +2493,10 @@ Error RenderingDevice::texture_clear(RID p_texture, const Color &p_color, uint32 ERR_FAIL_COND_V(p_base_mipmap + p_mipmaps > src_tex->mipmaps, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_base_layer + p_layers > src_tex->layers, ERR_INVALID_PARAMETER); - _check_transfer_worker_texture(src_tex); + // Clear the texture if the driver requires it during its first use. + _texture_check_pending_clear(p_texture, src_tex); - RDD::TextureSubresourceRange range; - range.aspect = src_tex->read_aspect_flags; - range.base_mipmap = src_tex->base_mipmap + p_base_mipmap; - range.mipmap_count = p_mipmaps; - range.base_layer = src_tex->base_layer + p_base_layer; - range.layer_count = p_layers; - - // Indicate the texture will get modified for the shared texture fallback. - _texture_update_shared_fallback(p_texture, src_tex, true); - - if (_texture_make_mutable(src_tex, p_texture)) { - // The texture must be mutable to be used as a clear destination. - draw_graph.add_synchronization(); - } - - draw_graph.add_texture_clear(src_tex->driver_id, src_tex->draw_tracker, p_color, range); + _texture_clear(p_texture, src_tex, p_color, p_base_mipmap, p_mipmaps, p_base_layer, p_layers); return OK; } @@ -3553,6 +3605,21 @@ void RenderingDevice::_uniform_set_update_shared(UniformSet *p_uniform_set) { } } +void RenderingDevice::_uniform_set_update_clears(UniformSet *p_uniform_set) { + if (p_uniform_set->pending_clear_textures.is_empty()) { + return; + } + + for (RID texture_id : p_uniform_set->pending_clear_textures) { + Texture *texture = texture_owner.get_or_null(texture_id); + if (texture != nullptr) { + _texture_check_pending_clear(texture_id, texture); + } + } + + p_uniform_set->pending_clear_textures.clear(); +} + RID RenderingDevice::uniform_set_create(const VectorView &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool) { _THREAD_SAFE_METHOD_ @@ -3582,6 +3649,7 @@ RID RenderingDevice::uniform_set_create(const VectorView &p_uniform Vector draw_trackers_usage; HashMap untracked_usage; Vector shared_textures_to_update; + LocalVector pending_clear_textures; for (uint32_t i = 0; i < set_uniform_count; i++) { const ShaderUniform &set_uniform = set_uniforms[i]; @@ -3652,6 +3720,10 @@ RID RenderingDevice::uniform_set_create(const VectorView &p_uniform attachable_textures.push_back(attachable_texture); } + if (texture->pending_clear) { + pending_clear_textures.push_back(texture_id); + } + RDD::TextureID driver_id = texture->driver_id; RDG::ResourceTracker *tracker = texture->draw_tracker; if (texture->shared_fallback != nullptr && texture->shared_fallback->texture.id != 0) { @@ -3698,6 +3770,10 @@ RID RenderingDevice::uniform_set_create(const VectorView &p_uniform attachable_textures.push_back(attachable_texture); } + if (texture->pending_clear) { + pending_clear_textures.push_back(texture_id); + } + RDD::TextureID driver_id = texture->driver_id; RDG::ResourceTracker *tracker = texture->draw_tracker; if (texture->shared_fallback != nullptr && texture->shared_fallback->texture.id != 0) { @@ -3742,6 +3818,10 @@ RID RenderingDevice::uniform_set_create(const VectorView &p_uniform shared_textures_to_update.push_back({ true, texture_id }); } + if (texture->pending_clear) { + pending_clear_textures.push_back(texture_id); + } + if (_texture_make_mutable(texture, texture_id)) { // The texture must be mutable as a layout transition will be required. draw_graph.add_synchronization(); @@ -3934,6 +4014,7 @@ RID RenderingDevice::uniform_set_create(const VectorView &p_uniform uniform_set.draw_trackers_usage = draw_trackers_usage; uniform_set.untracked_usage = untracked_usage; uniform_set.shared_textures_to_update = shared_textures_to_update; + uniform_set.pending_clear_textures = pending_clear_textures; uniform_set.shader_set = p_shader_set; uniform_set.shader_id = p_shader; @@ -4450,6 +4531,9 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer, continue; } + // Clear the texture if the driver requires it during its first use. + _texture_check_pending_clear(texture_rid, texture); + // Indicate the texture will get modified for the shared texture fallback. _texture_update_shared_fallback(texture_rid, texture, true); @@ -4779,12 +4863,13 @@ void RenderingDevice::draw_list_draw(DrawListID p_list, bool p_use_indices, uint if (draw_list.state.sets[i].pipeline_expected_format != draw_list.state.sets[i].uniform_set_format) { if (draw_list.state.sets[i].uniform_set_format == 0) { - ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline."); + ERR_FAIL_MSG(vformat("Uniforms were never supplied for set (%d) at the time of drawing, which are required by the pipeline.", i)); } else if (uniform_set_owner.owns(draw_list.state.sets[i].uniform_set)) { UniformSet *us = uniform_set_owner.get_or_null(draw_list.state.sets[i].uniform_set); - ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + "):\n" + _shader_uniform_debug(us->shader_id, us->shader_set) + "\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(draw_list.state.pipeline_shader)); + const String us_info = us ? vformat("(%d):\n%s\n", i, _shader_uniform_debug(us->shader_id, us->shader_set)) : vformat("(%d, which was just freed) ", i); + ERR_FAIL_MSG(vformat("Uniforms supplied for set %sare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n%s", us_info, _shader_uniform_debug(draw_list.state.pipeline_shader))); } else { - ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + ", which was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(draw_list.state.pipeline_shader)); + ERR_FAIL_MSG(vformat("Uniforms supplied for set (%d, which was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n%s", i, _shader_uniform_debug(draw_list.state.pipeline_shader))); } } } @@ -4836,7 +4921,10 @@ void RenderingDevice::draw_list_draw(DrawListID p_list, bool p_use_indices, uint } UniformSet *uniform_set = uniform_set_owner.get_or_null(draw_list.state.sets[i].uniform_set); + ERR_FAIL_NULL(uniform_set); _uniform_set_update_shared(uniform_set); + _uniform_set_update_clears(uniform_set); + draw_graph.add_draw_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); draw_list.state.sets[i].bound = true; @@ -4946,9 +5034,10 @@ void RenderingDevice::draw_list_draw_indirect(DrawListID p_list, bool p_use_indi ERR_FAIL_MSG(vformat("Uniforms were never supplied for set (%d) at the time of drawing, which are required by the pipeline.", i)); } else if (uniform_set_owner.owns(draw_list.state.sets[i].uniform_set)) { UniformSet *us = uniform_set_owner.get_or_null(draw_list.state.sets[i].uniform_set); - ERR_FAIL_MSG(vformat("Uniforms supplied for set (%d):\n%s\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n%s", i, _shader_uniform_debug(us->shader_id, us->shader_set), _shader_uniform_debug(draw_list.state.pipeline_shader))); + const String us_info = us ? vformat("(%d):\n%s\n", i, _shader_uniform_debug(us->shader_id, us->shader_set)) : vformat("(%d, which was just freed) ", i); + ERR_FAIL_MSG(vformat("Uniforms supplied for set %sare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n%s", us_info, _shader_uniform_debug(draw_list.state.pipeline_shader))); } else { - ERR_FAIL_MSG(vformat("Uniforms supplied for set (%s, which was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n%s", i, _shader_uniform_debug(draw_list.state.pipeline_shader))); + ERR_FAIL_MSG(vformat("Uniforms supplied for set (%d, which was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n%s", i, _shader_uniform_debug(draw_list.state.pipeline_shader))); } } } @@ -4976,7 +5065,9 @@ void RenderingDevice::draw_list_draw_indirect(DrawListID p_list, bool p_use_indi draw_graph.add_draw_list_bind_uniform_set(draw_list.state.pipeline_shader_driver_id, draw_list.state.sets[i].uniform_set_driver_id, i); UniformSet *uniform_set = uniform_set_owner.get_or_null(draw_list.state.sets[i].uniform_set); + ERR_FAIL_NULL(uniform_set); _uniform_set_update_shared(uniform_set); + _uniform_set_update_clears(uniform_set); draw_graph.add_draw_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); @@ -5371,6 +5462,7 @@ void RenderingDevice::compute_list_dispatch(ComputeListID p_list, uint32_t p_x_g } UniformSet *uniform_set = uniform_set_owner.get_or_null(compute_list.state.sets[i].uniform_set); _uniform_set_update_shared(uniform_set); + _uniform_set_update_clears(uniform_set); draw_graph.add_compute_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); compute_list.state.sets[i].bound = true; @@ -5507,6 +5599,7 @@ void RenderingDevice::compute_list_dispatch_indirect(ComputeListID p_list, RID p UniformSet *uniform_set = uniform_set_owner.get_or_null(compute_list.state.sets[i].uniform_set); _uniform_set_update_shared(uniform_set); + _uniform_set_update_clears(uniform_set); draw_graph.add_compute_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); compute_list.state.sets[i].bound = true; @@ -6753,16 +6846,15 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ ERR_FAIL_COND_V(!main_queue, FAILED); transfer_queue_family = driver->command_queue_family_get(RDD::COMMAND_QUEUE_FAMILY_TRANSFER_BIT); - if (transfer_queue_family) { - // Create the transfer queue. - transfer_queue = driver->command_queue_create(transfer_queue_family); - ERR_FAIL_COND_V(!transfer_queue, FAILED); - } else { - // Use main queue as the transfer queue. - transfer_queue = main_queue; + if (!transfer_queue_family) { + // Use main queue family if transfer queue family is not supported. transfer_queue_family = main_queue_family; } + // Create the transfer queue. + transfer_queue = driver->command_queue_create(transfer_queue_family); + ERR_FAIL_COND_V(!transfer_queue, FAILED); + if (present_queue_family) { // Create the present queue. present_queue = driver->command_queue_create(present_queue_family); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index b6e589e714da..0bee8d7de825 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -303,6 +303,7 @@ class RenderingDevice : public RenderingDeviceCommons { bool is_resolve_buffer = false; bool is_discardable = false; bool has_initial_data = false; + bool pending_clear = false; BitField read_aspect_flags = {}; BitField barrier_aspect_flags = {}; @@ -356,6 +357,8 @@ class RenderingDevice : public RenderingDeviceCommons { void _texture_free_shared_fallback(Texture *p_texture); void _texture_copy_shared(RID p_src_texture_rid, Texture *p_src_texture, RID p_dst_texture_rid, Texture *p_dst_texture); void _texture_create_reinterpret_buffer(Texture *p_texture); + void _texture_check_pending_clear(RID p_texture_rid, Texture *p_texture); + void _texture_clear(RID p_texture_rid, Texture *p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers); uint32_t _texture_vrs_method_to_usage_bits() const; struct TextureGetDataRequest { @@ -1091,6 +1094,7 @@ class RenderingDevice : public RenderingDeviceCommons { Vector draw_trackers_usage; HashMap untracked_usage; LocalVector shared_textures_to_update; + LocalVector pending_clear_textures; InvalidationCallback invalidated_callback = nullptr; void *invalidated_callback_userdata = nullptr; }; @@ -1098,6 +1102,7 @@ class RenderingDevice : public RenderingDeviceCommons { RID_Owner uniform_set_owner; void _uniform_set_update_shared(UniformSet *p_uniform_set); + void _uniform_set_update_clears(UniformSet *p_uniform_set); public: /** Bake a set of uniforms that can be bound at runtime with the given shader. diff --git a/servers/rendering/rendering_device_driver.cpp b/servers/rendering/rendering_device_driver.cpp index 0c26a5808a1f..abc57e441676 100644 --- a/servers/rendering/rendering_device_driver.cpp +++ b/servers/rendering/rendering_device_driver.cpp @@ -53,6 +53,8 @@ uint64_t RenderingDeviceDriver::api_trait_get(ApiTrait p_trait) { return false; case API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS: return false; + case API_TRAIT_TEXTURE_OUTPUTS_REQUIRE_CLEARS: + return false; default: ERR_FAIL_V(0); } diff --git a/servers/rendering/rendering_device_driver.h b/servers/rendering/rendering_device_driver.h index 7d7d732f0794..a41af12348d6 100644 --- a/servers/rendering/rendering_device_driver.h +++ b/servers/rendering/rendering_device_driver.h @@ -784,6 +784,7 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { API_TRAIT_CLEARS_WITH_COPY_ENGINE, API_TRAIT_USE_GENERAL_IN_COPY_QUEUES, API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS, + API_TRAIT_TEXTURE_OUTPUTS_REQUIRE_CLEARS, }; enum ShaderChangeInvalidation { diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 3c198652b23b..d78cc7b7ff28 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -263,8 +263,8 @@ class RenderingServerDefault : public RenderingServer { } RSG::material_storage->shader_initialize(shader, false); - RSG::material_storage->shader_set_code(shader, p_code); RSG::material_storage->shader_set_path_hint(shader, p_path_hint); + RSG::material_storage->shader_set_code(shader, p_code); } else { command_queue.push(RSG::material_storage, &RendererMaterialStorage::shader_initialize, shader, false); command_queue.push(RSG::material_storage, &RendererMaterialStorage::shader_set_code, shader, p_code); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 8202dff8cbe2..93655d5a45d2 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2034,7 +2034,7 @@ Dictionary RenderingServer::_mesh_get_surface(RID p_mesh, int p_idx) { Dictionary ld; ld["edge_length"] = sd.lods[i].edge_length; ld["index_data"] = sd.lods[i].index_data; - lods.push_back(lods); + lods.push_back(ld); } d["lods"] = lods; } @@ -3648,9 +3648,9 @@ void RenderingServer::init() { GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/reflections/sky_reflections/ggx_samples", PROPERTY_HINT_RANGE, "0,256,1"), 32); GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/reflections/sky_reflections/ggx_samples.mobile", PROPERTY_HINT_RANGE, "0,128,1"), 16); GLOBAL_DEF("rendering/reflections/sky_reflections/fast_filter_high_quality", false); - GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/reflections/reflection_atlas/reflection_size", PROPERTY_HINT_RANGE, "0,4096,1"), 256); - GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/reflections/reflection_atlas/reflection_size.mobile", PROPERTY_HINT_RANGE, "0,2048,1"), 128); - GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/reflections/reflection_atlas/reflection_count", PROPERTY_HINT_RANGE, "0,256,1"), 64); + GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/reflections/reflection_atlas/reflection_size", PROPERTY_HINT_RANGE, "4,4096,1"), 256); + GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/reflections/reflection_atlas/reflection_size.mobile", PROPERTY_HINT_RANGE, "4,2048,1"), 128); + GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/reflections/reflection_atlas/reflection_count", PROPERTY_HINT_RANGE, "1,256,1"), 64); GLOBAL_DEF_RST("rendering/reflections/specular_occlusion/enabled", true); GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false);