diff --git a/doc/classes/RDPipelineRasterizationState.xml b/doc/classes/RDPipelineRasterizationState.xml index 034abc688cb..f2fb2919991 100644 --- a/doc/classes/RDPipelineRasterizationState.xml +++ b/doc/classes/RDPipelineRasterizationState.xml @@ -27,6 +27,9 @@ If [code]true[/code], primitives are discarded immediately before the rasterization stage. + + If [code]true[/code], primitive coverage is over-estimated during rasterization (any fragment containing part of the primitive will be included). May not be supported on all hardware. + If [code]true[/code], clamps depth values according to the minimum and maximum depth of the associated viewport. diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 8271d4b7e38..120b0cc1756 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -5634,7 +5634,7 @@ RDD::PipelineID RenderingDeviceDriverD3D12::render_pipeline_create( (&pipeline_desc.RasterizerState)->SlopeScaledDepthBias = 0.0f; } (&pipeline_desc.RasterizerState)->ForcedSampleCount = 0; - (&pipeline_desc.RasterizerState)->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + (&pipeline_desc.RasterizerState)->ConservativeRaster = p_rasterization_state.enable_conservative_rasterization ? D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; (&pipeline_desc.RasterizerState)->MultisampleEnable = TEXTURE_SAMPLES_COUNT[p_multisample_state.sample_count] != 1; (&pipeline_desc.RasterizerState)->AntialiasedLineEnable = true; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index d20f396281e..70db4f139d4 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -498,6 +498,7 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() { _register_requested_device_extension(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, false); _register_requested_device_extension(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false); _register_requested_device_extension(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, false); + _register_requested_device_extension(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, false); if (Engine::get_singleton()->is_generate_spirv_debug_info_enabled()) { _register_requested_device_extension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME, true); @@ -4585,6 +4586,17 @@ RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create( rasterization_state_create_info.depthBiasSlopeFactor = p_rasterization_state.depth_bias_slope_factor; rasterization_state_create_info.lineWidth = p_rasterization_state.line_width; + VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeStateCreateInfoExt = {}; + if (p_rasterization_state.enable_conservative_rasterization) { + if (enabled_device_extension_names.has(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { + conservativeStateCreateInfoExt.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT; + conservativeStateCreateInfoExt.conservativeRasterizationMode = VkConservativeRasterizationModeEXT::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT; + rasterization_state_create_info.pNext = &conservativeStateCreateInfoExt; + } else { + WARN_PRINT(vformat("enable_conservative_rasterization is true but %s is not available.", VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)); + } + } + // Multisample. VkPipelineMultisampleStateCreateInfo multisample_state_create_info = {}; multisample_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index 4d9b5650800..13a8ef18b5f 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -533,6 +533,7 @@ public: RD_SETGET(float, depth_bias_slope_factor) RD_SETGET(float, line_width) RD_SETGET(uint32_t, patch_control_points) + RD_SETGET(bool, enable_conservative_rasterization) protected: static void _bind_methods() { @@ -547,6 +548,7 @@ protected: RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor); RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width); RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_conservative_rasterization); } }; diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h index d516d968af6..13a3d15c44d 100644 --- a/servers/rendering/rendering_device_commons.h +++ b/servers/rendering/rendering_device_commons.h @@ -666,6 +666,7 @@ public: float depth_bias_slope_factor = 0.0f; float line_width = 1.0f; uint32_t patch_control_points = 1; + bool enable_conservative_rasterization = false; }; struct PipelineMultisampleState {