diff options
Diffstat (limited to 'servers')
30 files changed, 270 insertions, 250 deletions
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 0a01d0c0b0..7aa2f9b7de 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -532,7 +532,7 @@ void Body2DSW::integrate_velocities(real_t p_step) { } void Body2DSW::wakeup_neighbours() { - for (Pair<Constraint2DSW *, int> &E : constraint_list) { + for (const Pair<Constraint2DSW *, int> &E : constraint_list) { const Constraint2DSW *c = E.first; Body2DSW **n = c->get_body_ptr(); int bc = c->get_body_count(); diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h index d46437e782..d0f3dbbd35 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -322,12 +322,12 @@ public: m_angularLimits[2].m_hiLimit = angularUpper.z; } - //! Retrieves the angular limit informacion + //! Retrieves the angular limit information. G6DOFRotationalLimitMotor3DSW *getRotationalLimitMotor(int index) { return &m_angularLimits[index]; } - //! Retrieves the limit informacion + //! Retrieves the limit information. G6DOFTranslationalLimitMotor3DSW *getTranslationalLimitMotor() { return &m_linearLimits; } diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp index db9bdb2986..1895fe1e2e 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp @@ -200,7 +200,7 @@ void SliderJoint3DSW::solve(real_t p_step) { real_t softness = (i) ? m_softnessOrthoLin : (m_solveLinLim ? m_softnessLimLin : m_softnessDirLin); real_t restitution = (i) ? m_restitutionOrthoLin : (m_solveLinLim ? m_restitutionLimLin : m_restitutionDirLin); real_t damping = (i) ? m_dampingOrthoLin : (m_solveLinLim ? m_dampingLimLin : m_dampingDirLin); - // calcutate and apply impulse + // Calculate and apply impulse. real_t normalImpulse = softness * (restitution * depth / p_step - damping * rel_vel) * m_jacLinDiagABInv[i]; Vector3 impulse_vector = normal * normalImpulse; if (dynamic_A) { diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 717b4e8d14..857f112102 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -205,7 +205,7 @@ void register_server_types() { GDREGISTER_CLASS(RDPipelineColorBlendStateAttachment); GDREGISTER_CLASS(RDPipelineColorBlendState); GDREGISTER_CLASS(RDShaderSource); - GDREGISTER_CLASS(RDShaderBytecode); + GDREGISTER_CLASS(RDShaderSPIRV); GDREGISTER_CLASS(RDShaderFile); GDREGISTER_CLASS(RDPipelineSpecializationConstant); diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h index ebb81abdad..c0c03eb26a 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.h +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -235,7 +235,7 @@ public: Transform3D xform = view_xform * p_transform; float radius = xform.basis.get_uniform_scale(); - if (radius > 0.98 || radius < 1.02) { + if (radius < 0.98 || radius > 1.02) { xform.basis.orthonormalize(); } diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 5dab066262..47bb756d55 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -1351,8 +1351,9 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) { if (pass < blur_passes - 2) { blur_pipeline = SSAO_BLUR_PASS_WIDE; + } else { + blur_pipeline = SSAO_BLUR_PASS_SMART; } - blur_pipeline = SSAO_BLUR_PASS_SMART; } for (int i = 0; i < 4; i++) { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 6d1c408a32..5f6d9465c7 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -160,12 +160,12 @@ bool RenderForwardMobile::free(RID p_rid) { /* Render functions */ RD::DataFormat RenderForwardMobile::_render_buffers_get_color_format() { - // Using 32bit buffers enables AFBC on mobile devices which should have a definate performance improvement (MALI G710 and newer support this on 64bit RTs) + // Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs) return RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; } bool RenderForwardMobile::_render_buffers_can_be_storage() { - // Using 32bit buffers enables AFBC on mobile devices which should have a definate performance improvement (MALI G710 and newer support this on 64bit RTs) + // Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs) // Doesn't support storage return false; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 6a66e9fa01..18c1fe02a0 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -620,7 +620,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array); RD::get_singleton()->draw_list_draw(p_draw_list, true); - //restore if overrided + // Restore if overridden. push_constant.color_texture_pixel_size[0] = texpixel_size.x; push_constant.color_texture_pixel_size[1] = texpixel_size.y; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 02f3a01ec3..2e0e7c3c43 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2250,7 +2250,7 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() { } void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) { - ERR_FAIL_COND_MSG(p_view_count == 0, "Must have atleast 1 view"); + ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view"); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 178fb60885..d5c7db6fd2 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -8410,7 +8410,7 @@ void RendererStorageRD::global_variables_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); - for (PropertyInfo &E : settings) { + for (const PropertyInfo &E : settings) { if (E.name.begins_with("shader_globals/")) { StringName name = E.name.get_slice("/", 1); Dictionary d = ProjectSettings::get_singleton()->get(E.name); @@ -8581,7 +8581,7 @@ void RendererStorageRD::_update_global_variables() { if (global_variables.must_update_buffer_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (RID E : global_variables.materials_using_buffer) { + for (const RID &E : global_variables.materials_using_buffer) { Material *material = material_owner.getornull(E); ERR_CONTINUE(!material); //wtf @@ -8594,7 +8594,7 @@ void RendererStorageRD::_update_global_variables() { if (global_variables.must_update_texture_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (RID E : global_variables.materials_using_texture) { + for (const RID &E : global_variables.materials_using_texture) { Material *material = material_owner.getornull(E); ERR_CONTINUE(!material); //wtf diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 8c4070562e..9c1068ea2e 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -571,7 +571,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge max_texture_uniforms++; } else { if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; //instances are indexed directly, dont need index uniforms + continue; // Instances are indexed directly, don't need index uniforms. } max_uniforms++; @@ -605,7 +605,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (uniform.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { //insert, but don't generate any code. p_actions.uniforms->insert(uniform_name, uniform); - continue; //instances are indexed directly, dont need index uniforms + continue; // Instances are indexed directly, don't need index uniforms. } if (SL::is_sampler_type(uniform.type)) { ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_order) + ") uniform "; @@ -760,7 +760,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (var_frag_to_light.size() > 0) { String gcode = "\n\nstruct {\n"; - for (Pair<StringName, SL::ShaderNode::Varying> &E : var_frag_to_light) { + for (const Pair<StringName, SL::ShaderNode::Varying> &E : var_frag_to_light) { gcode += "\t" + _prestr(E.second.precision) + _typestr(E.second.type) + " " + _mkid(E.first); if (E.second.array_size > 0) { gcode += "["; @@ -1394,7 +1394,7 @@ void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) { ShaderLanguage::get_builtin_funcs(&func_list); - for (String &E : func_list) { + for (const String &E : func_list) { internal_functions.insert(E); } texture_functions.insert("texture"); diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 27305cc938..1b9f54d1c8 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -116,8 +116,10 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con } StringBuilder tohash; - tohash.append("[VersionKey]"); - tohash.append(RenderingDevice::get_singleton()->shader_get_cache_key()); + tohash.append("[SpirvCacheKey]"); + tohash.append(RenderingDevice::get_singleton()->shader_get_spirv_cache_key()); + tohash.append("[BinaryCacheKey]"); + tohash.append(RenderingDevice::get_singleton()->shader_get_binary_cache_key()); tohash.append("[Vertex]"); tohash.append(p_vertex_code ? p_vertex_code : ""); tohash.append("[Fragment]"); @@ -148,8 +150,8 @@ void ShaderRD::_clear_version(Version *p_version) { } memdelete_arr(p_version->variants); - if (p_version->variant_stages) { - memdelete_arr(p_version->variant_stages); + if (p_version->variant_data) { + memdelete_arr(p_version->variant_data); } p_version->variants = nullptr; } @@ -203,7 +205,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { return; //variant is disabled, return } - Vector<RD::ShaderStageData> &stages = p_version->variant_stages[p_variant]; + Vector<RD::ShaderStageSPIRVData> stages; String error; String current_source; @@ -217,8 +219,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_VERTEX]); current_source = builder.as_string(); - RD::ShaderStageData stage; - stage.spir_v = RD::get_singleton()->shader_compile_from_source(RD::SHADER_STAGE_VERTEX, current_source, RD::SHADER_LANGUAGE_GLSL, &error); + RD::ShaderStageSPIRVData stage; + stage.spir_v = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_VERTEX, current_source, RD::SHADER_LANGUAGE_GLSL, &error); if (stage.spir_v.size() == 0) { build_ok = false; } else { @@ -235,8 +237,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT]); current_source = builder.as_string(); - RD::ShaderStageData stage; - stage.spir_v = RD::get_singleton()->shader_compile_from_source(RD::SHADER_STAGE_FRAGMENT, current_source, RD::SHADER_LANGUAGE_GLSL, &error); + RD::ShaderStageSPIRVData stage; + stage.spir_v = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_FRAGMENT, current_source, RD::SHADER_LANGUAGE_GLSL, &error); if (stage.spir_v.size() == 0) { build_ok = false; } else { @@ -254,8 +256,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { current_source = builder.as_string(); - RD::ShaderStageData stage; - stage.spir_v = RD::get_singleton()->shader_compile_from_source(RD::SHADER_STAGE_COMPUTE, current_source, RD::SHADER_LANGUAGE_GLSL, &error); + RD::ShaderStageSPIRVData stage; + stage.spir_v = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_COMPUTE, current_source, RD::SHADER_LANGUAGE_GLSL, &error); if (stage.spir_v.size() == 0) { build_ok = false; } else { @@ -275,10 +277,15 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { return; } - RID shader = RD::get_singleton()->shader_create(stages); + Vector<uint8_t> shader_data = RD::get_singleton()->shader_compile_binary_from_spirv(stages); + + ERR_FAIL_COND(shader_data.size() == 0); + + RID shader = RD::get_singleton()->shader_create_from_bytecode(shader_data); { MutexLock lock(variant_set_mutex); p_version->variants[p_variant] = shader; + p_version->variant_data[p_variant] = shader_data; } } @@ -364,14 +371,12 @@ String ShaderRD::_version_get_sha1(Version *p_version) const { } static const char *shader_file_header = "GDSC"; -static const uint32_t cache_file_version = 1; +static const uint32_t cache_file_version = 2; bool ShaderRD::_load_from_cache(Version *p_version) { String sha1 = _version_get_sha1(p_version); String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; - uint64_t time_from = OS::get_singleton()->get_ticks_usec(); - FileAccessRef f = FileAccess::open(path, FileAccess::READ); if (!f) { return false; @@ -390,76 +395,43 @@ bool ShaderRD::_load_from_cache(Version *p_version) { ERR_FAIL_COND_V(variant_count != (uint32_t)variant_defines.size(), false); //should not happen but check - bool success = true; for (uint32_t i = 0; i < variant_count; i++) { - uint32_t stage_count = f->get_32(); - p_version->variant_stages[i].resize(stage_count); - for (uint32_t j = 0; j < stage_count; j++) { - p_version->variant_stages[i].write[j].shader_stage = RD::ShaderStage(f->get_32()); - - int compression = f->get_32(); - uint32_t length = f->get_32(); - - if (compression == 0) { - Vector<uint8_t> data; - data.resize(length); - - f->get_buffer(data.ptrw(), length); - - p_version->variant_stages[i].write[j].spir_v = data; - } else { - Vector<uint8_t> data; - - if (compression == 2) { - //zstd - int smol_length = f->get_32(); - Vector<uint8_t> zstd_data; - - zstd_data.resize(smol_length); - f->get_buffer(zstd_data.ptrw(), smol_length); - - data.resize(length); - Compression::decompress(data.ptrw(), data.size(), zstd_data.ptr(), zstd_data.size(), Compression::MODE_ZSTD); - - } else { - data.resize(length); - f->get_buffer(data.ptrw(), length); - } - - Vector<uint8_t> spirv; - uint32_t spirv_size = smolv::GetDecodedBufferSize(data.ptr(), data.size()); - spirv.resize(spirv_size); - if (!smolv::Decode(data.ptr(), data.size(), spirv.ptrw(), spirv_size)) { - ERR_PRINT("Malformed smolv input uncompressing shader " + name + ", variant #" + itos(i) + " stage :" + itos(j)); - success = false; - break; - } - p_version->variant_stages[i].write[j].spir_v = spirv; - } + uint32_t variant_size = f->get_32(); + ERR_FAIL_COND_V(variant_size == 0 && variants_enabled[i], false); + if (!variants_enabled[i]) { + continue; } - } + Vector<uint8_t> variant_bytes; + variant_bytes.resize(variant_size); - if (!success) { - for (uint32_t i = 0; i < variant_count; i++) { - p_version->variant_stages[i].resize(0); - } - return false; - } + uint32_t br = f->get_buffer(variant_bytes.ptrw(), variant_size); - float time_ms = double(OS::get_singleton()->get_ticks_usec() - time_from) / 1000.0; + ERR_FAIL_COND_V(br != variant_size, false); - print_verbose("Shader cache load success '" + path + "' " + rtos(time_ms) + "ms."); + p_version->variant_data[i] = variant_bytes; + } for (uint32_t i = 0; i < variant_count; i++) { - RID shader = RD::get_singleton()->shader_create(p_version->variant_stages[i]); + if (!variants_enabled[i]) { + MutexLock lock(variant_set_mutex); + p_version->variants[i] = RID(); + continue; + } + RID shader = RD::get_singleton()->shader_create_from_bytecode(p_version->variant_data[i]); + if (shader.is_null()) { + for (uint32_t j = 0; j < i; j++) { + RD::get_singleton()->free(p_version->variants[i]); + } + ERR_FAIL_COND_V(shader.is_null(), false); + } { MutexLock lock(variant_set_mutex); p_version->variants[i] = shader; } } - memdelete_arr(p_version->variant_stages); //clear stages - p_version->variant_stages = nullptr; + memdelete_arr(p_version->variant_data); //clear stages + p_version->variant_data = nullptr; p_version->valid = true; return true; } @@ -476,49 +448,8 @@ void ShaderRD::_save_to_cache(Version *p_version) { f->store_32(variant_count); //variant count for (uint32_t i = 0; i < variant_count; i++) { - f->store_32(p_version->variant_stages[i].size()); //stage count - for (int j = 0; j < p_version->variant_stages[i].size(); j++) { - f->store_32(p_version->variant_stages[i][j].shader_stage); //stage count - Vector<uint8_t> spirv = p_version->variant_stages[i][j].spir_v; - - bool save_uncompressed = true; - if (shader_cache_save_compressed) { - smolv::ByteArray smolv; - bool strip_debug = !shader_cache_save_debug; - if (!smolv::Encode(spirv.ptr(), spirv.size(), smolv, strip_debug ? smolv::kEncodeFlagStripDebugInfo : 0)) { - ERR_PRINT("Error compressing shader " + name + ", variant #" + itos(i) + " stage :" + itos(i)); - } else { - bool compress_zstd = shader_cache_save_compressed_zstd; - - if (compress_zstd) { - Vector<uint8_t> zstd; - zstd.resize(Compression::get_max_compressed_buffer_size(smolv.size(), Compression::MODE_ZSTD)); - int dst_size = Compression::compress(zstd.ptrw(), &smolv[0], smolv.size(), Compression::MODE_ZSTD); - if (dst_size >= 0 && (uint32_t)dst_size < smolv.size()) { - f->store_32(2); //compressed zstd - f->store_32(smolv.size()); //size of smolv buffer - f->store_32(dst_size); //size of smolv buffer - f->store_buffer(zstd.ptr(), dst_size); //smolv buffer - } else { - compress_zstd = false; - } - } - - if (!compress_zstd) { - f->store_32(1); //compressed - f->store_32(smolv.size()); //size of smolv buffer - f->store_buffer(&smolv[0], smolv.size()); //smolv buffer - } - save_uncompressed = false; - } - } - - if (save_uncompressed) { - f->store_32(0); //uncompressed - f->store_32(spirv.size()); //stage count - f->store_buffer(spirv.ptr(), spirv.size()); //stage count - } - } + f->store_32(p_version->variant_data[i].size()); //stage count + f->store_buffer(p_version->variant_data[i].ptr(), p_version->variant_data[i].size()); } f->close(); @@ -531,8 +462,8 @@ void ShaderRD::_compile_version(Version *p_version) { p_version->dirty = false; p_version->variants = memnew_arr(RID, variant_defines.size()); - typedef Vector<RD::ShaderStageData> ShaderStageArray; - p_version->variant_stages = memnew_arr(ShaderStageArray, variant_defines.size()); + typedef Vector<uint8_t> ShaderStageData; + p_version->variant_data = memnew_arr(ShaderStageData, variant_defines.size()); if (shader_cache_dir_valid) { if (_load_from_cache(p_version)) { @@ -571,19 +502,19 @@ void ShaderRD::_compile_version(Version *p_version) { } } memdelete_arr(p_version->variants); - if (p_version->variant_stages) { - memdelete_arr(p_version->variant_stages); + if (p_version->variant_data) { + memdelete_arr(p_version->variant_data); } p_version->variants = nullptr; - p_version->variant_stages = nullptr; + p_version->variant_data = nullptr; return; } else if (shader_cache_dir_valid) { //save shader cache _save_to_cache(p_version); } - memdelete_arr(p_version->variant_stages); //clear stages - p_version->variant_stages = nullptr; + memdelete_arr(p_version->variant_data); //clear stages + p_version->variant_data = nullptr; p_version->valid = true; } diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index 9a68e02007..529328f0ed 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -59,7 +59,7 @@ class ShaderRD { Map<StringName, CharString> code_sections; Vector<CharString> custom_defines; - Vector<RD::ShaderStageData> *variant_stages = nullptr; + Vector<uint8_t> *variant_data = nullptr; RID *variants = nullptr; //same size as version defines bool valid; diff --git a/servers/rendering/renderer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index 4dceeea995..e88e68b511 100644 --- a/servers/rendering/renderer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl @@ -138,7 +138,7 @@ void main() { if (bool(particles.data[particle].flags & PARTICLE_FLAG_ACTIVE) || bool(particles.data[particle].flags & PARTICLE_FLAG_TRAILED)) { txform = particles.data[particle].xform; if (params.trail_size > 1) { - // since the steps dont fit precisely in the history frames, must do a tiny bit of + // Since the steps don't fit precisely in the history frames, must do a tiny bit of // interpolation to get them close to their intended location. uint part_ofs = particle % params.trail_size; float natural_ofs = fract((float(part_ofs) / float(params.trail_size)) * float(params.trail_total)) * params.frame_delta; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index ef1c9bacfb..b3a349c948 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -1214,7 +1214,7 @@ void main() { specular_light *= specular * metallic * albedo * 2.0; #else - // scales the specular reflections, needs to be be computed before lighting happens, + // scales the specular reflections, needs to be computed before lighting happens, // but after environment, GI, and reflection probes are added // Environment brdf approximation (Lazarov 2013) // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index 3a05275652..b53bf6a6d4 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -177,7 +177,7 @@ layout(set = 1, binding = 0, std140) uniform SceneData { uint cluster_type_size; uint max_cluster_element_count_div_32; - //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. vec4 directional_penumbra_shadow_kernel[32]; vec4 directional_soft_shadow_kernel[32]; vec4 penumbra_shadow_kernel[32]; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 7e72ece5dc..70900a847c 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -981,7 +981,7 @@ void main() { specular_light *= specular * metallic * albedo * 2.0; #else - // scales the specular reflections, needs to be be computed before lighting happens, + // scales the specular reflections, needs to be computed before lighting happens, // but after environment, GI, and reflection probes are added // Environment brdf approximation (Lazarov 2013) // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index 1b8e21551c..d9682d7b23 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -138,7 +138,7 @@ layout(set = 1, binding = 0, std140) uniform SceneData { vec2 viewport_size; vec2 screen_pixel_size; - //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. vec4 directional_penumbra_shadow_kernel[32]; vec4 directional_soft_shadow_kernel[32]; vec4 penumbra_shadow_kernel[32]; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index 99db35bb34..d6e5c6a92e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -20,10 +20,10 @@ layout(set = 0, binding = 3, std430) restrict readonly buffer DispatchData { dispatch_data; struct ProcessVoxel { - uint position; //xyz 7 bit packed, extra 11 bits for neigbours - uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours - uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours - uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours + uint position; // xyz 7 bit packed, extra 11 bits for neighbors. + uint albedo; // rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors. + uint light; // rgbe8985 encoded total saved light, extra 2 bits for neighbors. + uint light_aniso; // 55555 light anisotropy, extra 2 bits for neighbors. //total neighbours: 26 }; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index bc376e9522..eedd28959c 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl @@ -266,9 +266,9 @@ void main() { } else if (params.sky_mode == SKY_MODE_SKY) { #ifdef USE_CUBEMAP_ARRAY - light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates + light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates. #else - light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates + light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates. #endif light.rgb *= params.sky_energy; light.a = 0.0; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl index aa4ded146f..4d9fa85a74 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl @@ -101,7 +101,7 @@ layout(set = 0, binding = 10, std430) restrict buffer DispatchData { dispatch_data; struct ProcessVoxel { - uint position; //xyz 7 bit packed, extra 11 bits for neigbours + uint position; // xyz 7 bit packed, extra 11 bits for neighbors. uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours @@ -134,7 +134,7 @@ layout(set = 0, binding = 5, std430) restrict buffer readonly DispatchData { dispatch_data; struct ProcessVoxel { - uint position; //xyz 7 bit packed, extra 11 bits for neigbours + uint position; // xyz 7 bit packed, extra 11 bits for neighbors. uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours @@ -183,7 +183,7 @@ void main() { ivec3 write_pos = read_pos + params.scroll; if (any(lessThan(write_pos, ivec3(0))) || any(greaterThanEqual(write_pos, ivec3(params.grid_size)))) { - return; //fits outside the 3D texture, dont do anything + return; // Fits outside the 3D texture, don't do anything. } uint albedo = ((src_process_voxels.data[index].albedo & 0x7FFF) << 1) | 1; //add solid bit diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 2ade8454bb..83d1b33bf2 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1259,7 +1259,7 @@ void RendererSceneCull::_update_instance_visibility_depth(Instance *p_instance) } if (cycle_detected) { - ERR_PRINT("Cycle detected in the visibility dependecies tree."); + ERR_PRINT("Cycle detected in the visibility dependencies tree."); for (Set<Instance *>::Element *E = traversed_nodes.front(); E; E = E->next()) { Instance *instance = E->get(); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); @@ -3391,7 +3391,7 @@ void RendererSceneCull::render_probes() { idx++; } - for (Instance *instance : probe->owner->scenario->directional_lights) { + for (const Instance *instance : probe->owner->scenario->directional_lights) { InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { continue; @@ -3464,7 +3464,7 @@ void RendererSceneCull::render_probes() { idx++; } - for (Instance *instance : probe->owner->scenario->directional_lights) { + for (const Instance *instance : probe->owner->scenario->directional_lights) { InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { continue; @@ -3571,7 +3571,7 @@ void RendererSceneCull::render_particle_colliders() { void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { List<RendererStorage::InstanceShaderParam> plist; RSG::storage->material_get_instance_shader_parameters(p_material, &plist); - for (RendererStorage::InstanceShaderParam &E : plist) { + for (const RendererStorage::InstanceShaderParam &E : plist) { StringName name = E.info.name; if (isparams.has(name)) { if (isparams[name].info.type != E.info.type) { diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 3594939362..b298ad193b 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -38,23 +38,23 @@ RenderingDevice *RenderingDevice::get_singleton() { return singleton; } -RenderingDevice::ShaderCompileFunction RenderingDevice::compile_function = nullptr; +RenderingDevice::ShaderCompileToSPIRVFunction RenderingDevice::compile_to_spirv_function = nullptr; RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = nullptr; -RenderingDevice::ShaderGetCacheKeyFunction RenderingDevice::get_cache_key_function = nullptr; +RenderingDevice::ShaderSPIRVGetCacheKeyFunction RenderingDevice::get_spirv_cache_key_function = nullptr; -void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) { - compile_function = p_function; +void RenderingDevice::shader_set_compile_to_spirv_function(ShaderCompileToSPIRVFunction p_function) { + compile_to_spirv_function = p_function; } -void RenderingDevice::shader_set_cache_function(ShaderCacheFunction p_function) { +void RenderingDevice::shader_set_spirv_cache_function(ShaderCacheFunction p_function) { cache_function = p_function; } -void RenderingDevice::shader_set_get_cache_key_function(ShaderGetCacheKeyFunction p_function) { - get_cache_key_function = p_function; +void RenderingDevice::shader_set_get_cache_key_function(ShaderSPIRVGetCacheKeyFunction p_function) { + get_spirv_cache_key_function = p_function; } -Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, bool p_allow_cache) { +Vector<uint8_t> RenderingDevice::shader_compile_spirv_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, bool p_allow_cache) { if (p_allow_cache && cache_function) { Vector<uint8_t> cache = cache_function(p_stage, p_source_code, p_language); if (cache.size()) { @@ -62,18 +62,24 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, } } - ERR_FAIL_COND_V(!compile_function, Vector<uint8_t>()); + ERR_FAIL_COND_V(!compile_to_spirv_function, Vector<uint8_t>()); - return compile_function(p_stage, p_source_code, p_language, r_error, &device_capabilities); + return compile_to_spirv_function(p_stage, p_source_code, p_language, r_error, &device_capabilities); } -String RenderingDevice::shader_get_cache_key() const { - if (get_cache_key_function) { - return get_cache_key_function(&device_capabilities); +String RenderingDevice::shader_get_spirv_cache_key() const { + if (get_spirv_cache_key_function) { + return get_spirv_cache_key_function(&device_capabilities); } return String(); } +RID RenderingDevice::shader_create_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv) { + Vector<uint8_t> bytecode = shader_compile_binary_from_spirv(p_spirv); + ERR_FAIL_COND_V(bytecode.size() == 0, RID()); + return shader_create_from_bytecode(bytecode); +} + RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) { ERR_FAIL_COND_V(p_format.is_null(), RID()); ERR_FAIL_COND_V(p_view.is_null(), RID()); @@ -170,40 +176,59 @@ RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatI return vertex_array_create(p_vertex_count, p_vertex_format, buffers); } -Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { - ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>()); +Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { + ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderSPIRV>()); - Ref<RDShaderBytecode> bytecode; + Ref<RDShaderSPIRV> bytecode; bytecode.instantiate(); for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { String error; ShaderStage stage = ShaderStage(i); - Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache); + Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache); bytecode->set_stage_bytecode(stage, spirv); bytecode->set_stage_compile_error(stage, error); } return bytecode; } -RID RenderingDevice::shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode) { - ERR_FAIL_COND_V(p_bytecode.is_null(), RID()); +Vector<uint8_t> RenderingDevice::_shader_compile_binary_from_spirv(const Ref<RDShaderSPIRV> &p_spirv) { + ERR_FAIL_COND_V(p_spirv.is_null(), Vector<uint8_t>()); - Vector<ShaderStageData> stage_data; + Vector<ShaderStageSPIRVData> stage_data; for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { ShaderStage stage = ShaderStage(i); - ShaderStageData sd; + ShaderStageSPIRVData sd; sd.shader_stage = stage; - String error = p_bytecode->get_stage_compile_error(stage); - ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); - sd.spir_v = p_bytecode->get_stage_bytecode(stage); + String error = p_spirv->get_stage_compile_error(stage); + ERR_FAIL_COND_V_MSG(error != String(), Vector<uint8_t>(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); + sd.spir_v = p_spirv->get_stage_bytecode(stage); if (sd.spir_v.is_empty()) { continue; } stage_data.push_back(sd); } - return shader_create(stage_data); + return shader_compile_binary_from_spirv(stage_data); +} + +RID RenderingDevice::_shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv) { + ERR_FAIL_COND_V(p_spirv.is_null(), RID()); + + Vector<ShaderStageSPIRVData> stage_data; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + ShaderStage stage = ShaderStage(i); + ShaderStageSPIRVData sd; + sd.shader_stage = stage; + String error = p_spirv->get_stage_compile_error(stage); + ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); + sd.spir_v = p_spirv->get_stage_bytecode(stage); + if (sd.spir_v.is_empty()) { + continue; + } + stage_data.push_back(sd); + } + return shader_create_from_spirv(stage_data); } RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { @@ -366,8 +391,10 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); - ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::shader_create_from_bytecode); + ClassDB::bind_method(D_METHOD("shader_compile_spirv_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_spirv_from_source, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("shader_compile_binary_from_spirv", "spirv_data"), &RenderingDevice::_shader_compile_binary_from_spirv); + ClassDB::bind_method(D_METHOD("shader_create_from_spirv", "spirv_data"), &RenderingDevice::_shader_compile_binary_from_spirv); + ClassDB::bind_method(D_METHOD("shader_create_from_bytecode", "binary_data"), &RenderingDevice::shader_create_from_bytecode); ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 9a154ef7e9..eaf1ace798 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -41,7 +41,7 @@ class RDAttachmentFormat; class RDSamplerState; class RDVertexAttribute; class RDShaderSource; -class RDShaderBytecode; +class RDShaderSPIRV; class RDUniforms; class RDPipelineRasterizationState; class RDPipelineMultisampleState; @@ -105,14 +105,14 @@ public: bool supports_multiview = false; // If true this device supports multiview options }; - typedef String (*ShaderGetCacheKeyFunction)(const Capabilities *p_capabilities); - typedef Vector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities); + typedef String (*ShaderSPIRVGetCacheKeyFunction)(const Capabilities *p_capabilities); + typedef Vector<uint8_t> (*ShaderCompileToSPIRVFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities); typedef Vector<uint8_t> (*ShaderCacheFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language); private: - static ShaderCompileFunction compile_function; + static ShaderCompileToSPIRVFunction compile_to_spirv_function; static ShaderCacheFunction cache_function; - static ShaderGetCacheKeyFunction get_cache_key_function; + static ShaderSPIRVGetCacheKeyFunction get_spirv_cache_key_function; static RenderingDevice *singleton; @@ -651,24 +651,28 @@ public: const Capabilities *get_device_capabilities() const { return &device_capabilities; }; - virtual Vector<uint8_t> shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = nullptr, bool p_allow_cache = true); - virtual String shader_get_cache_key() const; + virtual Vector<uint8_t> shader_compile_spirv_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = nullptr, bool p_allow_cache = true); + virtual String shader_get_spirv_cache_key() const; - static void shader_set_compile_function(ShaderCompileFunction p_function); - static void shader_set_cache_function(ShaderCacheFunction p_function); - static void shader_set_get_cache_key_function(ShaderGetCacheKeyFunction p_function); + static void shader_set_compile_to_spirv_function(ShaderCompileToSPIRVFunction p_function); + static void shader_set_spirv_cache_function(ShaderCacheFunction p_function); + static void shader_set_get_cache_key_function(ShaderSPIRVGetCacheKeyFunction p_function); - struct ShaderStageData { + struct ShaderStageSPIRVData { ShaderStage shader_stage; Vector<uint8_t> spir_v; - ShaderStageData() { + ShaderStageSPIRVData() { shader_stage = SHADER_STAGE_VERTEX; } }; - RID shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode); - virtual RID shader_create(const Vector<ShaderStageData> &p_stages) = 0; + virtual String shader_get_binary_cache_key() const = 0; + virtual Vector<uint8_t> shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv) = 0; + + virtual RID shader_create_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv); + virtual RID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary) = 0; + virtual uint32_t shader_get_vertex_input_attribute_mask(RID p_shader) = 0; /******************/ @@ -1194,7 +1198,9 @@ protected: VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats); RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers); - Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); + Ref<RDShaderSPIRV> _shader_compile_spirv_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); + Vector<uint8_t> _shader_compile_binary_from_spirv(const Ref<RDShaderSPIRV> &p_bytecode); + RID _shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv); RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp index 2652edb1bc..fa3f2f3895 100644 --- a/servers/rendering/rendering_device_binds.cpp +++ b/servers/rendering/rendering_device_binds.cpp @@ -172,7 +172,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String /* STEP 2, Compile the versions, add to shader file */ for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { - Ref<RDShaderBytecode> bytecode; + Ref<RDShaderSPIRV> bytecode; bytecode.instantiate(); for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { @@ -182,7 +182,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String } code = code.replace("VERSION_DEFINES", E->get()); String error; - Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); + Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_spirv_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv); if (error != "") { error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n"; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index df1b40974f..ccc3e2fb39 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -263,8 +263,8 @@ protected: } }; -class RDShaderBytecode : public Resource { - GDCLASS(RDShaderBytecode, Resource) +class RDShaderSPIRV : public Resource { + GDCLASS(RDShaderSPIRV, Resource) Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX]; String compile_error[RD::SHADER_STAGE_MAX]; @@ -280,6 +280,19 @@ public: return bytecode[p_stage]; } + Vector<RD::ShaderStageSPIRVData> get_stages() const { + Vector<RD::ShaderStageSPIRVData> stages; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (bytecode[i].size()) { + RD::ShaderStageSPIRVData stage; + stage.shader_stage = RD::ShaderStage(i); + stage.spir_v = bytecode[i]; + stages.push_back(stage); + } + } + return stages; + } + void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) { ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); compile_error[p_stage] = p_compile_error; @@ -292,11 +305,11 @@ public: protected: static void _bind_methods() { - ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode); - ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode); + ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderSPIRV::set_stage_bytecode); + ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderSPIRV::get_stage_bytecode); - ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error); - ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error); + ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderSPIRV::set_stage_compile_error); + ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderSPIRV::get_stage_compile_error); ADD_GROUP("Bytecode", "bytecode_"); ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX); @@ -316,24 +329,29 @@ protected: class RDShaderFile : public Resource { GDCLASS(RDShaderFile, Resource) - Map<StringName, Ref<RDShaderBytecode>> versions; + Map<StringName, Ref<RDShaderSPIRV>> versions; String base_error; public: - void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) { + void set_bytecode(const Ref<RDShaderSPIRV> &p_bytecode, const StringName &p_version = StringName()) { ERR_FAIL_COND(p_bytecode.is_null()); versions[p_version] = p_bytecode; emit_changed(); } - Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const { - ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>()); + Ref<RDShaderSPIRV> get_spirv(const StringName &p_version = StringName()) const { + ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderSPIRV>()); return versions[p_version]; } + Vector<RD::ShaderStageSPIRVData> get_spirv_stages(const StringName &p_version = StringName()) const { + ERR_FAIL_COND_V(!versions.has(p_version), Vector<RD::ShaderStageSPIRVData>()); + return versions[p_version]->get_stages(); + } + Vector<StringName> get_version_list() const { Vector<StringName> vnames; - for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + for (Map<StringName, Ref<RDShaderSPIRV>>::Element *E = versions.front(); E; E = E->next()) { vnames.push_back(E->key()); } vnames.sort_custom<StringName::AlphCompare>(); @@ -353,7 +371,7 @@ public: if (base_error != "") { ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error); } else { - for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + for (Map<StringName, Ref<RDShaderSPIRV>>::Element *E = versions.front(); E; E = E->next()) { for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { String error = E->get()->get_stage_compile_error(RD::ShaderStage(i)); if (error != String()) { @@ -388,9 +406,9 @@ protected: versions.clear(); List<Variant> keys; p_versions.get_key_list(&keys); - for (Variant &E : keys) { + for (const Variant &E : keys) { StringName name = E; - Ref<RDShaderBytecode> bc = p_versions[E]; + Ref<RDShaderSPIRV> bc = p_versions[E]; ERR_CONTINUE(bc.is_null()); versions[name] = bc; } @@ -400,7 +418,7 @@ protected: static void _bind_methods() { ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName())); - ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_spirv", "version"), &RDShaderFile::get_spirv, DEFVAL(StringName())); ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list); ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error); diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 2db246c31f..baa5381554 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -912,6 +912,8 @@ void ShaderLanguage::clear() { completion_class = SubClassTag::TAG_GLOBAL; completion_struct = StringName(); + unknown_varying_usages.clear(); + #ifdef DEBUG_ENABLED used_constants.clear(); used_varyings.clear(); @@ -2818,6 +2820,20 @@ bool ShaderLanguage::is_token_operator(TokenType p_type) { p_type == TK_COLON); } +bool ShaderLanguage::is_token_operator_assign(TokenType p_type) { + return (p_type == TK_OP_ASSIGN || + p_type == TK_OP_ASSIGN_ADD || + p_type == TK_OP_ASSIGN_SUB || + p_type == TK_OP_ASSIGN_MUL || + p_type == TK_OP_ASSIGN_DIV || + p_type == TK_OP_ASSIGN_MOD || + p_type == TK_OP_ASSIGN_SHIFT_LEFT || + p_type == TK_OP_ASSIGN_SHIFT_RIGHT || + p_type == TK_OP_ASSIGN_BIT_AND || + p_type == TK_OP_ASSIGN_BIT_OR || + p_type == TK_OP_ASSIGN_BIT_XOR); +} + bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) { if (p_constant->datatype == p_to_type) { if (p_value) { @@ -3324,8 +3340,7 @@ bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, St p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT; } break; - case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT: - case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT: + case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT: case ShaderNode::Varying::STAGE_VERTEX: if (current_function == varying_function_names.fragment) { *r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'."); @@ -3348,13 +3363,14 @@ bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, St bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, String *r_message) { switch (p_varying.stage) { case ShaderNode::Varying::STAGE_UNKNOWN: - *r_message = RTR("Varying must be assigned before using!"); - return false; + VaryingUsage usage; + usage.var = &p_varying; + usage.line = tk_line; + unknown_varying_usages.push_back(usage); + break; case ShaderNode::Varying::STAGE_VERTEX: - if (current_function == varying_function_names.fragment) { - p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT; - } else if (current_function == varying_function_names.light) { - p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT; + if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT; } break; case ShaderNode::Varying::STAGE_FRAGMENT: @@ -3362,24 +3378,25 @@ bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, Str p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT; } break; - case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT: - if (current_function == varying_function_names.light) { - *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); - return false; - } - break; - case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT: - if (current_function == varying_function_names.fragment) { - *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); - return false; - } - break; default: break; } return true; } +bool ShaderLanguage::_check_varying_usages(int *r_error_line, String *r_error_message) const { + for (const List<ShaderLanguage::VaryingUsage>::Element *E = unknown_varying_usages.front(); E; E = E->next()) { + ShaderNode::Varying::Stage stage = E->get().var->stage; + if (stage != ShaderNode::Varying::STAGE_UNKNOWN && stage != ShaderNode::Varying::STAGE_VERTEX && stage != ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT) { + *r_error_line = E->get().line; + *r_error_message = RTR("Fragment-stage varying could not been accessed in custom function!"); + return false; + } + } + + return true; +} + bool ShaderLanguage::_check_node_constness(const Node *p_node) const { switch (p_node->type) { case Node::TYPE_OPERATOR: { @@ -4237,7 +4254,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Token next_token = _get_token(); _set_tkpos(prev_pos); String error; - if (next_token.type == TK_OP_ASSIGN) { + + if (is_token_operator_assign(next_token.type)) { if (!_validate_varying_assign(shader->varyings[identifier], &error)) { _set_error(error); return nullptr; @@ -4448,7 +4466,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons String member_name = String(ident.ptr()); if (shader->structs.has(st)) { StructNode *n = shader->structs[st].shader_struct; - for (MemberNode *E : n->members) { + for (const MemberNode *E : n->members) { if (String(E->name) == member_name) { member_type = E->datatype; array_size = E->array_size; @@ -4778,10 +4796,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons String member_struct_name; if (expr->get_array_size() > 0) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= (uint32_t)expr->get_array_size()) { - _set_error(vformat("Index [%s] out of range [%s..%s]", index_constant, 0, expr->get_array_size() - 1)); - return nullptr; + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= (uint32_t)expr->get_array_size()) { + _set_error(vformat("Index [%s] out of range [%s..%s]", index_constant, 0, expr->get_array_size() - 1)); + return nullptr; + } } member_type = expr->get_datatype(); if (member_type == TYPE_STRUCT) { @@ -7875,6 +7895,15 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); } + + int error_line; + String error_message; + if (!_check_varying_usages(&error_line, &error_message)) { + _set_tkpos({ 0, error_line }); + _set_error(error_message); + return ERR_PARSE_ERROR; + } + return OK; } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index a91fa57a8e..c02d6c47ec 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -646,10 +646,9 @@ public: struct Varying { enum Stage { STAGE_UNKNOWN, - STAGE_VERTEX, // transition stage to STAGE_VERTEX_TO_FRAGMENT or STAGE_VERTEX_TO_LIGHT, emits error if they are not used - STAGE_FRAGMENT, // transition stage to STAGE_FRAGMENT_TO_LIGHT, emits error if it's not used - STAGE_VERTEX_TO_FRAGMENT, - STAGE_VERTEX_TO_LIGHT, + STAGE_VERTEX, // transition stage to STAGE_VERTEX_TO_FRAGMENT_LIGHT, emits warning if it's not used + STAGE_FRAGMENT, // transition stage to STAGE_FRAGMENT_TO_LIGHT, emits warning if it's not used + STAGE_VERTEX_TO_FRAGMENT_LIGHT, STAGE_FRAGMENT_TO_LIGHT, }; @@ -767,6 +766,7 @@ public: static String get_datatype_name(DataType p_type); static bool is_token_nonvoid_datatype(TokenType p_type); static bool is_token_operator(TokenType p_type); + static bool is_token_operator_assign(TokenType p_type); static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = nullptr); static DataType get_scalar_type(DataType p_type); @@ -876,6 +876,14 @@ private: VaryingFunctionNames varying_function_names; + struct VaryingUsage { + ShaderNode::Varying *var; + int line; + }; + List<VaryingUsage> unknown_varying_usages; + + bool _check_varying_usages(int *r_error_line, String *r_error_message) const; + TkPos _get_tkpos() { TkPos tkp; tkp.char_idx = char_idx; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 9377075e76..1f01f47fff 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -972,7 +972,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa if (index_array_len) { List<Variant> keys; p_lods.get_key_list(&keys); - for (Variant &E : keys) { + for (const Variant &E : keys) { float distance = E; ERR_CONTINUE(distance <= 0.0); Vector<int> indices = p_lods[E]; diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 6031bd7003..6b248c9554 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -41,7 +41,7 @@ struct BlitToScreen; /** @author Bastiaan Olij <mux213@gmail.com> - The XR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs. + The XR interface is a template class on top of which we build interface to different AR, VR and tracking SDKs. The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server. |