diff options
6 files changed, 173 insertions, 156 deletions
| diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 7e1b4788e2..5bf3bbf8a4 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -5808,7 +5808,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma  	tessellation_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;  	tessellation_create_info.pNext = nullptr;  	tessellation_create_info.flags = 0; -	ERR_FAIL_COND_V(p_rasterization_state.patch_control_points < 1 || p_rasterization_state.patch_control_points > limits.maxTessellationPatchSize, RID()); +	ERR_FAIL_COND_V(limits.maxTessellationPatchSize > 0 && (p_rasterization_state.patch_control_points < 1 || p_rasterization_state.patch_control_points > limits.maxTessellationPatchSize), RID());  	tessellation_create_info.patchControlPoints = p_rasterization_state.patch_control_points;  	VkPipelineViewportStateCreateInfo viewport_state_create_info; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 03419ec8f5..4985fd1687 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -35,6 +35,34 @@  using namespace RendererSceneRenderImplementation; +RenderForwardMobile::ForwardID RenderForwardMobile::_allocate_forward_id(ForwardIDType p_type) { +	int32_t index = -1; +	for (uint32_t i = 0; i < forward_id_allocators[p_type].allocations.size(); i++) { +		if (forward_id_allocators[p_type].allocations[i] == false) { +			index = i; +			break; +		} +	} + +	if (index == -1) { +		index = forward_id_allocators[p_type].allocations.size(); +		forward_id_allocators[p_type].allocations.push_back(true); +		forward_id_allocators[p_type].map.push_back(0xFF); +	} else { +		forward_id_allocators[p_type].allocations[index] = true; +	} + +	return index; +} +void RenderForwardMobile::_free_forward_id(ForwardIDType p_type, ForwardID p_id) { +	ERR_FAIL_INDEX(p_id, (ForwardID)forward_id_allocators[p_type].allocations.size()); +	forward_id_allocators[p_type].allocations[p_id] = false; +} + +void RenderForwardMobile::_map_forward_id(ForwardIDType p_type, ForwardID p_id, uint32_t p_index) { +	forward_id_allocators[p_type].map[p_id] = p_index; +} +  /* Render buffer */  void RenderForwardMobile::RenderBufferDataForwardMobile::clear() { @@ -68,7 +96,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b  	RD::DataFormat color_format = RenderForwardMobile::singleton->_render_buffers_get_color_format();  	if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) { -		if (color_format == RD::DATA_FORMAT_B10G11R11_UFLOAT_PACK32) { +		if (color_format == RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32) {  			// @TODO add a second color buffer for alpha as this format is RGB only  		} @@ -139,7 +167,14 @@ RD::DataFormat RenderForwardMobile::_render_buffers_get_color_format() {  	// Using 32bit buffers enables AFBC on mobile devices which should have a definate performance improvement (MALI G710 and newer support this on 64bit RTs)  	// NO ALPHA and unsigned float.  	// @TODO No alpha is an issue, recommendation here is to add a second RT for alpha -	return RD::DATA_FORMAT_B10G11R11_UFLOAT_PACK32; +	return RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; +} + +bool RenderForwardMobile::_render_buffers_can_be_storage() { +	// Using 32bit buffers enables AFBC on mobile devices which should have a definate performance improvement (MALI G710 and newer support this on 64bit RTs) +	// NO ALPHA and unsigned float. +	// @TODO No alpha is an issue, recommendation here is to add a second RT for alpha +	return false;  }  RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) { @@ -1403,6 +1438,44 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para  	}  } +void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, const GeometryInstanceForwardMobile *p_instance) { +	// first zero out our indices + +	p_push_constant->omni_lights[0] = 0xFFFF; +	p_push_constant->omni_lights[1] = 0xFFFF; + +	p_push_constant->spot_lights[0] = 0xFFFF; +	p_push_constant->spot_lights[1] = 0xFFFF; + +	p_push_constant->decals[0] = 0xFFFF; +	p_push_constant->decals[1] = 0xFFFF; + +	p_push_constant->reflection_probes[0] = 0xFFFF; +	p_push_constant->reflection_probes[1] = 0xFFFF; + +	for (uint32_t i = 0; i < MAX_RDL_CULL; i++) { +		uint32_t ofs = i < 4 ? 0 : 1; +		uint32_t shift = (i & 0x3) << 3; +		uint32_t mask = ~(0xFF << shift); +		if (i < p_instance->omni_light_count) { +			p_push_constant->omni_lights[ofs] &= mask; +			p_push_constant->omni_lights[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift; +		} +		if (i < p_instance->spot_light_count) { +			p_push_constant->spot_lights[ofs] &= mask; +			p_push_constant->spot_lights[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift; +		} +		if (i < p_instance->decals_count) { +			p_push_constant->decals[ofs] &= mask; +			p_push_constant->decals[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift; +		} +		if (i < p_instance->reflection_probe_count) { +			p_push_constant->reflection_probes[ofs] &= mask; +			p_push_constant->reflection_probes[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift; +		} +	} +} +  template <RenderForwardMobile::PassMode p_pass_mode>  void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {  	RD::DrawListID draw_list = p_draw_list; @@ -1452,8 +1525,6 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr  			push_constant.lightmap_uv_scale[3] = inst->lightmap_uv_scale.size.y;  		}; -		_fill_instance_indices(inst->omni_lights, inst->omni_light_count, push_constant.omni_lights, inst->spot_lights, inst->spot_light_count, push_constant.spot_lights, inst->reflection_probes, inst->reflection_probe_count, push_constant.reflection_probes, inst->decals, inst->decals_count, push_constant.decals, push_constant.layer_mask); -  		RID material_uniform_set;  		SceneShaderForwardMobile::ShaderData *shader;  		void *mesh_surface; @@ -1464,6 +1535,8 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr  			mesh_surface = surf->surface_shadow;  		} else { +			_fill_push_constant_instance_indices(&push_constant, inst); +  #ifdef DEBUG_ENABLED  			if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {  				material_uniform_set = scene_shader.default_material_uniform_set; @@ -1772,13 +1845,13 @@ void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstanc  		switch (type) {  			case RS::LIGHT_OMNI: {  				if (ginstance->omni_light_count < (uint32_t)MAX_RDL_CULL) { -					ginstance->omni_lights[ginstance->omni_light_count] = p_light_instances[i]; +					ginstance->omni_lights[ginstance->omni_light_count] = light_instance_get_forward_id(p_light_instances[i]);  					ginstance->omni_light_count++;  				}  			} break;  			case RS::LIGHT_SPOT: {  				if (ginstance->spot_light_count < (uint32_t)MAX_RDL_CULL) { -					ginstance->spot_lights[ginstance->spot_light_count] = p_light_instances[i]; +					ginstance->spot_lights[ginstance->spot_light_count] = light_instance_get_forward_id(p_light_instances[i]);  					ginstance->spot_light_count++;  				}  			} break; @@ -1794,7 +1867,7 @@ void RenderForwardMobile::geometry_instance_pair_reflection_probe_instances(Geom  	ginstance->reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL;  	for (uint32_t i = 0; i < ginstance->reflection_probe_count; i++) { -		ginstance->reflection_probes[i] = p_reflection_probe_instances[i]; +		ginstance->reflection_probes[i] = reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]);  	}  } @@ -1804,7 +1877,7 @@ void RenderForwardMobile::geometry_instance_pair_decal_instances(GeometryInstanc  	ginstance->decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL;  	for (uint32_t i = 0; i < ginstance->decals_count; i++) { -		ginstance->decals[i] = p_decal_instances[i]; +		ginstance->decals[i] = decal_instance_get_forward_id(p_decal_instances[i]);  	}  } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index bf3aa7ed5c..5d28cdb5d3 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -42,6 +42,18 @@ namespace RendererSceneRenderImplementation {  class RenderForwardMobile : public RendererSceneRenderRD {  	friend SceneShaderForwardMobile; +	struct ForwardIDAllocator { +		LocalVector<bool> allocations; +		LocalVector<uint8_t> map; +	}; + +	ForwardIDAllocator forward_id_allocators[FORWARD_ID_MAX]; + +	virtual ForwardID _allocate_forward_id(ForwardIDType p_type) override; +	virtual void _free_forward_id(ForwardIDType p_type, ForwardID p_id) override; +	virtual void _map_forward_id(ForwardIDType p_type, ForwardID p_id, uint32_t p_index) override; +	virtual bool _uses_forward_ids() const override { return true; } +  protected:  	/* Scene Shader */ @@ -152,6 +164,7 @@ protected:  	};  	virtual RD::DataFormat _render_buffers_get_color_format() override; +	virtual bool _render_buffers_can_be_storage() override;  	RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0);  	virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; @@ -515,14 +528,14 @@ protected:  		GeometryInstanceLightmapSH *lightmap_sh = nullptr;  		// culled light info -		uint32_t reflection_probe_count; -		RID reflection_probes[MAX_RDL_CULL]; -		uint32_t omni_light_count; -		RID omni_lights[MAX_RDL_CULL]; -		uint32_t spot_light_count; -		RID spot_lights[MAX_RDL_CULL]; -		uint32_t decals_count; -		RID decals[MAX_RDL_CULL]; +		uint32_t reflection_probe_count = 0; +		ForwardID reflection_probes[MAX_RDL_CULL]; +		uint32_t omni_light_count = 0; +		ForwardID omni_lights[MAX_RDL_CULL]; +		uint32_t spot_light_count = 0; +		ForwardID spot_lights[MAX_RDL_CULL]; +		uint32_t decals_count = 0; +		ForwardID decals[MAX_RDL_CULL];  		GeometryInstanceSurfaceDataCache *surface_caches = nullptr; @@ -554,6 +567,8 @@ protected:  				dirty_list_element(this) {}  	}; +	_FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, const GeometryInstanceForwardMobile *p_instance); +  public:  	static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);  	static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 9b32971e30..7b5f448c18 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -567,6 +567,8 @@ int RendererSceneRenderRD::reflection_atlas_get_size(RID p_ref_atlas) const {  RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) {  	ReflectionProbeInstance rpi;  	rpi.probe = p_probe; +	rpi.forward_id = _allocate_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE); +  	return reflection_probe_instance_owner.make_rid(rpi);  } @@ -659,7 +661,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc  			tf.mipmaps = mipmaps;  			tf.width = atlas->size;  			tf.height = atlas->size; -			tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; +			tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | (_render_buffers_can_be_storage() ? RD::TEXTURE_USAGE_STORAGE_BIT : 0);  			atlas->reflection = RD::get_singleton()->texture_create(tf, RD::TextureView());  		} @@ -1233,6 +1235,9 @@ RID RendererSceneRenderRD::light_instance_create(RID p_light) {  	light_instance->self = li;  	light_instance->light = p_light;  	light_instance->light_type = storage->light_get_type(p_light); +	if (light_instance->light_type != RS::LIGHT_DIRECTIONAL) { +		light_instance->forward_id = _allocate_forward_id(light_instance->light_type == RS::LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT); +	}  	return li;  } @@ -1306,6 +1311,7 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap  RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {  	DecalInstance di;  	di.decal = p_decal; +	di.forward_id = _allocate_forward_id(FORWARD_ID_TYPE_DECAL);  	return decal_instance_owner.make_rid(di);  } @@ -2122,6 +2128,10 @@ RD::DataFormat RendererSceneRenderRD::_render_buffers_get_color_format() {  	return RD::DATA_FORMAT_R16G16B16A16_SFLOAT;  } +bool RendererSceneRenderRD::_render_buffers_can_be_storage() { +	return true; +} +  void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) {  	ERR_FAIL_COND_MSG(p_view_count == 0, "Must have atleast 1 view"); @@ -2152,9 +2162,9 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p  		tf.width = rb->width;  		tf.height = rb->height;  		tf.array_layers = rb->view_count; // create a layer for every view -		tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; +		tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | (_render_buffers_can_be_storage() ? RD::TEXTURE_USAGE_STORAGE_BIT : 0);  		if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { -			tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; +			tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | (_render_buffers_can_be_storage() ? RD::TEXTURE_USAGE_STORAGE_BIT : 0);  		} else {  			tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;  		} @@ -2328,10 +2338,13 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti  		sort_array.sort(cluster.reflection_sort, cluster.reflection_count);  	} +	bool using_forward_ids = _uses_forward_ids();  	for (uint32_t i = 0; i < cluster.reflection_count; i++) {  		ReflectionProbeInstance *rpi = cluster.reflection_sort[i].instance; -		rpi->render_index = i; +		if (using_forward_ids) { +			_map_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id, i); +		}  		RID base_probe = rpi->probe; @@ -2628,6 +2641,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const  		shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);  	} +	bool using_forward_ids = _uses_forward_ids(); +  	for (uint32_t i = 0; i < (cluster.omni_light_count + cluster.spot_light_count); i++) {  		uint32_t index = (i < cluster.omni_light_count) ? i : i - (cluster.omni_light_count);  		Cluster::LightData &light_data = (i < cluster.omni_light_count) ? cluster.omni_lights[index] : cluster.spot_lights[index]; @@ -2635,6 +2650,10 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const  		LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance;  		RID base = li->light; +		if (using_forward_ids) { +			_map_forward_id(type == RS::LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT, li->forward_id, index); +		} +  		Transform3D light_transform = li->transform;  		float sign = storage->light_is_negative(base) ? -1 : 1; @@ -2767,7 +2786,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const  			light_data.shadow_enabled = false;  		} -		li->light_index = index;  		li->cull_mask = storage->light_get_cull_mask(base);  		if (current_cluster_builder != nullptr) { @@ -2836,11 +2854,15 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const  		sort_array.sort(cluster.decal_sort, cluster.decal_count);  	} +	bool using_forward_ids = _uses_forward_ids();  	for (uint32_t i = 0; i < cluster.decal_count; i++) {  		DecalInstance *di = cluster.decal_sort[i].instance;  		RID decal = di->decal; -		di->render_index = i; +		if (using_forward_ids) { +			_map_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id, i); +		} +  		di->cull_mask = storage->decal_get_cull_mask(decal);  		Transform3D xform = di->transform; @@ -2957,116 +2979,6 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const  	}  } -void RendererSceneRenderRD::_fill_instance_indices(const RID *p_omni_light_instances, uint32_t p_omni_light_instance_count, uint32_t *p_omni_light_indices, const RID *p_spot_light_instances, uint32_t p_spot_light_instance_count, uint32_t *p_spot_light_indices, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count, uint32_t *p_reflection_probe_indices, const RID *p_decal_instances, uint32_t p_decal_instance_count, uint32_t *p_decal_instance_indices, uint32_t p_layer_mask, uint32_t p_max_dst_words) { -	// first zero out our indices -	for (uint32_t i = 0; i < p_max_dst_words; i++) { -		p_omni_light_indices[i] = 0; -		p_spot_light_indices[i] = 0; -		p_reflection_probe_indices[i] = 0; -		p_decal_instance_indices[i] = 0; -	} - -	{ -		// process omni lights -		uint32_t dword = 0; -		uint32_t shift = 0; - -		for (uint32_t i = 0; i < p_omni_light_instance_count && dword < p_max_dst_words; i++) { -			LightInstance *li = light_instance_owner.getornull(p_omni_light_instances[i]); - -			if ((li->cull_mask & p_layer_mask) && (li->light_index < 255)) { -				p_omni_light_indices[dword] += li->light_index << shift; -				if (shift == 24) { -					dword++; -					shift = 0; -				} else { -					shift += 8; -				} -			} -		} - -		if (dword < 2) { -			// put in ending mark -			p_omni_light_indices[dword] += 0xFF << shift; -		} -	} - -	{ -		// process spot lights -		uint32_t dword = 0; -		uint32_t shift = 0; - -		for (uint32_t i = 0; i < p_spot_light_instance_count && dword < p_max_dst_words; i++) { -			LightInstance *li = light_instance_owner.getornull(p_spot_light_instances[i]); - -			if ((li->cull_mask & p_layer_mask) && (li->light_index < 255)) { -				p_spot_light_indices[dword] += li->light_index << shift; -				if (shift == 24) { -					dword++; -					shift = 0; -				} else { -					shift += 8; -				} -			} -		} - -		if (dword < 2) { -			// put in ending mark -			p_spot_light_indices[dword] += 0xFF << shift; -		} -	} - -	{ -		// process reflection probes -		uint32_t dword = 0; -		uint32_t shift = 0; - -		for (uint32_t i = 0; i < p_reflection_probe_instance_count && dword < p_max_dst_words; i++) { -			ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflection_probe_instances[i]); - -			if ((rpi->cull_mask & p_layer_mask) && (rpi->render_index < 255)) { -				p_reflection_probe_indices[dword] += rpi->render_index << shift; -				if (shift == 24) { -					dword++; -					shift = 0; -				} else { -					shift += 8; -				} -			} -		} - -		if (dword < 2) { -			// put in ending mark -			p_reflection_probe_indices[dword] += 0xFF << shift; -		} -	} - -	{ -		// process decals -		uint32_t dword = 0; -		uint32_t shift = 0; - -		for (uint32_t i = 0; i < p_decal_instance_count && dword < p_max_dst_words; i++) { -			DecalInstance *decal = decal_instance_owner.getornull(p_decal_instances[i]); - -			if ((decal->cull_mask & p_layer_mask) && (decal->render_index < 255)) { -				p_decal_instance_indices[dword] += decal->render_index << shift; -				if (shift == 24) { -					dword++; -					shift = 0; -				} else { -					shift += 8; -				} -			} -		} - -		if (dword < 2) { -			// put in ending mark -			p_decal_instance_indices[dword] += 0xFF << shift; -		} -	} -} -  void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {  	ERR_FAIL_COND(!rb->volumetric_fog); @@ -4042,11 +3954,13 @@ bool RendererSceneRenderRD::free(RID p_rid) {  		}  		reflection_atlas_owner.free(p_rid);  	} else if (reflection_probe_instance_owner.owns(p_rid)) { -		//not much to delete, just free it -		//ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid); +		ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid); +		_free_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id);  		reflection_probe_release_atlas_index(p_rid);  		reflection_probe_instance_owner.free(p_rid);  	} else if (decal_instance_owner.owns(p_rid)) { +		DecalInstance *di = decal_instance_owner.getornull(p_rid); +		_free_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id);  		decal_instance_owner.free(p_rid);  	} else if (lightmap_instance_owner.owns(p_rid)) {  		lightmap_instance_owner.free(p_rid); @@ -4081,6 +3995,9 @@ bool RendererSceneRenderRD::free(RID p_rid) {  			shadow_atlas->shadow_owners.erase(p_rid);  		} +		if (light_instance->light_type != RS::LIGHT_DIRECTIONAL) { +			_free_forward_id(light_instance->light_type == RS::LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT, light_instance->forward_id); +		}  		light_instance_owner.free(p_rid);  	} else if (shadow_atlas_owner.owns(p_rid)) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 58d9a765d0..cd2056d390 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -148,6 +148,23 @@ protected:  		}  	} +	//used for mobile renderer mostly + +	typedef int32_t ForwardID; + +	enum ForwardIDType { +		FORWARD_ID_TYPE_OMNI_LIGHT, +		FORWARD_ID_TYPE_SPOT_LIGHT, +		FORWARD_ID_TYPE_REFLECTION_PROBE, +		FORWARD_ID_TYPE_DECAL, +		FORWARD_ID_MAX, +	}; + +	virtual ForwardID _allocate_forward_id(ForwardIDType p_type) { return -1; } +	virtual void _free_forward_id(ForwardIDType p_type, ForwardID p_id) {} +	virtual void _map_forward_id(ForwardIDType p_type, ForwardID p_id, uint32_t p_index) {} +	virtual bool _uses_forward_ids() const { return false; } +  private:  	RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;  	static RendererSceneRenderRD *singleton; @@ -189,9 +206,10 @@ private:  		uint32_t render_step = 0;  		uint64_t last_pass = 0; -		uint32_t render_index = 0;  		uint32_t cull_mask = 0; +		ForwardID forward_id = -1; +  		Transform3D transform;  	}; @@ -202,8 +220,8 @@ private:  	struct DecalInstance {  		RID decal;  		Transform3D transform; -		uint32_t render_index;  		uint32_t cull_mask; +		ForwardID forward_id = -1;  	};  	mutable RID_Owner<DecalInstance> decal_instance_owner; @@ -347,7 +365,6 @@ private:  		uint64_t last_scene_pass = 0;  		uint64_t last_scene_shadow_pass = 0;  		uint64_t last_pass = 0; -		uint32_t light_index = 0;  		uint32_t cull_mask = 0;  		uint32_t light_directional_index = 0; @@ -359,6 +376,8 @@ private:  		Set<RID> shadow_atlases; //shadow atlases where this light is registered +		ForwardID forward_id = -1; +  		LightInstance() {}  	}; @@ -1006,14 +1025,9 @@ public:  		return li->last_pass;  	} -	_FORCE_INLINE_ void light_instance_set_index(RID p_light_instance, uint32_t p_index) { -		LightInstance *li = light_instance_owner.getornull(p_light_instance); -		li->light_index = p_index; -	} - -	_FORCE_INLINE_ uint32_t light_instance_get_index(RID p_light_instance) { +	_FORCE_INLINE_ ForwardID light_instance_get_forward_id(RID p_light_instance) {  		LightInstance *li = light_instance_owner.getornull(p_light_instance); -		return li->light_index; +		return li->forward_id;  	}  	_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) { @@ -1050,17 +1064,11 @@ public:  		return rpi->probe;  	} -	_FORCE_INLINE_ void reflection_probe_instance_set_render_index(RID p_instance, uint32_t p_render_index) { -		ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); -		ERR_FAIL_COND(!rpi); -		rpi->render_index = p_render_index; -	} - -	_FORCE_INLINE_ uint32_t reflection_probe_instance_get_render_index(RID p_instance) { +	_FORCE_INLINE_ ForwardID reflection_probe_instance_get_forward_id(RID p_instance) {  		ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);  		ERR_FAIL_COND_V(!rpi, 0); -		return rpi->render_index; +		return rpi->forward_id;  	}  	_FORCE_INLINE_ void reflection_probe_instance_set_render_pass(RID p_instance, uint32_t p_render_pass) { @@ -1098,6 +1106,11 @@ public:  		return decal->decal;  	} +	_FORCE_INLINE_ ForwardID decal_instance_get_forward_id(RID p_decal) const { +		DecalInstance *decal = decal_instance_owner.getornull(p_decal); +		return decal->forward_id; +	} +  	_FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal) const {  		DecalInstance *decal = decal_instance_owner.getornull(p_decal);  		return decal->transform; @@ -1118,8 +1131,6 @@ public:  		return li->transform;  	} -	void _fill_instance_indices(const RID *p_omni_light_instances, uint32_t p_omni_light_instance_count, uint32_t *p_omni_light_indices, const RID *p_spot_light_instances, uint32_t p_spot_light_instance_count, uint32_t *p_spot_light_indices, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count, uint32_t *p_reflection_probe_indices, const RID *p_decal_instances, uint32_t p_decal_instance_count, uint32_t *p_decal_instance_indices, uint32_t p_layer_mask, uint32_t p_max_dst_words = 2); -  	/* gi light probes */  	virtual RID voxel_gi_instance_create(RID p_base) override; @@ -1131,6 +1142,7 @@ public:  	/* render buffers */  	virtual RD::DataFormat _render_buffers_get_color_format(); +	virtual bool _render_buffers_can_be_storage();  	virtual RID render_buffers_create() override;  	virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) override;  	virtual void gi_set_use_half_resolution(bool p_enable) override; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 30673745ca..c28493d9e3 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -1291,7 +1291,7 @@ void main() {  			blur_shadow(shadow); -			light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, +			light_compute(normal, directional_lights.data[i].direction, normalize(view), 0.0, directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,  #ifdef LIGHT_BACKLIGHT_USED  					backlight,  #endif |