diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-06-28 08:25:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-28 08:25:38 +0200 |
commit | 16d9918b514d4d2d7fb846de8f2b1107aefab0b9 (patch) | |
tree | dfd0d8b3a50c0bedf67373677eafd0bb8f8f74c0 | |
parent | a386e59d4f4032a2311e8f127010290638b75969 (diff) | |
parent | fc6ac4a155c45181d0a3528a4891c5a12e412d1f (diff) |
Merge pull request #62467 from RandomShaper/descriptor_rw_matters
Consider uniform writability part of the interface of the set
5 files changed, 46 insertions, 8 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 99aa0e2442..f9189aacf7 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/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()) { 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; @@ -4548,8 +4548,9 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa //version 1: initial //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 { return "Vulkan-SV" + itos(SHADER_BINARY_VERSION); @@ -4560,6 +4561,7 @@ struct RenderingDeviceVulkanShaderBinaryDataBinding { uint32_t binding; uint32_t stages; uint32_t length; //size of arrays (in total elements), or ubos (in bytes * total elements) + uint32_t writable; }; 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>(), "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++) { const SpvReflectDescriptorBinding &binding = *bindings[j]; @@ -4720,6 +4734,18 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve 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; 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++) { UniformInfo info; info.type = UniformType(set_ptr[j].type); + info.writable = set_ptr[j].writable; info.length = set_ptr[j].length; info.binding = set_ptr[j].binding; info.stages = set_ptr[j].stages; diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 3b21ee67a1..2b92c74db9 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -544,12 +544,13 @@ class RenderingDeviceVulkan : public RenderingDevice { struct UniformInfo { UniformType type = UniformType::UNIFORM_TYPE_MAX; + bool writable = false; int binding = 0; uint32_t stages = 0; int length = 0; //size of arrays (in total elements), or ubos (in bytes * total elements) 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 { @@ -559,6 +560,9 @@ class RenderingDeviceVulkan : public RenderingDevice { if (type != p_info.type) { return type < p_info.type; } + if (writable != p_info.writable) { + return writable < p_info.writable; + } if (stages != p_info.stages) { return stages < p_info.stages; } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 5d8cda4f2b..eb4bc3d535 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/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)) { 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)) { 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(); } - 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 Vector<RD::Uniform> 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->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 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[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); @@ -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_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) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index c87fd6703f..3f03f857f7 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -799,6 +799,7 @@ private: RID fog_uniform_set; RID copy_uniform_set; + RID process_uniform_set_density; RID process_uniform_set; RID process_uniform_set2; RID sdfgi_uniform_set; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl index 347fd13b28..fdbd7d3e35 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/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 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 #ifdef MODE_FOG |