|
|
|
@ -53,6 +53,7 @@ RendererRD::ForwardID RenderForwardMobile::ForwardIDStorageMobile::allocate_forw
|
|
|
|
|
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);
|
|
|
|
|
forward_id_allocators[p_type].last_pass.push_back(0);
|
|
|
|
|
} else {
|
|
|
|
|
forward_id_allocators[p_type].allocations[index] = true;
|
|
|
|
|
}
|
|
|
|
@ -64,44 +65,72 @@ void RenderForwardMobile::ForwardIDStorageMobile::free_forward_id(RendererRD::Fo
|
|
|
|
|
forward_id_allocators[p_type].allocations[p_id] = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index) {
|
|
|
|
|
void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index, uint64_t p_last_pass) {
|
|
|
|
|
forward_id_allocators[p_type].map[p_id] = p_index;
|
|
|
|
|
forward_id_allocators[p_type].last_pass[p_id] = p_last_pass;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderForwardMobile::fill_push_constant_instance_indices(SceneState::InstanceData *p_instance_data, const GeometryInstanceForwardMobile *p_instance) {
|
|
|
|
|
// First zero out our indices.
|
|
|
|
|
uint64_t current_frame = RSG::rasterizer->get_frame_number();
|
|
|
|
|
|
|
|
|
|
p_instance_data->omni_lights[0] = 0xFFFFFFFF;
|
|
|
|
|
p_instance_data->omni_lights[1] = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
uint32_t idx = 0;
|
|
|
|
|
for (uint32_t i = 0; i < p_instance->omni_light_count; i++) {
|
|
|
|
|
uint32_t ofs = idx < 4 ? 0 : 1;
|
|
|
|
|
uint32_t shift = (idx & 0x3) << 3;
|
|
|
|
|
uint32_t mask = ~(0xFF << shift);
|
|
|
|
|
|
|
|
|
|
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].last_pass[p_instance->omni_lights[i]] == current_frame) {
|
|
|
|
|
p_instance_data->omni_lights[ofs] &= mask;
|
|
|
|
|
p_instance_data->omni_lights[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p_instance_data->spot_lights[0] = 0xFFFFFFFF;
|
|
|
|
|
p_instance_data->spot_lights[1] = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
|
for (uint32_t i = 0; i < p_instance->spot_light_count; i++) {
|
|
|
|
|
uint32_t ofs = idx < 4 ? 0 : 1;
|
|
|
|
|
uint32_t shift = (idx & 0x3) << 3;
|
|
|
|
|
uint32_t mask = ~(0xFF << shift);
|
|
|
|
|
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].last_pass[p_instance->spot_lights[i]] == current_frame) {
|
|
|
|
|
p_instance_data->spot_lights[ofs] &= mask;
|
|
|
|
|
p_instance_data->spot_lights[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p_instance_data->decals[0] = 0xFFFFFFFF;
|
|
|
|
|
p_instance_data->decals[1] = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
|
for (uint32_t i = 0; i < p_instance->decals_count; i++) {
|
|
|
|
|
uint32_t ofs = idx < 4 ? 0 : 1;
|
|
|
|
|
uint32_t shift = (idx & 0x3) << 3;
|
|
|
|
|
uint32_t mask = ~(0xFF << shift);
|
|
|
|
|
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].last_pass[p_instance->decals[i]] == current_frame) {
|
|
|
|
|
p_instance_data->decals[ofs] &= mask;
|
|
|
|
|
p_instance_data->decals[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p_instance_data->reflection_probes[0] = 0xFFFFFFFF;
|
|
|
|
|
p_instance_data->reflection_probes[1] = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < MAX_RDL_CULL; i++) {
|
|
|
|
|
uint32_t ofs = i < 4 ? 0 : 1;
|
|
|
|
|
uint32_t shift = (i & 0x3) << 3;
|
|
|
|
|
idx = 0;
|
|
|
|
|
for (uint32_t i = 0; i < p_instance->reflection_probe_count; i++) {
|
|
|
|
|
uint32_t ofs = idx < 4 ? 0 : 1;
|
|
|
|
|
uint32_t shift = (idx & 0x3) << 3;
|
|
|
|
|
uint32_t mask = ~(0xFF << shift);
|
|
|
|
|
if (i < p_instance->omni_light_count) {
|
|
|
|
|
p_instance_data->omni_lights[ofs] &= mask;
|
|
|
|
|
p_instance_data->omni_lights[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
|
|
|
|
|
}
|
|
|
|
|
if (i < p_instance->spot_light_count) {
|
|
|
|
|
p_instance_data->spot_lights[ofs] &= mask;
|
|
|
|
|
p_instance_data->spot_lights[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
|
|
|
|
|
}
|
|
|
|
|
if (i < p_instance->decals_count) {
|
|
|
|
|
p_instance_data->decals[ofs] &= mask;
|
|
|
|
|
p_instance_data->decals[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
|
|
|
|
|
}
|
|
|
|
|
if (i < p_instance->reflection_probe_count) {
|
|
|
|
|
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_REFLECTION_PROBE].last_pass[p_instance->reflection_probes[i]] == current_frame) {
|
|
|
|
|
p_instance_data->reflection_probes[ofs] &= mask;
|
|
|
|
|
p_instance_data->reflection_probes[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift;
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -539,7 +568,6 @@ void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, co
|
|
|
|
|
|
|
|
|
|
void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
|
|
|
|
|
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
|
|
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
|
|
|
|
|
|
|
|
|
p_render_data->cube_shadows.clear();
|
|
|
|
|
p_render_data->shadows.clear();
|
|
|
|
@ -598,28 +626,11 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
|
|
|
|
|
|
|
|
|
|
//full barrier here, we need raster, transfer and compute and it depends from the previous work
|
|
|
|
|
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);
|
|
|
|
|
|
|
|
|
|
bool using_shadows = true;
|
|
|
|
|
|
|
|
|
|
if (p_render_data->reflection_probe.is_valid()) {
|
|
|
|
|
if (!RSG::light_storage->reflection_probe_renders_shadows(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
|
|
|
|
using_shadows = false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//do not render reflections when rendering a reflection probe
|
|
|
|
|
light_storage->update_reflection_probe_buffer(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t directional_light_count = 0;
|
|
|
|
|
uint32_t positional_light_count = 0;
|
|
|
|
|
light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
|
|
|
|
|
texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform);
|
|
|
|
|
|
|
|
|
|
p_render_data->directional_light_count = directional_light_count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
|
|
|
|
|
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
|
|
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
|
|
|
|
|
|
|
|
|
ERR_FAIL_NULL(p_render_data);
|
|
|
|
|
|
|
|
|
@ -668,6 +679,25 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
|
|
|
bool using_subpass_transparent = true;
|
|
|
|
|
bool using_subpass_post_process = true;
|
|
|
|
|
|
|
|
|
|
bool using_shadows = true;
|
|
|
|
|
|
|
|
|
|
if (p_render_data->reflection_probe.is_valid()) {
|
|
|
|
|
if (!RSG::light_storage->reflection_probe_renders_shadows(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
|
|
|
|
using_shadows = false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//do not render reflections when rendering a reflection probe
|
|
|
|
|
light_storage->update_reflection_probe_buffer(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update light and decal buffer first so we know what lights and decals are safe to pair with.
|
|
|
|
|
uint32_t directional_light_count = 0;
|
|
|
|
|
uint32_t positional_light_count = 0;
|
|
|
|
|
light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
|
|
|
|
|
texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform);
|
|
|
|
|
|
|
|
|
|
p_render_data->directional_light_count = directional_light_count;
|
|
|
|
|
|
|
|
|
|
// fill our render lists early so we can find out if we use various features
|
|
|
|
|
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
|
|
|
|
|
render_list[RENDER_LIST_OPAQUE].sort_by_key();
|
|
|
|
|