Kaynağa Gözat

Merge pull request #55281 from bruvzg/mvk_fog_volumes

Rémi Verschelde 3 yıl önce
ebeveyn
işleme
3e3300637e

+ 37 - 0
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -3796,6 +3796,18 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 		rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
 		RD::get_singleton()->set_resource_name(rb->volumetric_fog->fog_map, "Fog map");
 
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+		Vector<uint8_t> dm;
+		dm.resize(target_width * target_height * volumetric_fog_depth * 4);
+		dm.fill(0);
+
+		rb->volumetric_fog->density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
+		RD::get_singleton()->set_resource_name(rb->volumetric_fog->density_map, "Fog density map");
+		rb->volumetric_fog->light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
+		RD::get_singleton()->set_resource_name(rb->volumetric_fog->light_map, "Fog light map");
+		rb->volumetric_fog->emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
+		RD::get_singleton()->set_resource_name(rb->volumetric_fog->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;
 		rb->volumetric_fog->density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -3807,6 +3819,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 		rb->volumetric_fog->emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
 		RD::get_singleton()->set_resource_name(rb->volumetric_fog->emissive_map, "Fog emissive map");
 		RD::get_singleton()->texture_clear(rb->volumetric_fog->emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+#endif
 
 		Vector<RD::Uniform> uniforms;
 		{
@@ -3872,7 +3885,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 			{
 				RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
 				u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
 				u.binding = 1;
 				u.ids.push_back(rb->volumetric_fog->emissive_map);
 				uniforms.push_back(u);
@@ -3888,7 +3905,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 			{
 				RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
 				u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
 				u.binding = 3;
 				u.ids.push_back(rb->volumetric_fog->density_map);
 				uniforms.push_back(u);
@@ -3896,7 +3917,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 			{
 				RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
 				u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
 				u.binding = 4;
 				u.ids.push_back(rb->volumetric_fog->light_map);
 				uniforms.push_back(u);
@@ -4163,14 +4188,22 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 		}
 		{
 			RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
 			u.binding = 16;
 			u.ids.push_back(rb->volumetric_fog->density_map);
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
 			u.binding = 17;
 			u.ids.push_back(rb->volumetric_fog->light_map);
 			uniforms.push_back(u);
@@ -4178,7 +4211,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 		{
 			RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
 			u.binding = 18;
 			u.ids.push_back(rb->volumetric_fog->emissive_map);
 			uniforms.push_back(u);

+ 3 - 0
servers/rendering/renderer_rd/shader_rd.cpp

@@ -177,6 +177,9 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c
 				for (const KeyValue<StringName, CharString> &E : p_version->code_sections) {
 					builder.append(String("#define ") + String(E.key) + "_CODE_USED\n");
 				}
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				builder.append("#define MOLTENVK_USED\n");
+#endif
 			} break;
 			case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: {
 				builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment)

+ 38 - 0
servers/rendering/renderer_rd/shaders/volumetric_fog.glsl

@@ -47,7 +47,13 @@ layout(push_constant, binding = 0, std430) uniform Params {
 }
 params;
 
+#ifdef MOLTENVK_USED
+layout(set = 1, binding = 1) volatile buffer emissive_only_map_buffer {
+	uint emissive_only_map[];
+};
+#else
 layout(r32ui, set = 1, binding = 1) uniform volatile uimage3D emissive_only_map;
+#endif
 
 layout(set = 1, binding = 2, std140) uniform SceneParams {
 	vec2 fog_frustum_size_begin;
@@ -71,8 +77,17 @@ layout(set = 1, binding = 2, std140) uniform SceneParams {
 }
 scene_params;
 
+#ifdef MOLTENVK_USED
+layout(set = 1, binding = 3) volatile buffer density_only_map_buffer {
+	uint density_only_map[];
+};
+layout(set = 1, binding = 4) volatile buffer light_only_map_buffer {
+	uint light_only_map[];
+};
+#else
 layout(r32ui, set = 1, binding = 3) uniform volatile uimage3D density_only_map;
 layout(r32ui, set = 1, binding = 4) uniform volatile uimage3D light_only_map;
+#endif
 
 #ifdef MATERIAL_UNIFORMS_USED
 layout(set = 2, binding = 0, std140) uniform MaterialUniforms{
@@ -115,6 +130,9 @@ void main() {
 	if (any(greaterThanEqual(pos, scene_params.fog_volume_size))) {
 		return; //do not compute
 	}
+#ifdef MOLTENVK_USED
+	uint lpos = pos.z * scene_params.fog_volume_size.x * scene_params.fog_volume_size.y + pos.y * scene_params.fog_volume_size.x + pos.x;
+#endif
 
 	vec3 posf = vec3(pos);
 
@@ -197,7 +215,11 @@ void main() {
 		density *= cull_mask;
 		if (abs(density) > 0.001) {
 			int final_density = int(density * DENSITY_SCALE);
+#ifdef MOLTENVK_USED
+			atomicAdd(density_only_map[lpos], uint(final_density));
+#else
 			imageAtomicAdd(density_only_map, pos, uint(final_density));
+#endif
 
 #ifdef EMISSION_USED
 			{
@@ -207,7 +229,11 @@ void main() {
 				uvec3 emission_u = uvec3(emission.r * 511.0, emission.g * 511.0, emission.b * 255.0);
 				// R and G have 11 bits each and B has 10. Then pack them into a 32 bit uint
 				uint final_emission = emission_u.r << 21 | emission_u.g << 10 | emission_u.b;
+#ifdef MOLTENVK_USED
+				uint prev_emission = atomicAdd(emissive_only_map[lpos], final_emission);
+#else
 				uint prev_emission = imageAtomicAdd(emissive_only_map, pos, final_emission);
+#endif
 
 				// Adding can lead to colors overflowing, so validate
 				uvec3 prev_emission_u = uvec3(prev_emission >> 21, (prev_emission << 11) >> 21, prev_emission % 1024);
@@ -219,7 +245,11 @@ void main() {
 				if (any(overflowing)) {
 					uvec3 overflow_factor = mix(uvec3(0), uvec3(2047 << 21, 2047 << 10, 1023), overflowing);
 					uint force_max = overflow_factor.r | overflow_factor.g | overflow_factor.b;
+#ifdef MOLTENVK_USED
+					atomicOr(emissive_only_map[lpos], force_max);
+#else
 					imageAtomicOr(emissive_only_map, pos, force_max);
+#endif
 				}
 			}
 #endif
@@ -230,7 +260,11 @@ void main() {
 				uvec3 scattering_u = uvec3(scattering.r * 2047.0, scattering.g * 2047.0, scattering.b * 1023.0);
 				// R and G have 11 bits each and B has 10. Then pack them into a 32 bit uint
 				uint final_scattering = scattering_u.r << 21 | scattering_u.g << 10 | scattering_u.b;
+#ifdef MOLTENVK_USED
+				uint prev_scattering = atomicAdd(light_only_map[lpos], final_scattering);
+#else
 				uint prev_scattering = imageAtomicAdd(light_only_map, pos, final_scattering);
+#endif
 
 				// Adding can lead to colors overflowing, so validate
 				uvec3 prev_scattering_u = uvec3(prev_scattering >> 21, (prev_scattering << 11) >> 21, prev_scattering % 1024);
@@ -242,7 +276,11 @@ void main() {
 				if (any(overflowing)) {
 					uvec3 overflow_factor = mix(uvec3(0), uvec3(2047 << 21, 2047 << 10, 1023), overflowing);
 					uint force_max = overflow_factor.r | overflow_factor.g | overflow_factor.b;
+#ifdef MOLTENVK_USED
+					atomicOr(light_only_map[lpos], force_max);
+#else
 					imageAtomicOr(light_only_map, pos, force_max);
+#endif
 				}
 			}
 #endif // ALBEDO_USED

+ 35 - 0
servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl

@@ -190,9 +190,22 @@ params;
 #ifndef MODE_COPY
 layout(set = 0, binding = 15) uniform texture3D prev_density_texture;
 
+#ifdef MOLTENVK_USED
+layout(set = 0, binding = 16) buffer density_only_map_buffer {
+	uint density_only_map[];
+};
+layout(set = 0, binding = 17) buffer light_only_map_buffer {
+	uint light_only_map[];
+};
+layout(set = 0, binding = 18) buffer emissive_only_map_buffer {
+	uint emissive_only_map[];
+};
+#else
 layout(r32ui, set = 0, binding = 16) uniform uimage3D density_only_map;
 layout(r32ui, set = 0, binding = 17) uniform uimage3D light_only_map;
 layout(r32ui, set = 0, binding = 18) uniform uimage3D emissive_only_map;
+#endif
+
 #ifdef USE_RADIANCE_CUBEMAP_ARRAY
 layout(set = 0, binding = 19) uniform textureCubeArray sky_texture;
 #else
@@ -272,6 +285,9 @@ void main() {
 	if (any(greaterThanEqual(pos, params.fog_volume_size))) {
 		return; //do not compute
 	}
+#ifdef MOLTENVK_USED
+	uint lpos = pos.z * params.fog_volume_size.x * params.fog_volume_size.y + pos.y * params.fog_volume_size.x + pos.x;
+#endif
 
 	vec3 posf = vec3(pos);
 
@@ -335,15 +351,28 @@ void main() {
 	vec3 total_light = vec3(0.0);
 
 	float total_density = params.base_density;
+#ifdef MOLTENVK_USED
+	uint local_density = density_only_map[lpos];
+#else
 	uint local_density = imageLoad(density_only_map, pos).x;
+#endif
+
 	total_density += float(int(local_density)) / DENSITY_SCALE;
 	total_density = max(0.0, total_density);
 
+#ifdef MOLTENVK_USED
+	uint scattering_u = light_only_map[lpos];
+#else
 	uint scattering_u = imageLoad(light_only_map, pos).x;
+#endif
 	vec3 scattering = vec3(scattering_u >> 21, (scattering_u << 11) >> 21, scattering_u % 1024) / vec3(2047.0, 2047.0, 1023.0);
 	scattering += params.base_scattering * params.base_density;
 
+#ifdef MOLTENVK_USED
+	uint emission_u = emissive_only_map[lpos];
+#else
 	uint emission_u = imageLoad(emissive_only_map, pos).x;
+#endif
 	vec3 emission = vec3(emission_u >> 21, (emission_u << 11) >> 21, emission_u % 1024) / vec3(511.0, 511.0, 255.0);
 	emission += params.base_emission * params.base_density;
 
@@ -673,10 +702,16 @@ void main() {
 	final_density = mix(final_density, reprojected_density, reproject_amount);
 
 	imageStore(density_map, pos, final_density);
+#ifdef MOLTENVK_USED
+	density_only_map[lpos] = 0;
+	light_only_map[lpos] = 0;
+	emissive_only_map[lpos] = 0;
+#else
 	imageStore(density_only_map, pos, uvec4(0));
 	imageStore(light_only_map, pos, uvec4(0));
 	imageStore(emissive_only_map, pos, uvec4(0));
 #endif
+#endif
 
 #ifdef MODE_FOG