Przeglądaj źródła

Added support for VK_AMD_rasterization_order

Panagiotis Christopoulos Charitos 7 lat temu
rodzic
commit
75ce6a9390

+ 1 - 1
shaders/GBufferCommonFrag.glsl

@@ -106,7 +106,7 @@ vec2 computeTextureCoordParallax(in sampler2D heightMap, in vec2 uv, in float he
 	uint crntSample = 0;
 
 	uint sampleCount = uint(sampleCountf);
-	while(crntSample < sampleCount)
+	ANKI_LOOP while(crntSample < sampleCount)
 	{
 		crntSampledHeight = textureGrad(heightMap, uv + crntOffset, dPdx, dPdy).r;
 

+ 3 - 0
src/anki/gr/CommandBuffer.h

@@ -229,6 +229,9 @@ public:
 		setBlendOperation(attachment, func, func);
 	}
 
+	/// Set the rasterizatin order. By default it's RasterizationOrder::ORDERED.
+	void setRasterizationOrder(RasterizationOrder order);
+
 	/// Bind texture and sample.
 	/// @param set The set to bind to.
 	/// @param binding The binding to bind to.

+ 8 - 0
src/anki/gr/Enums.h

@@ -602,6 +602,14 @@ enum class IndexType : U8
 	U32,
 	COUNT
 };
+
+/// Rasterization order.
+enum class RasterizationOrder : U8
+{
+	ORDERED,
+	RELAXED,
+	COUNT
+};
 /// @}
 
 } // end namespace anki

+ 5 - 0
src/anki/gr/gl/CommandBuffer.cpp

@@ -1554,4 +1554,9 @@ void CommandBuffer::setPushConstants(const void* data, U32 dataSize)
 	self.pushBackNewCommand<PushConstants>(data, dataSize, self.m_alloc);
 }
 
+void CommandBuffer::setRasterizationOrder(RasterizationOrder order)
+{
+	// Nothing for GL
+}
+
 } // end namespace anki

+ 6 - 0
src/anki/gr/vulkan/CommandBuffer.cpp

@@ -364,4 +364,10 @@ void CommandBuffer::setPushConstants(const void* data, U32 dataSize)
 	self.setPushConstants(data, dataSize);
 }
 
+void CommandBuffer::setRasterizationOrder(RasterizationOrder order)
+{
+	ANKI_VK_SELF(CommandBufferImpl);
+	self.setRasterizationOrder(order);
+}
+
 } // end namespace anki

+ 2 - 0
src/anki/gr/vulkan/CommandBufferImpl.h

@@ -331,6 +331,8 @@ public:
 
 	void setPushConstants(const void* data, U32 dataSize);
 
+	void setRasterizationOrder(RasterizationOrder order);
+
 private:
 	StackAllocator<U8> m_alloc;
 

+ 12 - 0
src/anki/gr/vulkan/CommandBufferImpl.inl.h

@@ -752,6 +752,8 @@ inline void CommandBufferImpl::setPushConstants(const void* data, U32 dataSize)
 	ANKI_ASSERT(prog->getReflectionInfo().m_pushConstantsSize == dataSize
 				&& "The bound program should have push constants equal to the \"dataSize\" parameter");
 
+	commandCommon();
+
 	ANKI_CMD(
 		vkCmdPushConstants(m_handle, prog->getPipelineLayout().getHandle(), VK_SHADER_STAGE_ALL, 0, dataSize, data),
 		ANY_OTHER_COMMAND);
@@ -761,4 +763,14 @@ inline void CommandBufferImpl::setPushConstants(const void* data, U32 dataSize)
 #endif
 }
 
+inline void CommandBufferImpl::setRasterizationOrder(RasterizationOrder order)
+{
+	commandCommon();
+
+	if(!!(getGrManagerImpl().getExtensions() & VulkanExtensions::AMD_RASTERIZATION_ORDER))
+	{
+		m_state.setRasterizationOrder(order);
+	}
+}
+
 } // end namespace anki

+ 20 - 0
src/anki/gr/vulkan/Common.h

@@ -48,6 +48,7 @@ enum class VulkanExtensions : U16
 	EXT_SHADER_SUBGROUP_BALLOT = 1 << 8,
 	EXT_DEBUG_REPORT = 1 << 9,
 	AMD_SHADER_INFO = 1 << 10,
+	AMD_RASTERIZATION_ORDER = 1 << 11,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions, inline)
 
@@ -236,6 +237,25 @@ ANKI_USE_RESULT inline VkIndexType convertIndexType(IndexType ak)
 
 	return out;
 }
+
+ANKI_USE_RESULT inline VkRasterizationOrderAMD convertRasterizationOrder(RasterizationOrder ak)
+{
+	VkRasterizationOrderAMD out;
+	switch(ak)
+	{
+	case RasterizationOrder::ORDERED:
+		out = VK_RASTERIZATION_ORDER_STRICT_AMD;
+		break;
+	case RasterizationOrder::RELAXED:
+		out = VK_RASTERIZATION_ORDER_RELAXED_AMD;
+		break;
+	default:
+		ANKI_ASSERT(0);
+		out = VK_RASTERIZATION_ORDER_STRICT_AMD;
+	}
+
+	return out;
+}
 /// @}
 
 } // end namespace anki

+ 5 - 0
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -531,6 +531,11 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::AMD_SHADER_INFO;
 				extensionsToEnable[extensionsToEnableCount++] = VK_AMD_SHADER_INFO_EXTENSION_NAME;
 			}
+			else if(CString(extensionInfos[extCount].extensionName) == VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME)
+			{
+				m_extensions |= VulkanExtensions::AMD_RASTERIZATION_ORDER;
+				extensionsToEnable[extensionsToEnableCount++] = VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME;
+			}
 		}
 
 		if(!!(m_extensions & VulkanExtensions::KHR_MAINENANCE1))

+ 11 - 0
src/anki/gr/vulkan/Pipeline.cpp

@@ -271,6 +271,17 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 	rastCi.lineWidth = 1.0;
 	ci.pRasterizationState = &rastCi;
 
+	if(m_state.m_rasterizer.m_rasterizationOrder != RasterizationOrder::ORDERED)
+	{
+		VkPipelineRasterizationStateRasterizationOrderAMD& rastOrderCi = m_ci.m_rasterOrder;
+		rastOrderCi = {};
+		rastOrderCi.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD;
+		rastOrderCi.rasterizationOrder = convertRasterizationOrder(m_state.m_rasterizer.m_rasterizationOrder);
+
+		ANKI_ASSERT(rastCi.pNext == nullptr);
+		rastCi.pNext = &rastOrderCi;
+	}
+
 	// MS
 	VkPipelineMultisampleStateCreateInfo& msCi = m_ci.m_ms;
 	msCi = {};

+ 11 - 0
src/anki/gr/vulkan/Pipeline.h

@@ -85,6 +85,7 @@ class PPRasterizerStateInfo : public NonCopyable
 public:
 	FillMode m_fillMode = FillMode::SOLID;
 	FaceSelectionBit m_cullMode = FaceSelectionBit::BACK;
+	RasterizationOrder m_rasterizationOrder = RasterizationOrder::ORDERED;
 	F32 m_depthBiasConstantFactor = 0.0;
 	F32 m_depthBiasSlopeFactor = 0.0;
 };
@@ -250,6 +251,15 @@ public:
 		}
 	}
 
+	void setRasterizationOrder(RasterizationOrder order)
+	{
+		if(m_state.m_rasterizer.m_rasterizationOrder != order)
+		{
+			m_state.m_rasterizer.m_rasterizationOrder = order;
+			m_dirty.m_other |= DirtyBit::RASTER;
+		}
+	}
+
 	void setStencilOperations(FaceSelectionBit face,
 		StencilOperation stencilFail,
 		StencilOperation stencilPassDepthFail,
@@ -514,6 +524,7 @@ private:
 		VkPipelineColorBlendStateCreateInfo m_color;
 		VkPipelineDynamicStateCreateInfo m_dyn;
 		VkGraphicsPipelineCreateInfo m_ppline;
+		VkPipelineRasterizationStateRasterizationOrderAMD m_rasterOrder;
 	} m_ci;
 
 	Bool updateHashes();

+ 2 - 0
src/anki/renderer/GBuffer.cpp

@@ -99,6 +99,8 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 	const I32 colorStart = max(I32(start) - I32(earlyZCount), 0);
 	const I32 colorEnd = I32(end) - I32(earlyZCount);
 
+	cmdb->setRasterizationOrder(RasterizationOrder::RELAXED);
+
 	// First do early Z (if needed)
 	if(earlyZStart < earlyZEnd)
 	{