From 8abd9e800c6b3142b31512a030bd40063f5944c5 Mon Sep 17 00:00:00 2001
From: Alex Laptop <alexander.gauggel@web.de>
Date: Thu, 16 Sep 2021 16:24:07 +0200
Subject: [PATCH] [#114] Fix conservative rasterization not working if physical
 device primitiveOverestimationSize = 0

---
 src/vkcv/Core.cpp                    |  2 +-
 src/vkcv/GraphicsPipelineManager.cpp | 20 ++++++++++++++------
 src/vkcv/GraphicsPipelineManager.hpp |  7 ++++---
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 88fc4794..a07d2583 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -52,7 +52,7 @@ namespace vkcv
     Core::Core(Context &&context, const CommandResources& commandResources, const SyncResources& syncResources) noexcept :
             m_Context(std::move(context)),
             m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
-            m_PipelineManager{std::make_unique<GraphicsPipelineManager>(m_Context.m_Device)},
+            m_PipelineManager{std::make_unique<GraphicsPipelineManager>(m_Context.m_Device, m_Context.m_PhysicalDevice)},
             m_ComputePipelineManager{std::make_unique<ComputePipelineManager>(m_Context.m_Device)},
             m_DescriptorManager(std::make_unique<DescriptorManager>(m_Context.m_Device)),
             m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())},
diff --git a/src/vkcv/GraphicsPipelineManager.cpp b/src/vkcv/GraphicsPipelineManager.cpp
index cb7dd31d..870220f4 100644
--- a/src/vkcv/GraphicsPipelineManager.cpp
+++ b/src/vkcv/GraphicsPipelineManager.cpp
@@ -5,8 +5,9 @@
 namespace vkcv
 {
 	
-	GraphicsPipelineManager::GraphicsPipelineManager(vk::Device device) noexcept :
-            m_Device{device},
+	GraphicsPipelineManager::GraphicsPipelineManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept :
+            m_Device(device),
+            m_physicalDevice(physicalDevice),
             m_Pipelines{}
     {}
 	
@@ -237,7 +238,9 @@ namespace vkcv
 	 * @param config sets Depth Clamping and Culling Mode
 	 * @return Pipeline Rasterization State Create Info Struct
 	 */
-	vk::PipelineRasterizationStateCreateInfo createPipelineRasterizationStateCreateInfo(const GraphicsPipelineConfig &config) {
+	vk::PipelineRasterizationStateCreateInfo createPipelineRasterizationStateCreateInfo(
+		const GraphicsPipelineConfig &config,
+		const vk::PhysicalDeviceConservativeRasterizationPropertiesEXT& conservativeRasterProperties) {
 		vk::CullModeFlags cullMode;
 		switch (config.m_culling) {
 			case CullMode::None:
@@ -267,14 +270,14 @@ namespace vkcv
 				0.f,
 				1.f
 		);
-		
+
 		static vk::PipelineRasterizationConservativeStateCreateInfoEXT conservativeRasterization;
 		
 		if (config.m_UseConservativeRasterization) {
 			conservativeRasterization = vk::PipelineRasterizationConservativeStateCreateInfoEXT(
 					{},
 					vk::ConservativeRasterizationModeEXT::eOverestimate,
-					0.f
+					std::max(1 - conservativeRasterProperties.primitiveOverestimationSize, 0.f)
 			);
 			
 			pipelineRasterizationStateCreateInfo.pNext = &conservativeRasterization;
@@ -544,8 +547,13 @@ namespace vkcv
                 createPipelineViewportStateCreateInfo(config);
 
         // rasterization state
+        vk::PhysicalDeviceConservativeRasterizationPropertiesEXT    conservativeRasterProperties;
+        vk::PhysicalDeviceProperties                                deviceProperties;
+        vk::PhysicalDeviceProperties2                               deviceProperties2(deviceProperties);
+        deviceProperties2.pNext = &conservativeRasterProperties;
+        m_physicalDevice.getProperties2(&deviceProperties2);
         vk::PipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo =
-                createPipelineRasterizationStateCreateInfo(config);
+                createPipelineRasterizationStateCreateInfo(config, conservativeRasterProperties);
 
         // multisample state
         vk::PipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo =
diff --git a/src/vkcv/GraphicsPipelineManager.hpp b/src/vkcv/GraphicsPipelineManager.hpp
index a08e6493..782603ab 100644
--- a/src/vkcv/GraphicsPipelineManager.hpp
+++ b/src/vkcv/GraphicsPipelineManager.hpp
@@ -20,7 +20,7 @@ namespace vkcv
     {
     public:
 		GraphicsPipelineManager() = delete; // no default ctor
-        explicit GraphicsPipelineManager(vk::Device device) noexcept; // ctor
+        explicit GraphicsPipelineManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept; // ctor
         ~GraphicsPipelineManager() noexcept; // dtor
 	
 		GraphicsPipelineManager(const GraphicsPipelineManager &other) = delete; // copy-ctor
@@ -71,8 +71,9 @@ namespace vkcv
 			GraphicsPipelineConfig m_config;
         };
 
-        vk::Device m_Device;
-        std::vector<GraphicsPipeline> m_Pipelines;
+        vk::Device                      m_Device;
+        vk::PhysicalDevice              m_physicalDevice; // needed to get infos to configure conservative rasterization
+        std::vector<GraphicsPipeline>   m_Pipelines;
 
         void destroyPipelineById(uint64_t id);
 
-- 
GitLab