@@ -47,22 +47,29 @@ Fog::~Fog() {
4747 singleton = nullptr ;
4848}
4949
50- int Fog::_get_fog_variant () {
50+ int Fog::_get_fog_shader_group () {
5151 RenderingDevice *rd = RD::get_singleton ();
52- if (rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
53- return 0 ;
52+ bool use_32_bit_atomics = rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT);
53+ bool use_vulkan_memory_model = rd->has_feature (RD::SUPPORTS_VULKAN_MEMORY_MODEL);
54+ if (use_vulkan_memory_model) {
55+ return use_32_bit_atomics ? VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL : VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS;
5456 } else {
55- return 1 ;
57+ return use_32_bit_atomics ? VolumetricFogShader::SHADER_GROUP_BASE : VolumetricFogShader::SHADER_GROUP_NO_ATOMICS ;
5658 }
5759}
5860
61+ int Fog::_get_fog_variant () {
62+ RenderingDevice *rd = RD::get_singleton ();
63+ bool use_32_bit_atomics = rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT);
64+ bool use_vulkan_memory_model = rd->has_feature (RD::SUPPORTS_VULKAN_MEMORY_MODEL);
65+ return (use_vulkan_memory_model ? 2 : 0 ) + (use_32_bit_atomics ? 0 : 1 );
66+ }
67+
5968int Fog::_get_fog_process_variant (int p_idx) {
6069 RenderingDevice *rd = RD::get_singleton ();
61- if (rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
62- return p_idx;
63- } else {
64- return p_idx + VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX;
65- }
70+ bool use_32_bit_atomics = rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT);
71+ bool use_vulkan_memory_model = rd->has_feature (RD::SUPPORTS_VULKAN_MEMORY_MODEL);
72+ return (use_vulkan_memory_model ? (VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX * 2 ) : 0 ) + (use_32_bit_atomics ? 0 : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX) + p_idx;
6673}
6774
6875/* FOG VOLUMES */
@@ -210,18 +217,14 @@ void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_lay
210217 {
211218 String defines = " #define SAMPLERS_BINDING_FIRST_INDEX " + itos (SAMPLERS_BINDING_FIRST_INDEX) + " \n " ;
212219 // Initialize local fog shader
213- Vector<String> volumetric_fog_modes;
214- volumetric_fog_modes.push_back (" " );
215- volumetric_fog_modes.push_back (" #define NO_IMAGE_ATOMICS\n " );
220+ Vector<ShaderRD::VariantDefine> volumetric_fog_modes;
221+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (VolumetricFogShader::SHADER_GROUP_BASE, " " , false ));
222+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (VolumetricFogShader::SHADER_GROUP_NO_ATOMICS, " #define NO_IMAGE_ATOMICS\n " , false ));
223+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL, " #define USE_VULKAN_MEMORY_MODEL\n " , false ));
224+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS, " #define USE_VULKAN_MEMORY_MODEL\n #define NO_IMAGE_ATOMICS\n " , false ));
216225
217226 volumetric_fog.shader .initialize (volumetric_fog_modes, defines);
218-
219- RenderingDevice *rd = RD::get_singleton ();
220- if (rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
221- volumetric_fog.shader .set_variant_enabled (1 , false );
222- } else {
223- volumetric_fog.shader .set_variant_enabled (0 , false );
224- }
227+ volumetric_fog.shader .enable_group (_get_fog_shader_group ());
225228
226229 material_storage->shader_set_data_request_function (RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_shader_funcs);
227230 material_storage->material_set_data_request_function (RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_material_funcs);
@@ -302,30 +305,24 @@ ALBEDO = vec3(1.0);
302305 if (p_is_using_radiance_cubemap_array) {
303306 defines += " \n #define USE_RADIANCE_CUBEMAP_ARRAY \n " ;
304307 }
305- Vector<String> volumetric_fog_modes;
306- volumetric_fog_modes.push_back (" \n #define MODE_DENSITY\n " );
307- volumetric_fog_modes.push_back (" \n #define MODE_DENSITY\n #define ENABLE_SDFGI\n " );
308- volumetric_fog_modes.push_back (" \n #define MODE_FILTER\n " );
309- volumetric_fog_modes.push_back (" \n #define MODE_FOG\n " );
310- volumetric_fog_modes.push_back (" \n #define MODE_COPY\n " );
311-
312- volumetric_fog_modes.push_back (" \n #define MODE_DENSITY\n #define NO_IMAGE_ATOMICS\n " );
313- volumetric_fog_modes.push_back (" \n #define MODE_DENSITY\n #define ENABLE_SDFGI\n #define NO_IMAGE_ATOMICS\n " );
314- volumetric_fog_modes.push_back (" \n #define MODE_FILTER\n #define NO_IMAGE_ATOMICS\n " );
315- volumetric_fog_modes.push_back (" \n #define MODE_FOG\n #define NO_IMAGE_ATOMICS\n " );
316- volumetric_fog_modes.push_back (" \n #define MODE_COPY\n #define NO_IMAGE_ATOMICS\n " );
317-
318- volumetric_fog.process_shader .initialize (volumetric_fog_modes, defines);
319-
320- RenderingDevice *rd = RD::get_singleton ();
321- for (int i = 0 ; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) {
322- if (rd->has_feature (RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
323- volumetric_fog.process_shader .set_variant_enabled (i + VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX, false );
324- } else {
325- volumetric_fog.process_shader .set_variant_enabled (i, false );
308+ Vector<ShaderRD::VariantDefine> volumetric_fog_modes;
309+ int shader_group = 0 ;
310+ for (int vk_memory_model = 0 ; vk_memory_model < 2 ; vk_memory_model++) {
311+ for (int no_atomics = 0 ; no_atomics < 2 ; no_atomics++) {
312+ String base_define = vk_memory_model ? " \n #define USE_VULKAN_MEMORY_MODEL" : " " ;
313+ base_define += no_atomics ? " \n #define NO_IMAGE_ATOMICS" : " " ;
314+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (shader_group, base_define + " \n #define MODE_DENSITY\n " , false ));
315+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (shader_group, base_define + " \n #define MODE_DENSITY\n #define ENABLE_SDFGI\n " , false ));
316+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (shader_group, base_define + " \n #define MODE_FILTER\n " , false ));
317+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (shader_group, base_define + " \n #define MODE_FOG\n " , false ));
318+ volumetric_fog_modes.push_back (ShaderRD::VariantDefine (shader_group, base_define + " \n #define MODE_COPY\n " , false ));
319+ shader_group++;
326320 }
327321 }
328322
323+ volumetric_fog.process_shader .initialize (volumetric_fog_modes, defines);
324+ volumetric_fog.process_shader .enable_group (_get_fog_shader_group ());
325+
329326 volumetric_fog.process_shader_version = volumetric_fog.process_shader .version_create ();
330327 for (int i = 0 ; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) {
331328 volumetric_fog.process_pipelines [i] = RD::get_singleton ()->compute_pipeline_create (volumetric_fog.process_shader .version_get_shader (volumetric_fog.process_shader_version , _get_fog_process_variant (i)));
0 commit comments