From 09aa1bbdb3c9dc4891a192854636a4e33ccd46bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Tue, 25 Apr 2023 14:14:01 +0200 Subject: [PATCH] Fix unsupported sampler filter used for voxel GI --- doc/classes/RenderingDevice.xml | 8 ++++++++ drivers/vulkan/rendering_device_vulkan.cpp | 12 ++++++++++++ drivers/vulkan/rendering_device_vulkan.h | 1 + servers/rendering/renderer_rd/environment/gi.cpp | 4 +++- .../renderer_rd/shaders/environment/gi.glsl | 8 ++++++++ servers/rendering/rendering_device.cpp | 1 + servers/rendering/rendering_device.h | 1 + 7 files changed, 34 insertions(+), 1 deletion(-) diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index f597cb7efc6..b9f6a009fb5 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -452,6 +452,14 @@ + + + + + + Returns [code]true[/code] if implementation supports using a texture of [param format] with the given [param sampler_filter]. + + diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index d03324527ee..2fd46d65ff8 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -4305,6 +4305,18 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) { return id; } +bool RenderingDeviceVulkan::sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_sampler_filter) const { + ERR_FAIL_INDEX_V(p_format, DATA_FORMAT_MAX, false); + + _THREAD_SAFE_METHOD_ + + // Validate that this image is supported for the intended filtering. + VkFormatProperties properties; + vkGetPhysicalDeviceFormatProperties(context->get_physical_device(), vulkan_formats[p_format], &properties); + + return p_sampler_filter == RD::SAMPLER_FILTER_NEAREST || (p_sampler_filter == RD::SAMPLER_FILTER_LINEAR && (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)); +} + /**********************/ /**** VERTEX ARRAY ****/ /**********************/ diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 3f01895745b..2ec1574955d 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1084,6 +1084,7 @@ public: /*****************/ virtual RID sampler_create(const SamplerState &p_state); + virtual bool sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_sampler_filter) const; /**********************/ /**** VERTEX ARRAY ****/ diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index fd7975ed3a5..52f09e1ccb5 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -3493,6 +3493,9 @@ void GI::init(SkyRD *p_sky) { if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { defines += "\n#define USE_VRS\n"; } + if (!RD::get_singleton()->sampler_is_format_supported_for_filter(RD::DATA_FORMAT_R8G8_UINT, RD::SAMPLER_FILTER_LINEAR)) { + defines += "\n#define SAMPLE_VOXEL_GI_NEAREST\n"; + } Vector gi_modes; @@ -3931,7 +3934,6 @@ void GI::process_gi(Ref p_render_buffers, const RID *p_nor u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } - { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl index 459c4dcb1df..59af9501bae 100644 --- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl @@ -4,6 +4,10 @@ #VERSION_DEFINES +#ifdef SAMPLE_VOXEL_GI_NEAREST +#extension GL_EXT_samplerless_texture_functions : enable +#endif + layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #define M_PI 3.141592 @@ -625,7 +629,11 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref #ifdef USE_VOXEL_GI_INSTANCES { +#ifdef SAMPLE_VOXEL_GI_NEAREST + uvec2 voxel_gi_tex = texelFetch(voxel_gi_buffer, pos, 0).rg; +#else uvec2 voxel_gi_tex = texelFetch(usampler2D(voxel_gi_buffer, linear_sampler), pos, 0).rg; +#endif roughness *= roughness; //find arbitrary tangent and bitangent, then build a matrix vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 744fd051f5e..4ff8bbfb85b 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -723,6 +723,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("framebuffer_is_valid", "framebuffer"), &RenderingDevice::framebuffer_is_valid); ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); + ClassDB::bind_method(D_METHOD("sampler_is_format_supported_for_filter", "format", "sampler_filter"), &RenderingDevice::sampler_is_format_supported_for_filter); ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 447627b08ef..48246fa44a0 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -653,6 +653,7 @@ public: }; virtual RID sampler_create(const SamplerState &p_state) = 0; + virtual bool sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_sampler_filter) const = 0; /**********************/ /**** VERTEX ARRAY ****/