diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index a07109d9df..72e4b83453 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1733,8 +1733,14 @@ void RendererSceneRenderRD::init() { raster_effects.set_flag(RendererRD::CopyEffects::RASTER_EFFECT_COPY); raster_effects.set_flag(RendererRD::CopyEffects::RASTER_EFFECT_GAUSSIAN_BLUR); - // This path can be used in the future to redirect certain devices to use the raster version of the effect, either due to performance or driver errors. + // This path can be used to redirect certain devices to use the raster version of the effect, either due to performance, lack of capabilities, or driver errors. bool use_raster_for_octmaps = false; + + // Some devices may not support the A2B10G10R10 format as a storage image on the Mobile renderer. + if (!RD::get_singleton()->texture_is_format_supported_for_usage(_render_buffers_get_preferred_color_format(), RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT)) { + use_raster_for_octmaps = true; + } + if (use_raster_for_octmaps) { raster_effects.set_flag(RendererRD::CopyEffects::RASTER_EFFECT_OCTMAP); } diff --git a/servers/rendering/renderer_rd/shaders/effects/octmap_downsampler_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/octmap_downsampler_raster.glsl index 21c6a35c19..24097e6653 100644 --- a/servers/rendering/renderer_rd/shaders/effects/octmap_downsampler_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/octmap_downsampler_raster.glsl @@ -36,9 +36,22 @@ layout(location = 0) out vec2 uv_interp; /* clang-format on */ void main() { - vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); - gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); - uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 + // old code, ARM driver bug on Mali-GXXx GPUs and Vulkan API 1.3.xxx + // https://github.com/godotengine/godot/pull/92817#issuecomment-2168625982 + //vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); + //gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); + //uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 + + vec2 vertex_base; + if (gl_VertexIndex == 0) { + vertex_base = vec2(-1.0, -1.0); + } else if (gl_VertexIndex == 1) { + vertex_base = vec2(-1.0, 3.0); + } else { + vertex_base = vec2(3.0, -1.0); + } + gl_Position = vec4(vertex_base, 0.0, 1.0); + uv_interp = clamp(vertex_base, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 } /* clang-format off */ @@ -69,10 +82,10 @@ float calcWeight(float u, float v) { void main() { #ifdef USE_HIGH_QUALITY float inv_size = 1.0 / float(params.size); - float u0 = (uv_interp.x * 2.0f - 0.75) * inv_size - 1.0f; - float u1 = (uv_interp.x * 2.0f + 0.75) * inv_size - 1.0f; - float v0 = (uv_interp.y * 2.0f - 0.75) * inv_size - 1.0f; - float v1 = (uv_interp.y * 2.0f + 0.75) * inv_size - 1.0f; + float u0 = (uv_interp.x * 2.0f) + (1.0f - 0.75f) * inv_size - 1.0f; + float u1 = (uv_interp.x * 2.0f) + (1.0f + 0.75f) * inv_size - 1.0f; + float v0 = (uv_interp.y * 2.0f) + (1.0f - 0.75f) * inv_size - 1.0f; + float v1 = (uv_interp.y * 2.0f) + (1.0f + 0.75f) * inv_size - 1.0f; float weights[4]; weights[0] = calcWeight(u0, v0); weights[1] = calcWeight(u1, v0); diff --git a/servers/rendering/renderer_rd/shaders/effects/octmap_roughness_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/octmap_roughness_raster.glsl index e5a0efc407..0fa19b0323 100644 --- a/servers/rendering/renderer_rd/shaders/effects/octmap_roughness_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/octmap_roughness_raster.glsl @@ -11,9 +11,22 @@ layout(location = 0) out vec2 uv_interp; /* clang-format on */ void main() { - vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); - gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); - uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 + // old code, ARM driver bug on Mali-GXXx GPUs and Vulkan API 1.3.xxx + // https://github.com/godotengine/godot/pull/92817#issuecomment-2168625982 + //vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); + //gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); + //uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 + + vec2 vertex_base; + if (gl_VertexIndex == 0) { + vertex_base = vec2(-1.0, -1.0); + } else if (gl_VertexIndex == 1) { + vertex_base = vec2(-1.0, 3.0); + } else { + vertex_base = vec2(3.0, -1.0); + } + gl_Position = vec4(vertex_base, 0.0, 1.0); + uv_interp = clamp(vertex_base, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 } /* clang-format off */ @@ -37,10 +50,9 @@ void main() { if (params.use_direct_write) { frag_color = vec4(texture(source_oct, uv_interp).rgb, 1.0); } else { - vec2 inv_size = 1.0 / vec2(params.size); vec3 N = oct_to_vec3_with_border(uv_interp, params.border_size.y); vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); - float solid_angle_texel = 4.0 * M_PI / (params.size * params.size); + float solid_angle_texel = 4.0 * M_PI / (params.dest_size * params.dest_size); float roughness2 = params.roughness * params.roughness; float roughness4 = roughness2 * roughness2; vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);