Skip to content

Commit b962b38

Browse files
committed
Check for Vulkan Memory Model support and make it a variant.
1 parent 967e2d4 commit b962b38

File tree

9 files changed

+86
-44
lines changed

9 files changed

+86
-44
lines changed

drivers/d3d12/rendering_device_driver_d3d12.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5588,6 +5588,8 @@ bool RenderingDeviceDriverD3D12::has_feature(Features p_feature) {
55885588
return true;
55895589
case SUPPORTS_IMAGE_ATOMIC_32_BIT:
55905590
return true;
5591+
case SUPPORTS_VULKAN_MEMORY_MODEL:
5592+
return false;
55915593
default:
55925594
return false;
55935595
}

drivers/metal/rendering_device_driver_metal.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,8 @@ bool isArrayTexture(MTLTextureType p_type) {
27432743
return device_properties->features.metal_fx_temporal;
27442744
case SUPPORTS_IMAGE_ATOMIC_32_BIT:
27452745
return device_properties->features.supports_native_image_atomics;
2746+
case SUPPORTS_VULKAN_MEMORY_MODEL:
2747+
return true;
27462748
default:
27472749
return false;
27482750
}

drivers/vulkan/rendering_device_driver_vulkan.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
533533
_register_requested_device_extension(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
534534
_register_requested_device_extension(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, false);
535535
_register_requested_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, false);
536+
_register_requested_device_extension(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, false);
536537
_register_requested_device_extension(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, false);
537538

538539
// We don't actually use this extension, but some runtime components on some platforms
@@ -756,6 +757,7 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
756757
VkPhysicalDeviceVulkan12Features device_features_vk_1_2 = {};
757758
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {};
758759
VkPhysicalDeviceBufferDeviceAddressFeaturesKHR buffer_device_address_features = {};
760+
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkan_memory_model_features = {};
759761
VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = {};
760762
VkPhysicalDeviceFragmentDensityMapFeaturesEXT fdm_features = {};
761763
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {};
@@ -778,6 +780,11 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
778780
buffer_device_address_features.pNext = next_features;
779781
next_features = &buffer_device_address_features;
780782
}
783+
if (enabled_device_extension_names.has(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) {
784+
vulkan_memory_model_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
785+
vulkan_memory_model_features.pNext = next_features;
786+
next_features = &vulkan_memory_model_features;
787+
}
781788
}
782789

783790
if (enabled_device_extension_names.has(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
@@ -826,6 +833,10 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
826833
if (enabled_device_extension_names.has(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) {
827834
buffer_device_address_support = device_features_vk_1_2.bufferDeviceAddress;
828835
}
836+
if (enabled_device_extension_names.has(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) {
837+
vulkan_memory_model_support = device_features_vk_1_2.vulkanMemoryModel;
838+
vulkan_memory_model_device_scope_support = device_features_vk_1_2.vulkanMemoryModelDeviceScope;
839+
}
829840
} else {
830841
if (enabled_device_extension_names.has(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
831842
shader_capabilities.shader_float16_is_supported = shader_features.shaderFloat16;
@@ -834,6 +845,10 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
834845
if (enabled_device_extension_names.has(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) {
835846
buffer_device_address_support = buffer_device_address_features.bufferDeviceAddress;
836847
}
848+
if (enabled_device_extension_names.has(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) {
849+
vulkan_memory_model_support = vulkan_memory_model_features.vulkanMemoryModel;
850+
vulkan_memory_model_device_scope_support = vulkan_memory_model_features.vulkanMemoryModelDeviceScope;
851+
}
837852
}
838853

839854
if (enabled_device_extension_names.has(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
@@ -1078,6 +1093,15 @@ Error RenderingDeviceDriverVulkan::_initialize_device(const LocalVector<VkDevice
10781093
create_info_next = &buffer_device_address_features;
10791094
}
10801095

1096+
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkan_memory_model_features = {};
1097+
if (vulkan_memory_model_support && vulkan_memory_model_device_scope_support) {
1098+
vulkan_memory_model_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
1099+
vulkan_memory_model_features.pNext = create_info_next;
1100+
vulkan_memory_model_features.vulkanMemoryModel = vulkan_memory_model_support;
1101+
vulkan_memory_model_features.vulkanMemoryModelDeviceScope = vulkan_memory_model_device_scope_support;
1102+
create_info_next = &vulkan_memory_model_features;
1103+
}
1104+
10811105
VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = {};
10821106
if (fsr_capabilities.pipeline_supported || fsr_capabilities.primitive_supported || fsr_capabilities.attachment_supported) {
10831107
fsr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
@@ -5901,6 +5925,8 @@ bool RenderingDeviceDriverVulkan::has_feature(Features p_feature) {
59015925
#else
59025926
return true;
59035927
#endif
5928+
case SUPPORTS_VULKAN_MEMORY_MODEL:
5929+
return vulkan_memory_model_support && vulkan_memory_model_device_scope_support;
59045930
default:
59055931
return false;
59065932
}

drivers/vulkan/rendering_device_driver_vulkan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
133133
StorageBufferCapabilities storage_buffer_capabilities;
134134
RenderingShaderContainerFormatVulkan shader_container_format;
135135
bool buffer_device_address_support = false;
136+
bool vulkan_memory_model_support = false;
137+
bool vulkan_memory_model_device_scope_support = false;
136138
bool pipeline_cache_control_support = false;
137139
bool device_fault_support = false;
138140
#if defined(VK_TRACK_DEVICE_MEMORY)

servers/rendering/renderer_rd/environment/fog.cpp

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
5968
int 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)));

servers/rendering/renderer_rd/environment/fog.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Fog : public RendererFog {
4848
private:
4949
static Fog *singleton;
5050

51+
static int _get_fog_shader_group();
5152
static int _get_fog_variant();
5253
static int _get_fog_process_variant(int p_idx);
5354

@@ -76,6 +77,13 @@ class Fog : public RendererFog {
7677

7778
/* Volumetric Fog */
7879
struct VolumetricFogShader {
80+
enum ShaderGroup {
81+
SHADER_GROUP_BASE,
82+
SHADER_GROUP_NO_ATOMICS,
83+
SHADER_GROUP_VULKAN_MEMORY_MODEL,
84+
SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS,
85+
};
86+
7987
enum FogSet {
8088
FOG_SET_BASE,
8189
FOG_SET_UNIFORMS,

servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
#version 450
44

5-
#pragma use_vulkan_memory_model
6-
75
#VERSION_DEFINES
86

7+
#ifdef USE_VULKAN_MEMORY_MODEL
8+
#pragma use_vulkan_memory_model
9+
#endif
10+
911
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
1012

1113
#define DENSITY_SCALE 1024.0

servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
#version 450
44

5-
#pragma use_vulkan_memory_model
6-
75
#VERSION_DEFINES
86

7+
#ifdef USE_VULKAN_MEMORY_MODEL
8+
#pragma use_vulkan_memory_model
9+
#endif
10+
911
#ifdef MODE_DENSITY
1012
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
1113
#else

servers/rendering/rendering_device_commons.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ class RenderingDeviceCommons : public Object {
953953
SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS,
954954
SUPPORTS_BUFFER_DEVICE_ADDRESS,
955955
SUPPORTS_IMAGE_ATOMIC_32_BIT,
956+
SUPPORTS_VULKAN_MEMORY_MODEL,
956957
};
957958

958959
enum SubgroupOperations {

0 commit comments

Comments
 (0)