summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct3
-rw-r--r--editor/plugins/theme_editor_plugin.cpp7
-rw-r--r--methods.py4
-rw-r--r--modules/gdscript/gdscript_compiler.cpp2
-rw-r--r--modules/gdscript/gdscript_vm.cpp33
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs2
-rw-r--r--scene/main/canvas_item.cpp5
-rw-r--r--servers/rendering/renderer_rd/effects/ss_effects.cpp32
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl15
15 files changed, 106 insertions, 37 deletions
diff --git a/SConstruct b/SConstruct
index 845b9be4a6..ee2247acf1 100644
--- a/SConstruct
+++ b/SConstruct
@@ -200,6 +200,7 @@ opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extr
opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False))
opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "")
opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False))
+opts.Add("vsproj_name", "Name of the Visual Studio solution", "godot")
opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False))
opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False))
opts.Add("build_profile", "Path to a file containing a feature build profile", "")
@@ -923,7 +924,7 @@ if selected_platform in platform_list:
print("Error: The `vsproj` option is only usable on Windows with Visual Studio.")
Exit(255)
env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]]
- methods.generate_vs_project(env, GetOption("num_jobs"))
+ methods.generate_vs_project(env, GetOption("num_jobs"), env["vsproj_name"])
methods.generate_cpp_hint_file("cpp.hint")
# Check for the existence of headers
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 073adb467a..2519928ea3 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -3223,6 +3223,7 @@ void ThemeTypeEditor::_update_stylebox_from_leading() {
if (!leading_stylebox.pinned || leading_stylebox.stylebox.is_null()) {
return;
}
+ ERR_FAIL_COND_MSG(edited_theme.is_null(), "Leading stylebox does not have an edited theme to update");
// Prevent changes from immediately being reported while the operation is still ongoing.
edited_theme->_freeze_change_propagation();
@@ -3706,7 +3707,11 @@ void ThemeEditorPlugin::edit(Object *p_node) {
if (Object::cast_to<Theme>(p_node)) {
theme_editor->edit(Object::cast_to<Theme>(p_node));
} else {
- theme_editor->edit(Ref<Theme>());
+ // We intentionally keep a reference to the last used theme to work around
+ // the the editor being hidden while base resources are edited. Uncomment
+ // the following line again and remove this comment once that bug has been
+ // fixed (scheduled for Godot 4.1 in PR 73098):
+ // theme_editor->edit(Ref<Theme>());
}
}
diff --git a/methods.py b/methods.py
index 7ede2592ff..dddac9bd86 100644
--- a/methods.py
+++ b/methods.py
@@ -732,7 +732,7 @@ def add_to_vs_project(env, sources):
env.vs_srcs += [basename + ".cpp"]
-def generate_vs_project(env, num_jobs):
+def generate_vs_project(env, num_jobs, project_name="godot"):
batch_file = find_visual_c_batch_file(env)
if batch_file:
@@ -873,7 +873,7 @@ def generate_vs_project(env, num_jobs):
env["MSVS"]["PROJECTSUFFIX"] = ".vcxproj"
env["MSVS"]["SOLUTIONSUFFIX"] = ".sln"
env.MSVSProject(
- target=["#godot" + env["MSVSPROJECTSUFFIX"]],
+ target=["#" + project_name + env["MSVSPROJECTSUFFIX"]],
incs=env.vs_incs,
srcs=env.vs_srcs,
auto_build_solution=1,
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 46cd4b0d55..b34be11169 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -254,7 +254,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (codegen.script->member_indices.has(identifier)) {
if (codegen.script->member_indices[identifier].getter != StringName() && codegen.script->member_indices[identifier].getter != codegen.function_name) {
// Perform getter.
- GDScriptCodeGenerator::Address temp = codegen.add_temporary();
+ GDScriptCodeGenerator::Address temp = codegen.add_temporary(codegen.script->member_indices[identifier].data_type);
Vector<GDScriptCodeGenerator::Address> args; // No argument needed.
gen->write_call_self(temp, codegen.script->member_indices[identifier].getter, args);
return temp;
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 7a11ea52f0..4db41c4dfa 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -1244,7 +1244,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
"' to a variable of type '" + nc->get_name() + "'.";
OPCODE_BREAK;
}
- Object *src_obj = src->operator Object *();
+
+ bool was_freed = false;
+ Object *src_obj = src->get_validated_object_with_check(was_freed);
+ if (!src_obj) {
+ if (was_freed) {
+ err_text = "Trying to assign invalid previously freed instance.";
+ } else {
+ err_text = "Trying to assign invalid null variable.";
+ }
+ OPCODE_BREAK;
+ }
if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) {
err_text = "Trying to assign value of type '" + src_obj->get_class_name() +
@@ -1274,15 +1284,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_BREAK;
}
- if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) {
- ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
+ if (src->get_type() != Variant::NIL) {
+ bool was_freed = false;
+ Object *val_obj = src->get_validated_object_with_check(was_freed);
+ if (!val_obj) {
+ if (was_freed) {
+ err_text = "Trying to assign invalid previously freed instance.";
+ } else {
+ err_text = "Trying to assign invalid null variable.";
+ }
+ OPCODE_BREAK;
+ }
+
+ ScriptInstance *scr_inst = val_obj->get_script_instance();
if (!scr_inst) {
- err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() +
+ err_text = "Trying to assign value of type '" + val_obj->get_class_name() +
"' to a variable of type '" + base_type->get_path().get_file() + "'.";
OPCODE_BREAK;
}
- Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr();
+ Script *src_type = val_obj->get_script_instance()->get_script().ptr();
bool valid = false;
while (src_type) {
@@ -1294,7 +1315,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (!valid) {
- err_text = "Trying to assign value of type '" + src->operator Object *()->get_script_instance()->get_script()->get_path().get_file() +
+ err_text = "Trying to assign value of type '" + val_obj->get_script_instance()->get_script()->get_path().get_file() +
"' to a variable of type '" + base_type->get_path().get_file() + "'.";
OPCODE_BREAK;
}
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd
new file mode 100644
index 0000000000..dd2708b21d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd
@@ -0,0 +1,7 @@
+func test():
+ var x = Node.new()
+
+ x.free()
+
+ var ok = x
+ var bad : Node = x
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out
new file mode 100644
index 0000000000..679e51ed81
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> analyzer/errors/native_freed_instance.gd
+>> 7
+>> Trying to assign invalid previously freed instance.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd
new file mode 100644
index 0000000000..758fbaccc9
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd
@@ -0,0 +1,10 @@
+class A extends Node:
+ pass
+
+func test():
+ var x = A.new()
+
+ x.free()
+
+ var ok = x
+ var bad : A = x
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out
new file mode 100644
index 0000000000..dec7090322
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> analyzer/errors/script_freed_instance.gd
+>> 10
+>> Trying to assign invalid previously freed instance.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd
new file mode 100644
index 0000000000..38bb7f6e9c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd
@@ -0,0 +1,9 @@
+var Value:int = 8 :
+ get:
+ return Value
+ set(v):
+ Value = v
+
+func test():
+ var f:float = Value
+ print(int(f))
diff --git a/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out
new file mode 100644
index 0000000000..b0cb63ef59
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+8
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
index ed3a4c6e26..6c5c61acb9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
@@ -302,7 +302,7 @@ namespace GodotTools.Build
public static bool CleanProjectBlocking(
[DisallowNull] string configuration,
[AllowNull] string platform = null
- ) => CleanProjectBlocking(CreateBuildInfo(configuration, platform, rebuild: false));
+ ) => CleanProjectBlocking(CreateBuildInfo(configuration, platform, rebuild: false, onlyClean: true));
public static bool PublishProjectBlocking(
[DisallowNull] string configuration,
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index e5dcdd2afd..1c7d42ad36 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -515,12 +515,13 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
float length = (p_to - p_from).length();
- if (length < p_dash) {
+ Vector2 step = p_dash * (p_to - p_from).normalized();
+
+ if (length < p_dash || step == Vector2() || p_dash <= 0.0) {
RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
return;
}
- Vector2 step = p_dash * (p_to - p_from).normalized();
int steps = (p_aligned) ? Math::ceil(length / p_dash) : Math::floor(length / p_dash);
if (steps % 2 == 0) {
steps--;
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp
index e031e33041..9389f8149e 100644
--- a/servers/rendering/renderer_rd/effects/ss_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp
@@ -484,7 +484,7 @@ void SSEffects::downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uin
downsample_uniform_set = uniform_set_cache->get_cache_vec(shader, 2, u_depths);
}
- float depth_linearize_mul = -p_projection.columns[3][2];
+ float depth_linearize_mul = -p_projection.columns[3][2] * 0.5;
float depth_linearize_add = p_projection.columns[2][2];
if (depth_linearize_mul * depth_linearize_add < 0) {
depth_linearize_add = -depth_linearize_add;
@@ -668,8 +668,14 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende
ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
- ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width;
- ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height;
+ ssil.gather_push_constant.half_screen_pixel_size[0] = 2.0 / p_settings.full_screen_size.x;
+ ssil.gather_push_constant.half_screen_pixel_size[1] = 2.0 / p_settings.full_screen_size.y;
+ if (ssil_half_size) {
+ ssil.gather_push_constant.half_screen_pixel_size[0] *= 2.0;
+ ssil.gather_push_constant.half_screen_pixel_size[1] *= 2.0;
+ }
+ ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.75;
+ ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.75;
float tan_half_fov_x = 1.0 / p_projection.columns[0][0];
float tan_half_fov_y = 1.0 / p_projection.columns[1][1];
ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
@@ -680,9 +686,6 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende
ssil.gather_push_constant.z_far = p_projection.get_z_far();
ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
- ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25;
- ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25;
-
ssil.gather_push_constant.radius = p_settings.radius;
float radius_near_limit = (p_settings.radius * 1.2f);
if (ssil_quality <= RS::ENV_SSIL_QUALITY_LOW) {
@@ -733,7 +736,7 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende
RD::Uniform u_depth_texture_view;
u_depth_texture_view.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u_depth_texture_view.binding = 0;
- u_depth_texture_view.append_id(default_sampler);
+ u_depth_texture_view.append_id(ss_effects.mirror_sampler);
u_depth_texture_view.append_id(depth_texture_view);
RD::Uniform u_normal_buffer;
@@ -1056,8 +1059,14 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe
ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
- ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width;
- ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height;
+ ssao.gather_push_constant.half_screen_pixel_size[0] = 2.0 / p_settings.full_screen_size.x;
+ ssao.gather_push_constant.half_screen_pixel_size[1] = 2.0 / p_settings.full_screen_size.y;
+ if (ssao_half_size) {
+ ssao.gather_push_constant.half_screen_pixel_size[0] *= 2.0;
+ ssao.gather_push_constant.half_screen_pixel_size[1] *= 2.0;
+ }
+ ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.75;
+ ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.75;
float tan_half_fov_x = 1.0 / p_projection.columns[0][0];
float tan_half_fov_y = 1.0 / p_projection.columns[1][1];
ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
@@ -1066,9 +1075,6 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe
ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
- ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25;
- ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25;
-
ssao.gather_push_constant.radius = p_settings.radius;
float radius_near_limit = (p_settings.radius * 1.2f);
if (ssao_quality <= RS::ENV_SSAO_QUALITY_LOW) {
@@ -1105,7 +1111,7 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe
RD::Uniform u_depth_texture_view;
u_depth_texture_view.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u_depth_texture_view.binding = 0;
- u_depth_texture_view.append_id(default_sampler);
+ u_depth_texture_view.append_id(ss_effects.mirror_sampler);
u_depth_texture_view.append_id(depth_texture_view);
RD::Uniform u_normal_buffer;
diff --git a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
index b1ff46dd3b..4f81e36c58 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
@@ -161,17 +161,11 @@ void prepare_depths_and_mips(vec4 p_samples, uvec2 p_output_coord, uvec2 p_gtid)
still_alive = p_gtid.x % 16 == depth_array_offset.x && depth_array_offset.y % 16 == depth_array_offset.y;
p_output_coord /= 2;
- groupMemoryBarrier();
- barrier();
if (still_alive) {
+ // Use the previous average, not ideal, but still not bad.
float sample_00 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 0];
- float sample_01 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 8];
- float sample_10 = depth_buffer[depth_array_index][buffer_coord.x + 8][buffer_coord.y + 0];
- float sample_11 = depth_buffer[depth_array_index][buffer_coord.x + 8][buffer_coord.y + 8];
-
- float avg = mip_smart_average(vec4(sample_00, sample_01, sample_10, sample_11));
- imageStore(dest_image4, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(avg));
+ imageStore(dest_image4, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(sample_00));
}
#endif
}
@@ -190,6 +184,7 @@ void prepare_depths(vec4 p_samples, uvec2 p_tid) {
void main() {
#ifdef USE_HALF_BUFFERS
+// Half buffers means that we divide depth into two half res buffers (we only capture 1/4 of pixels).
#ifdef USE_HALF_SIZE
float sample_00 = texelFetch(source_depth, ivec2(4 * gl_GlobalInvocationID.x + 0, 4 * gl_GlobalInvocationID.y + 0), 0).x;
float sample_11 = texelFetch(source_depth, ivec2(4 * gl_GlobalInvocationID.x + 2, 4 * gl_GlobalInvocationID.y + 2), 0).x;
@@ -219,11 +214,11 @@ void main() {
vec2 uv = (vec2(depth_buffer_coord) + 0.5f) * params.pixel_size;
vec4 samples = textureGather(source_depth, uv);
-#endif
+#endif //USE_HALF_SIZE
#ifdef GENERATE_MIPS
prepare_depths_and_mips(samples, output_coord, gl_LocalInvocationID.xy);
#else
prepare_depths(samples, gl_GlobalInvocationID.xy);
#endif
-#endif
+#endif //USE_HALF_BUFFERS
}