Просмотр исходного кода

Fix a bug in descriptor set binding

Panagiotis Christopoulos Charitos 6 лет назад
Родитель
Сommit
23b5898f75

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

@@ -703,6 +703,12 @@ inline void CommandBufferImpl::bindShaderProgram(ShaderProgramPtr& prog)
 		{
 			m_dsetState[i].setLayout(impl.getDescriptorSetLayout(i));
 		}
+		else
+		{
+			// According to the spec the bound DS may be disturbed if the ppline layout is not combatible. Play it safe
+			// and dirty the slot. That will force rebind of the DS at drawcall time.
+			m_dsetState[i].setLayout(DescriptorSetLayout());
+		}
 	}
 
 	m_microCmdb->pushObjectRef(prog);

+ 1 - 1
src/anki/gr/vulkan/DescriptorSet.cpp

@@ -516,7 +516,7 @@ void DescriptorSetState::flush(Bool& stateDirty,
 
 	hash = (toHashCount == 1) ? toHash[0] : computeHash(&toHash[0], toHashCount * sizeof(U64));
 
-	if(hash != m_lastHash || dynamicOffsetsDirty)
+	if(hash != m_lastHash || dynamicOffsetsDirty || m_layoutDirty)
 	{
 		m_lastHash = hash;
 		stateDirty = true;

+ 19 - 1
src/anki/gr/vulkan/DescriptorSet.h

@@ -57,6 +57,16 @@ public:
 		return m_handle != VK_NULL_HANDLE;
 	}
 
+	Bool operator==(const DescriptorSetLayout& b) const
+	{
+		return m_entry == b.m_entry;
+	}
+
+	Bool operator!=(const DescriptorSetLayout& b) const
+	{
+		return !operator==(b);
+	}
+
 private:
 	VkDescriptorSetLayout m_handle = VK_NULL_HANDLE;
 	DSLayoutCacheEntry* m_entry = nullptr;
@@ -106,8 +116,16 @@ class DescriptorSetState
 public:
 	void setLayout(const DescriptorSetLayout& layout)
 	{
+		if(layout.isCreated())
+		{
+			m_layoutDirty = m_layout != layout;
+		}
+		else
+		{
+			m_layoutDirty = true;
+		}
+
 		m_layout = layout;
-		m_layoutDirty = true;
 	}
 
 	void bindTextureAndSampler(U binding, const TextureView* texView, const Sampler* sampler, VkImageLayout layout)