1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Apple: Use image atomic operations on supported Apple hardware

Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
This commit is contained in:
Stuart Carnie
2025-06-27 09:59:21 +10:00
parent 9b22b41531
commit 5230f6c60c
32 changed files with 5354 additions and 719 deletions

View File

@@ -417,6 +417,7 @@ void Fog::VolumetricFog::init(const Vector3i &fog_size, RID p_sky_shader) {
width = fog_size.x;
height = fog_size.y;
depth = fog_size.z;
atomic_type = RD::get_singleton()->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT) ? RD::UNIFORM_TYPE_IMAGE : RD::UNIFORM_TYPE_STORAGE_BUFFER;
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@@ -440,29 +441,29 @@ void Fog::VolumetricFog::init(const Vector3i &fog_size, RID p_sky_shader) {
fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(fog_map, "Fog map");
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
Vector<uint8_t> dm;
dm.resize_initialized(fog_size.x * fog_size.y * fog_size.z * 4);
if (atomic_type == RD::UNIFORM_TYPE_STORAGE_BUFFER) {
Vector<uint8_t> dm;
dm.resize_initialized(fog_size.x * fog_size.y * fog_size.z * 4);
density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
RD::get_singleton()->set_resource_name(density_map, "Fog density map");
light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
RD::get_singleton()->set_resource_name(light_map, "Fog light map");
emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");
#else
tf.format = RD::DATA_FORMAT_R32_UINT;
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(density_map, "Fog density map");
RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
light_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(light_map, "Fog light map");
RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");
RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
#endif
density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
RD::get_singleton()->set_resource_name(density_map, "Fog density map");
light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
RD::get_singleton()->set_resource_name(light_map, "Fog light map");
emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");
} else {
tf.format = RD::DATA_FORMAT_R32_UINT;
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_ATOMIC_BIT;
density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(density_map, "Fog density map");
RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
light_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(light_map, "Fog light map");
RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");
RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
}
Vector<RD::Uniform> uniforms;
{
@@ -579,11 +580,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
#endif
u.uniform_type = fog->atomic_type;
u.binding = 1;
u.append_id(fog->emissive_map);
uniforms.push_back(u);
@@ -599,11 +596,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
#endif
u.uniform_type = fog->atomic_type;
u.binding = 3;
u.append_id(fog->density_map);
uniforms.push_back(u);
@@ -611,11 +604,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
#endif
u.uniform_type = fog->atomic_type;
u.binding = 4;
u.append_id(fog->light_map);
uniforms.push_back(u);
@@ -918,22 +907,14 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
}
{
RD::Uniform u;
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
#endif
u.uniform_type = fog->atomic_type;
u.binding = 16;
u.append_id(fog->density_map);
uniforms.push_back(u);
}
{
RD::Uniform u;
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
#endif
u.uniform_type = fog->atomic_type;
u.binding = 17;
u.append_id(fog->light_map);
uniforms.push_back(u);
@@ -941,11 +922,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
{
RD::Uniform u;
#if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
#endif
u.uniform_type = fog->atomic_type;
u.binding = 18;
u.append_id(fog->emissive_map);
uniforms.push_back(u);

View File

@@ -316,6 +316,9 @@ public:
int last_shadow_filter = -1;
// If the device doesn't support image atomics, use storage buffers instead.
RD::UniformType atomic_type = RD::UNIFORM_TYPE_IMAGE;
virtual void configure(RenderSceneBuffersRD *p_render_buffers) override {}
virtual void free_data() override {}