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 {