Browse Source

Consider uniform writability part of the interface of the set

Pedro J. Estébanez 3 years ago
parent
commit
fc6ac4a155

+ 29 - 2
drivers/vulkan/rendering_device_vulkan.cpp

@@ -4348,7 +4348,7 @@ String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) {
 			if (!ret.is_empty()) {
 			if (!ret.is_empty()) {
 				ret += "\n";
 				ret += "\n";
 			}
 			}
-			ret += "Set: " + itos(i) + " Binding: " + itos(ui.binding) + " Type: " + shader_uniform_names[ui.type] + " Length: " + itos(ui.length);
+			ret += "Set: " + itos(i) + " Binding: " + itos(ui.binding) + " Type: " + shader_uniform_names[ui.type] + " Writable: " + (ui.writable ? "Y" : "N") + " Length: " + itos(ui.length);
 		}
 		}
 	}
 	}
 	return ret;
 	return ret;
@@ -4548,8 +4548,9 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
 
 
 //version 1: initial
 //version 1: initial
 //version 2: Added shader name
 //version 2: Added shader name
+//version 3: Added writable
 
 
-#define SHADER_BINARY_VERSION 2
+#define SHADER_BINARY_VERSION 3
 
 
 String RenderingDeviceVulkan::shader_get_binary_cache_key() const {
 String RenderingDeviceVulkan::shader_get_binary_cache_key() const {
 	return "Vulkan-SV" + itos(SHADER_BINARY_VERSION);
 	return "Vulkan-SV" + itos(SHADER_BINARY_VERSION);
@@ -4560,6 +4561,7 @@ struct RenderingDeviceVulkanShaderBinaryDataBinding {
 	uint32_t binding;
 	uint32_t binding;
 	uint32_t stages;
 	uint32_t stages;
 	uint32_t length; //size of arrays (in total elements), or ubos (in bytes * total elements)
 	uint32_t length; //size of arrays (in total elements), or ubos (in bytes * total elements)
+	uint32_t writable;
 };
 };
 
 
 struct RenderingDeviceVulkanShaderBinarySpecializationConstant {
 struct RenderingDeviceVulkanShaderBinarySpecializationConstant {
@@ -4642,6 +4644,18 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
 				ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(),
 				ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(),
 						"Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");
 						"Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");
 
 
+				uint32_t interface_vars_count = 0;
+				result = spvReflectEnumerateInterfaceVariables(&module, &interface_vars_count, nullptr);
+				ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(),
+						"Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating interface variables.");
+
+				Vector<SpvReflectInterfaceVariable *> interface_vars;
+				interface_vars.resize(interface_vars_count);
+				result = spvReflectEnumerateInterfaceVariables(&module, &interface_vars_count, interface_vars.ptrw());
+
+				ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, Vector<uint8_t>(),
+						"Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed getting interface variables.");
+
 				for (uint32_t j = 0; j < binding_count; j++) {
 				for (uint32_t j = 0; j < binding_count; j++) {
 					const SpvReflectDescriptorBinding &binding = *bindings[j];
 					const SpvReflectDescriptorBinding &binding = *bindings[j];
 
 
@@ -4720,6 +4734,18 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
 						info.length = 0;
 						info.length = 0;
 					}
 					}
 
 
+					SpvReflectInterfaceVariable *interface_var = nullptr;
+					for (uint32_t k = 0; k < interface_vars_count; k++) {
+						if (interface_vars[k]->spirv_id == binding.spirv_id) {
+							interface_var = interface_vars[k];
+							break;
+						}
+					}
+					ERR_FAIL_COND_V_MSG(!interface_var, Vector<uint8_t>(),
+							"Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed finding interface variable.");
+
+					info.writable = !(bool)(interface_var->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
+
 					info.binding = binding.binding;
 					info.binding = binding.binding;
 					uint32_t set = binding.set;
 					uint32_t set = binding.set;
 
 
@@ -5087,6 +5113,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
 		for (uint32_t j = 0; j < set_count; j++) {
 		for (uint32_t j = 0; j < set_count; j++) {
 			UniformInfo info;
 			UniformInfo info;
 			info.type = UniformType(set_ptr[j].type);
 			info.type = UniformType(set_ptr[j].type);
+			info.writable = set_ptr[j].writable;
 			info.length = set_ptr[j].length;
 			info.length = set_ptr[j].length;
 			info.binding = set_ptr[j].binding;
 			info.binding = set_ptr[j].binding;
 			info.stages = set_ptr[j].stages;
 			info.stages = set_ptr[j].stages;

+ 5 - 1
drivers/vulkan/rendering_device_vulkan.h

@@ -544,12 +544,13 @@ class RenderingDeviceVulkan : public RenderingDevice {
 
 
 	struct UniformInfo {
 	struct UniformInfo {
 		UniformType type = UniformType::UNIFORM_TYPE_MAX;
 		UniformType type = UniformType::UNIFORM_TYPE_MAX;
+		bool writable = false;
 		int binding = 0;
 		int binding = 0;
 		uint32_t stages = 0;
 		uint32_t stages = 0;
 		int length = 0; //size of arrays (in total elements), or ubos (in bytes * total elements)
 		int length = 0; //size of arrays (in total elements), or ubos (in bytes * total elements)
 
 
 		bool operator!=(const UniformInfo &p_info) const {
 		bool operator!=(const UniformInfo &p_info) const {
-			return (binding != p_info.binding || type != p_info.type || stages != p_info.stages || length != p_info.length);
+			return (binding != p_info.binding || type != p_info.type || writable != p_info.writable || stages != p_info.stages || length != p_info.length);
 		}
 		}
 
 
 		bool operator<(const UniformInfo &p_info) const {
 		bool operator<(const UniformInfo &p_info) const {
@@ -559,6 +560,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
 			if (type != p_info.type) {
 			if (type != p_info.type) {
 				return type < p_info.type;
 				return type < p_info.type;
 			}
 			}
+			if (writable != p_info.writable) {
+				return writable < p_info.writable;
+			}
 			if (stages != p_info.stages) {
 			if (stages != p_info.stages) {
 				return stages < p_info.stages;
 				return stages < p_info.stages;
 			}
 			}

+ 11 - 4
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -4150,6 +4150,9 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
 	if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) {
 	if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) {
 		RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set);
 		RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set);
 	}
 	}
+	if (rb->volumetric_fog->process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) {
+		RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set_density);
+	}
 	if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
 	if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
 		RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set);
 		RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set);
 	}
 	}
@@ -4482,7 +4485,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 		RD::get_singleton()->compute_list_end();
 		RD::get_singleton()->compute_list_end();
 	}
 	}
 
 
-	if (rb->volumetric_fog->process_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
+	if (rb->volumetric_fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) {
 		//re create uniform set if needed
 		//re create uniform set if needed
 		Vector<RD::Uniform> uniforms;
 		Vector<RD::Uniform> uniforms;
 		Vector<RD::Uniform> copy_uniforms;
 		Vector<RD::Uniform> copy_uniforms;
@@ -4682,7 +4685,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 
 		rb->volumetric_fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0);
 		rb->volumetric_fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0);
 
 
-		rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
+		rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
 
 
 		RID aux7 = uniforms.write[7].get_id(0);
 		RID aux7 = uniforms.write[7].get_id(0);
 		RID aux8 = uniforms.write[8].get_id(0);
 		RID aux8 = uniforms.write[8].get_id(0);
@@ -4690,7 +4693,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 		uniforms.write[7].set_id(0, aux8);
 		uniforms.write[7].set_id(0, aux8);
 		uniforms.write[8].set_id(0, aux7);
 		uniforms.write[8].set_id(0, aux7);
 
 
-		rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, 0), 0);
+		rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
+
+		uniforms.remove_at(8);
+		uniforms.write[7].set_id(0, aux7);
+		rb->volumetric_fog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
 	}
 	}
 
 
 	bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr);
 	bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr);
@@ -4833,7 +4840,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 
 	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]);
 	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]);
 
 
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set_density, 0);
 
 
 	if (using_sdfgi) {
 	if (using_sdfgi) {
 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1);
 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1);

+ 1 - 0
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -799,6 +799,7 @@ private:
 
 
 		RID fog_uniform_set;
 		RID fog_uniform_set;
 		RID copy_uniform_set;
 		RID copy_uniform_set;
+		RID process_uniform_set_density;
 		RID process_uniform_set;
 		RID process_uniform_set;
 		RID process_uniform_set2;
 		RID process_uniform_set2;
 		RID sdfgi_uniform_set;
 		RID sdfgi_uniform_set;

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

@@ -53,7 +53,6 @@ layout(set = 0, binding = 7) uniform sampler linear_sampler;
 
 
 #ifdef MODE_DENSITY
 #ifdef MODE_DENSITY
 layout(rgba16f, set = 0, binding = 8) uniform restrict writeonly image3D density_map;
 layout(rgba16f, set = 0, binding = 8) uniform restrict writeonly image3D density_map;
-layout(rgba16f, set = 0, binding = 9) uniform restrict readonly image3D fog_map; //unused
 #endif
 #endif
 
 
 #ifdef MODE_FOG
 #ifdef MODE_FOG