1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

Use half float precision buffer for 3D when HDR2D is enabled

This is necessary for Environment effects like Glow to work correctly.
This commit is contained in:
clayjohn
2025-08-25 14:03:31 -07:00
parent c7b1767560
commit f61ee7bdf6
13 changed files with 60 additions and 53 deletions

View File

@@ -1542,7 +1542,7 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
}
atlas->reflections.resize(atlas->count);
for (int i = 0; i < atlas->count; i++) {
atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format());
atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_preferred_color_format());
for (int j = 0; j < 6; j++) {
atlas->reflections.write[i].fbs[j] = RendererSceneRenderRD::get_singleton()->reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer);
}
@@ -1814,7 +1814,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
}
RD::DataFormat LightStorage::get_reflection_probe_color_format() {
return RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format();
return RendererSceneRenderRD::get_singleton()->_render_buffers_get_preferred_color_format();
}
uint32_t LightStorage::get_reflection_probe_color_usage_bits() {

View File

@@ -152,6 +152,8 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
render_target = p_config->get_render_target();
force_hdr = texture_storage->render_target_is_using_hdr(render_target);
target_size = p_config->get_target_size();
internal_size = p_config->get_internal_size();
view_count = p_config->get_view_count();
@@ -177,7 +179,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co
// Create our color buffer.
const bool resolve_target = msaa_3d != RS::VIEWPORT_MSAA_DISABLED;
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, base_data_format, get_color_usage_bits(resolve_target, false, can_be_storage));
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, get_base_data_format(), get_color_usage_bits(resolve_target, false, can_be_storage));
// TODO: Detect when it is safe to use RD::TEXTURE_USAGE_TRANSIENT_BIT for RB_TEX_DEPTH, RB_TEX_COLOR_MSAA and/or RB_TEX_DEPTH_MSAA.
// (it means we cannot sample from it, we cannot copy from/to it) to save VRAM (and maybe performance too).
@@ -190,7 +192,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co
texture_samples = RD::TEXTURE_SAMPLES_1;
} else {
texture_samples = msaa_to_samples(msaa_3d);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, base_data_format, get_color_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, get_base_data_format(), get_color_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, get_depth_format(false, true, can_be_storage), get_depth_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true);
}
@@ -267,7 +269,7 @@ void RenderSceneBuffersRD::ensure_mfx(RendererRD::MFXSpatialEffect *p_effect) {
RendererRD::MFXSpatialEffect::CreateParams params = {
.input_size = internal_size,
.output_size = target_size,
.input_format = base_data_format,
.input_format = get_base_data_format(),
.output_format = output_format,
};
@@ -525,12 +527,12 @@ void RenderSceneBuffersRD::allocate_blur_textures() {
usage_bits += RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, blur_size, view_count, mipmaps_required);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y >> 1), view_count, mipmaps_required - 1);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, blur_size, view_count, mipmaps_required);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y >> 1), view_count, mipmaps_required - 1);
// if !can_be_storage we need a half width version
if (!can_be_storage) {
create_texture(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y), 1, mipmaps_required);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y), 1, mipmaps_required);
}
// TODO redo this:
@@ -646,7 +648,7 @@ void RenderSceneBuffersRD::ensure_upscaled() {
if (!has_upscaled_texture()) {
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | (can_be_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : 0) | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
usage_bits |= RD::TEXTURE_USAGE_INPUT_ATTACHMENT_BIT;
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_UPSCALED, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, target_size);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_UPSCALED, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, target_size);
}
}
@@ -775,3 +777,9 @@ RD::DataFormat RenderSceneBuffersRD::get_vrs_format() {
uint32_t RenderSceneBuffersRD::get_vrs_usage_bits() {
return RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT;
}
float RenderSceneBuffersRD::get_luminance_multiplier() const {
// On mobile renderer when not using HDR2D we need to scale HDR values by two
// to fit 0-2 range color values into a UNORM buffer.
return (force_hdr || can_be_storage) ? 1.0 : 2.0;
}

View File

@@ -65,8 +65,9 @@ class RenderSceneBuffersRD : public RenderSceneBuffers {
private:
bool can_be_storage = true;
bool force_hdr = false;
uint32_t max_cluster_elements = 512;
RD::DataFormat base_data_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
RD::DataFormat preferred_data_format = RD::DATA_FORMAT_MAX;
RendererRD::VRS *vrs = nullptr;
uint64_t auto_exposure_version = 1;
RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED;
@@ -186,8 +187,10 @@ public:
bool get_can_be_storage() const { return can_be_storage; }
void set_max_cluster_elements(const uint32_t p_max_elements) { max_cluster_elements = p_max_elements; }
uint32_t get_max_cluster_elements() { return max_cluster_elements; }
void set_base_data_format(const RD::DataFormat p_base_data_format) { base_data_format = p_base_data_format; }
RD::DataFormat get_base_data_format() const { return base_data_format; }
void set_preferred_data_format(const RD::DataFormat p_preferred_data_format) { preferred_data_format = p_preferred_data_format; }
RD::DataFormat get_preferred_data_format() const { return preferred_data_format; }
RD::DataFormat get_base_data_format() const { return force_hdr ? RD::DATA_FORMAT_R16G16B16A16_SFLOAT : preferred_data_format; }
float get_luminance_multiplier() const;
void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; }
RS::ViewportVRSMode get_vrs_mode() { return vrs_mode; }

View File

@@ -1504,8 +1504,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
Ref<Image> image;
// Expand RGB10_A2 into RGBAH. This is needed for capturing viewport data
// when using the mobile renderer with HDR mode on.
// Expand RGB10_A2 into RGBAH.
if (tex->rd_format == RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32) {
Vector<uint8_t> new_data;
new_data.resize(data.size() * 2);
@@ -4533,7 +4532,7 @@ RID TextureStorage::render_target_get_vrs_texture(RID p_render_target) const {
RD::DataFormat TextureStorage::render_target_get_color_format(bool p_use_hdr, bool p_srgb) {
if (p_use_hdr) {
return RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format();
return RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
} else {
return p_srgb ? RD::DATA_FORMAT_R8G8B8A8_SRGB : RD::DATA_FORMAT_R8G8B8A8_UNORM;
}