Fixes to forward mobile

* use valid format for framebuffer: VK_FORMAT_A2B10G10R10_UNORM_PACK32
* Unfortunately cant be used for compute.
* Mobile will need to do refprobe, sky, mipmapblurring using raster.
This commit is contained in:
reduz 2021-07-15 17:06:33 -03:00
parent 60add98a4c
commit 76e25438c9
6 changed files with 173 additions and 156 deletions

View File

@ -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.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
tessellation_create_info.pNext = nullptr; tessellation_create_info.pNext = nullptr;
tessellation_create_info.flags = 0; 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; tessellation_create_info.patchControlPoints = p_rasterization_state.patch_control_points;
VkPipelineViewportStateCreateInfo viewport_state_create_info; VkPipelineViewportStateCreateInfo viewport_state_create_info;

View File

@ -35,6 +35,34 @@
using namespace RendererSceneRenderImplementation; 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 */ /* Render buffer */
void RenderForwardMobile::RenderBufferDataForwardMobile::clear() { 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(); RD::DataFormat color_format = RenderForwardMobile::singleton->_render_buffers_get_color_format();
if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) { 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 // @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) // 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. // NO ALPHA and unsigned float.
// @TODO No alpha is an issue, recommendation here is to add a second RT for alpha // @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) { 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> 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) { 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; 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; 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; RID material_uniform_set;
SceneShaderForwardMobile::ShaderData *shader; SceneShaderForwardMobile::ShaderData *shader;
void *mesh_surface; void *mesh_surface;
@ -1464,6 +1535,8 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
mesh_surface = surf->surface_shadow; mesh_surface = surf->surface_shadow;
} else { } else {
_fill_push_constant_instance_indices(&push_constant, inst);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) { if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
material_uniform_set = scene_shader.default_material_uniform_set; material_uniform_set = scene_shader.default_material_uniform_set;
@ -1772,13 +1845,13 @@ void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstanc
switch (type) { switch (type) {
case RS::LIGHT_OMNI: { case RS::LIGHT_OMNI: {
if (ginstance->omni_light_count < (uint32_t)MAX_RDL_CULL) { 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++; ginstance->omni_light_count++;
} }
} break; } break;
case RS::LIGHT_SPOT: { case RS::LIGHT_SPOT: {
if (ginstance->spot_light_count < (uint32_t)MAX_RDL_CULL) { 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++; ginstance->spot_light_count++;
} }
} break; } 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; 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++) { 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; 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++) { 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]);
} }
} }

View File

@ -42,6 +42,18 @@ namespace RendererSceneRenderImplementation {
class RenderForwardMobile : public RendererSceneRenderRD { class RenderForwardMobile : public RendererSceneRenderRD {
friend SceneShaderForwardMobile; 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: protected:
/* Scene Shader */ /* Scene Shader */
@ -152,6 +164,7 @@ protected:
}; };
virtual RD::DataFormat _render_buffers_get_color_format() override; 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); 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; virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
@ -515,14 +528,14 @@ protected:
GeometryInstanceLightmapSH *lightmap_sh = nullptr; GeometryInstanceLightmapSH *lightmap_sh = nullptr;
// culled light info // culled light info
uint32_t reflection_probe_count; uint32_t reflection_probe_count = 0;
RID reflection_probes[MAX_RDL_CULL]; ForwardID reflection_probes[MAX_RDL_CULL];
uint32_t omni_light_count; uint32_t omni_light_count = 0;
RID omni_lights[MAX_RDL_CULL]; ForwardID omni_lights[MAX_RDL_CULL];
uint32_t spot_light_count; uint32_t spot_light_count = 0;
RID spot_lights[MAX_RDL_CULL]; ForwardID spot_lights[MAX_RDL_CULL];
uint32_t decals_count; uint32_t decals_count = 0;
RID decals[MAX_RDL_CULL]; ForwardID decals[MAX_RDL_CULL];
GeometryInstanceSurfaceDataCache *surface_caches = nullptr; GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
@ -554,6 +567,8 @@ protected:
dirty_list_element(this) {} dirty_list_element(this) {}
}; };
_FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, const GeometryInstanceForwardMobile *p_instance);
public: public:
static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker); static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker); static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);

View File

@ -567,6 +567,8 @@ int RendererSceneRenderRD::reflection_atlas_get_size(RID p_ref_atlas) const {
RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) { RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) {
ReflectionProbeInstance rpi; ReflectionProbeInstance rpi;
rpi.probe = p_probe; rpi.probe = p_probe;
rpi.forward_id = _allocate_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE);
return reflection_probe_instance_owner.make_rid(rpi); 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.mipmaps = mipmaps;
tf.width = atlas->size; tf.width = atlas->size;
tf.height = 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()); 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->self = li;
light_instance->light = p_light; light_instance->light = p_light;
light_instance->light_type = storage->light_get_type(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; return li;
} }
@ -1306,6 +1311,7 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap
RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
DecalInstance di; DecalInstance di;
di.decal = p_decal; di.decal = p_decal;
di.forward_id = _allocate_forward_id(FORWARD_ID_TYPE_DECAL);
return decal_instance_owner.make_rid(di); 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; 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) { 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"); 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.width = rb->width;
tf.height = rb->height; tf.height = rb->height;
tf.array_layers = rb->view_count; // create a layer for every view 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) { 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 { } else {
tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; 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); 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++) { for (uint32_t i = 0; i < cluster.reflection_count; i++) {
ReflectionProbeInstance *rpi = cluster.reflection_sort[i].instance; 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; 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); 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++) { 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); 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]; 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; LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance;
RID base = li->light; 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; Transform3D light_transform = li->transform;
float sign = storage->light_is_negative(base) ? -1 : 1; 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; light_data.shadow_enabled = false;
} }
li->light_index = index;
li->cull_mask = storage->light_get_cull_mask(base); li->cull_mask = storage->light_get_cull_mask(base);
if (current_cluster_builder != nullptr) { 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); 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++) { for (uint32_t i = 0; i < cluster.decal_count; i++) {
DecalInstance *di = cluster.decal_sort[i].instance; DecalInstance *di = cluster.decal_sort[i].instance;
RID decal = di->decal; 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); di->cull_mask = storage->decal_get_cull_mask(decal);
Transform3D xform = di->transform; 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) { void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->volumetric_fog); ERR_FAIL_COND(!rb->volumetric_fog);
@ -4042,11 +3954,13 @@ bool RendererSceneRenderRD::free(RID p_rid) {
} }
reflection_atlas_owner.free(p_rid); reflection_atlas_owner.free(p_rid);
} else if (reflection_probe_instance_owner.owns(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_release_atlas_index(p_rid);
reflection_probe_instance_owner.free(p_rid); reflection_probe_instance_owner.free(p_rid);
} else if (decal_instance_owner.owns(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); decal_instance_owner.free(p_rid);
} else if (lightmap_instance_owner.owns(p_rid)) { } else if (lightmap_instance_owner.owns(p_rid)) {
lightmap_instance_owner.free(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); 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); light_instance_owner.free(p_rid);
} else if (shadow_atlas_owner.owns(p_rid)) { } else if (shadow_atlas_owner.owns(p_rid)) {

View File

@ -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: private:
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED; RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
static RendererSceneRenderRD *singleton; static RendererSceneRenderRD *singleton;
@ -189,9 +206,10 @@ private:
uint32_t render_step = 0; uint32_t render_step = 0;
uint64_t last_pass = 0; uint64_t last_pass = 0;
uint32_t render_index = 0;
uint32_t cull_mask = 0; uint32_t cull_mask = 0;
ForwardID forward_id = -1;
Transform3D transform; Transform3D transform;
}; };
@ -202,8 +220,8 @@ private:
struct DecalInstance { struct DecalInstance {
RID decal; RID decal;
Transform3D transform; Transform3D transform;
uint32_t render_index;
uint32_t cull_mask; uint32_t cull_mask;
ForwardID forward_id = -1;
}; };
mutable RID_Owner<DecalInstance> decal_instance_owner; mutable RID_Owner<DecalInstance> decal_instance_owner;
@ -347,7 +365,6 @@ private:
uint64_t last_scene_pass = 0; uint64_t last_scene_pass = 0;
uint64_t last_scene_shadow_pass = 0; uint64_t last_scene_shadow_pass = 0;
uint64_t last_pass = 0; uint64_t last_pass = 0;
uint32_t light_index = 0;
uint32_t cull_mask = 0; uint32_t cull_mask = 0;
uint32_t light_directional_index = 0; uint32_t light_directional_index = 0;
@ -359,6 +376,8 @@ private:
Set<RID> shadow_atlases; //shadow atlases where this light is registered Set<RID> shadow_atlases; //shadow atlases where this light is registered
ForwardID forward_id = -1;
LightInstance() {} LightInstance() {}
}; };
@ -1006,14 +1025,9 @@ public:
return li->last_pass; return li->last_pass;
} }
_FORCE_INLINE_ void light_instance_set_index(RID p_light_instance, uint32_t p_index) { _FORCE_INLINE_ ForwardID light_instance_get_forward_id(RID p_light_instance) {
LightInstance *li = light_instance_owner.getornull(p_light_instance); LightInstance *li = light_instance_owner.getornull(p_light_instance);
li->light_index = p_index; return li->forward_id;
}
_FORCE_INLINE_ uint32_t light_instance_get_index(RID p_light_instance) {
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->light_index;
} }
_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) { _FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
@ -1050,17 +1064,11 @@ public:
return rpi->probe; return rpi->probe;
} }
_FORCE_INLINE_ void reflection_probe_instance_set_render_index(RID p_instance, uint32_t p_render_index) { _FORCE_INLINE_ ForwardID reflection_probe_instance_get_forward_id(RID p_instance) {
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) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, 0); 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) { _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; 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 { _FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal) const {
DecalInstance *decal = decal_instance_owner.getornull(p_decal); DecalInstance *decal = decal_instance_owner.getornull(p_decal);
return decal->transform; return decal->transform;
@ -1118,8 +1131,6 @@ public:
return li->transform; 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 */ /* gi light probes */
virtual RID voxel_gi_instance_create(RID p_base) override; virtual RID voxel_gi_instance_create(RID p_base) override;
@ -1131,6 +1142,7 @@ public:
/* render buffers */ /* render buffers */
virtual RD::DataFormat _render_buffers_get_color_format(); virtual RD::DataFormat _render_buffers_get_color_format();
virtual bool _render_buffers_can_be_storage();
virtual RID render_buffers_create() override; 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 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; virtual void gi_set_use_half_resolution(bool p_enable) override;

View File

@ -1291,7 +1291,7 @@ void main() {
blur_shadow(shadow); 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 #ifdef LIGHT_BACKLIGHT_USED
backlight, backlight,
#endif #endif