瀏覽代碼

Small refactor for images

Panagiotis Christopoulos Charitos 4 年之前
父節點
當前提交
7e28f95eaf

+ 7 - 7
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -685,7 +685,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	// Descriptor indexing
 	// Descriptor indexing
 	if(!(m_extensions & VulkanExtensions::EXT_DESCRIPTOR_INDEXING))
 	if(!(m_extensions & VulkanExtensions::EXT_DESCRIPTOR_INDEXING))
 	{
 	{
-		ANKI_VK_LOGE("Descriptor indexing is not supported");
+		ANKI_VK_LOGE(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 	else
 	else
@@ -724,7 +724,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	// Buffer address
 	// Buffer address
 	if(!(m_extensions & VulkanExtensions::KHR_BUFFER_DEVICE_ADDRESS))
 	if(!(m_extensions & VulkanExtensions::KHR_BUFFER_DEVICE_ADDRESS))
 	{
 	{
-		ANKI_VK_LOGE("Device buffer access extension is not supported");
+		ANKI_VK_LOGE(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 	else
 	else
@@ -747,7 +747,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	// Scalar block layout
 	// Scalar block layout
 	if(!(m_extensions & VulkanExtensions::EXT_SCALAR_BLOCK_LAYOUT))
 	if(!(m_extensions & VulkanExtensions::EXT_SCALAR_BLOCK_LAYOUT))
 	{
 	{
-		ANKI_VK_LOGE("Scalar block layout extension is not supported");
+		ANKI_VK_LOGE(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 	else
 	else
@@ -772,7 +772,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	// Timeline semaphore
 	// Timeline semaphore
 	if(!(m_extensions & VulkanExtensions::KHR_TIMELINE_SEMAPHORE))
 	if(!(m_extensions & VulkanExtensions::KHR_TIMELINE_SEMAPHORE))
 	{
 	{
-		ANKI_VK_LOGE("Timeline semaphore extension is not supported");
+		ANKI_VK_LOGE(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 	else
 	else
@@ -842,7 +842,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	// F16 I8
 	// F16 I8
 	if(!(m_extensions & VulkanExtensions::KHR_SHADER_FLOAT16_INT8))
 	if(!(m_extensions & VulkanExtensions::KHR_SHADER_FLOAT16_INT8))
 	{
 	{
-		ANKI_VK_LOGE("FP16/Int8 extension is not supported");
+		ANKI_VK_LOGE(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 	else
 	else
@@ -861,7 +861,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	// 64bit atomics
 	// 64bit atomics
 	if(!(m_extensions & VulkanExtensions::KHR_SHADER_ATOMIC_INT64))
 	if(!(m_extensions & VulkanExtensions::KHR_SHADER_ATOMIC_INT64))
 	{
 	{
-		ANKI_VK_LOGE("64bit atomics are not supported");
+		ANKI_VK_LOGE(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 	else
 	else
@@ -917,7 +917,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 
 
 	if(!(m_extensions & VulkanExtensions::KHR_SPIRV_1_4))
 	if(!(m_extensions & VulkanExtensions::KHR_SPIRV_1_4))
 	{
 	{
-		ANKI_VK_LOGE("Spir-V 1.4 is not supported");
+		ANKI_VK_LOGE(VK_KHR_SPIRV_1_4_EXTENSION_NAME " is not supported");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 
 

+ 33 - 1
AnKi/Gr/Vulkan/TextureImpl.cpp

@@ -14,6 +14,38 @@
 namespace anki
 namespace anki
 {
 {
 
 
+U32 MicroImageView::getOrCreateBindlessIndex(VkImageLayout layout, GrManagerImpl& gr) const
+{
+	ANKI_ASSERT(layout == VK_IMAGE_LAYOUT_GENERAL || layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+
+	const U32 arrayIdx = (layout == VK_IMAGE_LAYOUT_GENERAL) ? 1 : 0;
+
+	LockGuard<SpinLock> lock(m_lock);
+
+	U32 outIdx;
+	if(m_bindlessIndices[arrayIdx] != MAX_U32)
+	{
+		outIdx = m_bindlessIndices[arrayIdx];
+	}
+	else
+	{
+		// Needs binding to the bindless descriptor set
+
+		if(layout == VK_IMAGE_LAYOUT_GENERAL)
+		{
+			outIdx = gr.getDescriptorSetFactory().bindBindlessImage(m_handle);
+		}
+		else
+		{
+			outIdx = gr.getDescriptorSetFactory().bindBindlessTexture(m_handle, layout);
+		}
+
+		m_bindlessIndices[arrayIdx] = outIdx;
+	}
+
+	return outIdx;
+}
+
 TextureImpl::~TextureImpl()
 TextureImpl::~TextureImpl()
 {
 {
 #if ANKI_ENABLE_ASSERTIONS
 #if ANKI_ENABLE_ASSERTIONS
@@ -23,7 +55,7 @@ TextureImpl::~TextureImpl()
 	}
 	}
 #endif
 #endif
 
 
-	for(auto it : m_viewsMap)
+	for(MicroImageView& it : m_viewsMap)
 	{
 	{
 		destroyMicroImageView(it);
 		destroyMicroImageView(it);
 	}
 	}

+ 40 - 17
AnKi/Gr/Vulkan/TextureImpl.h

@@ -33,20 +33,17 @@ ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(TextureImplWorkaround)
 /// A Vulkan image view with some extra data.
 /// A Vulkan image view with some extra data.
 class MicroImageView
 class MicroImageView
 {
 {
-public:
-	VkImageView m_handle = VK_NULL_HANDLE;
-
-	/// Index 0: Sampled image with SHADER_READ_ONLY layout.
-	/// Index 1: Storage image with ofcource GENERAL layout.
-	mutable Array<U32, 2> m_bindlessIndices = {MAX_U32, MAX_U32};
+	friend class TextureImpl;
 
 
-	/// Protect the m_bindlessIndices.
-	mutable SpinLock m_lock;
+public:
+	MicroImageView() = default;
 
 
-	/// Because for example a single surface view of a cube texture will be a 2D view.
-	TextureType m_derivedTextureType = TextureType::COUNT;
+	MicroImageView(MicroImageView&& b)
+	{
+		*this = std::move(b);
+	}
 
 
-	MicroImageView()
+	~MicroImageView()
 	{
 	{
 		for(U32 idx : m_bindlessIndices)
 		for(U32 idx : m_bindlessIndices)
 		{
 		{
@@ -56,18 +53,44 @@ public:
 		ANKI_ASSERT(m_handle == VK_NULL_HANDLE);
 		ANKI_ASSERT(m_handle == VK_NULL_HANDLE);
 	}
 	}
 
 
-	MicroImageView(const MicroImageView& b)
-	{
-		*this = std::move(b);
-	}
-
-	MicroImageView& operator=(const MicroImageView& b)
+	MicroImageView& operator=(MicroImageView&& b)
 	{
 	{
 		m_handle = b.m_handle;
 		m_handle = b.m_handle;
+		b.m_handle = VK_NULL_HANDLE;
 		m_bindlessIndices = b.m_bindlessIndices;
 		m_bindlessIndices = b.m_bindlessIndices;
+		b.m_bindlessIndices = {MAX_U32, MAX_U32};
 		m_derivedTextureType = b.m_derivedTextureType;
 		m_derivedTextureType = b.m_derivedTextureType;
+		b.m_derivedTextureType = TextureType::COUNT;
 		return *this;
 		return *this;
 	}
 	}
+
+	VkImageView getHandle() const
+	{
+		ANKI_ASSERT(m_handle);
+		return m_handle;
+	}
+
+	/// @note It's thread-safe.
+	U32 getOrCreateBindlessIndex(VkImageLayout layout, GrManagerImpl& gr) const;
+
+	TextureType getDerivedTextureType() const
+	{
+		ANKI_ASSERT(m_derivedTextureType != TextureType::COUNT);
+		return m_derivedTextureType;
+	}
+
+private:
+	VkImageView m_handle = VK_NULL_HANDLE;
+
+	/// Index 0: Sampled image with SHADER_READ_ONLY layout.
+	/// Index 1: Storage image with ofcource GENERAL layout.
+	mutable Array<U32, 2> m_bindlessIndices = {MAX_U32, MAX_U32};
+
+	/// Protect the m_bindlessIndices.
+	mutable SpinLock m_lock;
+
+	/// Because for example a single surface view of a cube texture will be a 2D view.
+	TextureType m_derivedTextureType = TextureType::COUNT;
 };
 };
 
 
 /// Texture container.
 /// Texture container.

+ 2 - 2
AnKi/Gr/Vulkan/TextureView.cpp

@@ -27,14 +27,14 @@ U32 TextureView::getOrCreateBindlessTextureIndex()
 	ANKI_VK_SELF(TextureViewImpl);
 	ANKI_VK_SELF(TextureViewImpl);
 	ANKI_ASSERT(self.getTextureImpl().computeLayout(TextureUsageBit::ALL_SAMPLED, 0)
 	ANKI_ASSERT(self.getTextureImpl().computeLayout(TextureUsageBit::ALL_SAMPLED, 0)
 				== VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
 				== VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-	return self.getOrCreateBindlessIndex(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, DescriptorType::TEXTURE);
+	return self.getOrCreateBindlessIndex(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
 }
 }
 
 
 U32 TextureView::getOrCreateBindlessImageIndex()
 U32 TextureView::getOrCreateBindlessImageIndex()
 {
 {
 	ANKI_VK_SELF(TextureViewImpl);
 	ANKI_VK_SELF(TextureViewImpl);
 	ANKI_ASSERT(self.getTextureImpl().computeLayout(TextureUsageBit::ALL_IMAGE, 0) == VK_IMAGE_LAYOUT_GENERAL);
 	ANKI_ASSERT(self.getTextureImpl().computeLayout(TextureUsageBit::ALL_IMAGE, 0) == VK_IMAGE_LAYOUT_GENERAL);
-	return self.getOrCreateBindlessIndex(VK_IMAGE_LAYOUT_GENERAL, DescriptorType::IMAGE);
+	return self.getOrCreateBindlessIndex(VK_IMAGE_LAYOUT_GENERAL);
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 8 - 38
AnKi/Gr/Vulkan/TextureViewImpl.cpp

@@ -27,8 +27,8 @@ Error TextureViewImpl::init(const TextureViewInitInfo& inf)
 
 
 	// Ask the texture for a view
 	// Ask the texture for a view
 	m_microImageView = &tex.getOrCreateView(inf);
 	m_microImageView = &tex.getOrCreateView(inf);
-	m_handle = m_microImageView->m_handle;
-	m_texType = m_microImageView->m_derivedTextureType;
+	m_handle = m_microImageView->getHandle();
+	m_texType = m_microImageView->getDerivedTextureType();
 
 
 	// Create the hash
 	// Create the hash
 	Array<U64, 2> toHash = {tex.getUuid(), ptrToNumber(m_handle)};
 	Array<U64, 2> toHash = {tex.getUuid(), ptrToNumber(m_handle)};
@@ -37,47 +37,17 @@ Error TextureViewImpl::init(const TextureViewInitInfo& inf)
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-U32 TextureViewImpl::getOrCreateBindlessIndex(VkImageLayout layout, DescriptorType resourceType)
+U32 TextureViewImpl::getOrCreateBindlessIndex(VkImageLayout layout)
 {
 {
-	ANKI_ASSERT(layout == VK_IMAGE_LAYOUT_GENERAL || layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-	ANKI_ASSERT(resourceType == DescriptorType::TEXTURE || resourceType == DescriptorType::IMAGE);
-	if(resourceType == DescriptorType::IMAGE)
-	{
-		ANKI_ASSERT(layout == VK_IMAGE_LAYOUT_GENERAL);
-	}
-	else
-	{
-		ANKI_ASSERT(layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-	}
-
-	ANKI_ASSERT(m_microImageView);
-
-	const U32 arrayIdx = (resourceType == DescriptorType::IMAGE) ? 1 : 0;
+	const U32 arrayIdx = (layout == VK_IMAGE_LAYOUT_GENERAL) ? 1 : 0;
+	U32& bindlessIdx = m_bindlessIndices[arrayIdx];
 
 
-	LockGuard<SpinLock> lock(m_microImageView->m_lock);
-
-	U32 outIdx;
-	if(m_microImageView->m_bindlessIndices[arrayIdx] != MAX_U32)
-	{
-		outIdx = m_microImageView->m_bindlessIndices[arrayIdx];
-	}
-	else
+	if(bindlessIdx == MAX_U32)
 	{
 	{
-		// Needs binding to the bindless descriptor set
-
-		if(resourceType == DescriptorType::TEXTURE)
-		{
-			outIdx = getGrManagerImpl().getDescriptorSetFactory().bindBindlessTexture(m_handle, layout);
-		}
-		else
-		{
-			outIdx = getGrManagerImpl().getDescriptorSetFactory().bindBindlessImage(m_handle);
-		}
-
-		m_microImageView->m_bindlessIndices[arrayIdx] = outIdx;
+		bindlessIdx = m_microImageView->getOrCreateBindlessIndex(layout, getGrManagerImpl());
 	}
 	}
 
 
-	return outIdx;
+	return bindlessIdx;
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 4 - 4
AnKi/Gr/Vulkan/TextureViewImpl.h

@@ -52,12 +52,12 @@ public:
 		return static_cast<const TextureImpl&>(*m_tex);
 		return static_cast<const TextureImpl&>(*m_tex);
 	}
 	}
 
 
-	/// @param resourceType Texture or image.
-	/// @note It's thread-safe.
-	U32 getOrCreateBindlessIndex(VkImageLayout layout, DescriptorType resourceType);
+	U32 getOrCreateBindlessIndex(VkImageLayout layout);
 
 
 private:
 private:
-	VkImageView m_handle = {}; /// Cache the handle.
+	VkImageView m_handle = {}; ///< Cache the handle.
+
+	Array<U32, 2> m_bindlessIndices = {MAX_U32, MAX_U32}; ///< Cache it.
 
 
 	/// This is a hash that depends on the Texture and the VkImageView. It's used as a replacement of
 	/// This is a hash that depends on the Texture and the VkImageView. It's used as a replacement of
 	/// TextureView::m_uuid since it creates less unique IDs.
 	/// TextureView::m_uuid since it creates less unique IDs.

+ 2 - 2
AnKi/ShaderCompiler/ShaderProgramParser.cpp

@@ -57,8 +57,8 @@ static const char* SHADER_HEADER = R"(#version 460 core
 #extension GL_EXT_nonuniform_qualifier : enable
 #extension GL_EXT_nonuniform_qualifier : enable
 #extension GL_EXT_scalar_block_layout : enable
 #extension GL_EXT_scalar_block_layout : enable
 
 
-#define ANKI_MAX_BINDLESS_TEXTURES %u
-#define ANKI_MAX_BINDLESS_IMAGES %u
+#define ANKI_MAX_BINDLESS_TEXTURES %uu
+#define ANKI_MAX_BINDLESS_IMAGES %uu
 
 
 #if defined(ANKI_RAY_GEN_SHADER) || defined(ANKI_ANY_HIT_SHADER) || defined(ANKI_CLOSEST_HIT_SHADER) || defined(ANKI_MISS_SHADER) || defined(ANKI_INTERSECTION_SHADER) || defined(ANKI_CALLABLE_SHADER)
 #if defined(ANKI_RAY_GEN_SHADER) || defined(ANKI_ANY_HIT_SHADER) || defined(ANKI_CLOSEST_HIT_SHADER) || defined(ANKI_MISS_SHADER) || defined(ANKI_INTERSECTION_SHADER) || defined(ANKI_CALLABLE_SHADER)
 #	extension GL_EXT_ray_tracing : enable
 #	extension GL_EXT_ray_tracing : enable

+ 2 - 2
AnKi/Util/StdTypes.h

@@ -269,12 +269,12 @@ static constexpr unsigned long long int operator""_GB(unsigned long long int x)
 /// @{
 /// @{
 static constexpr Second operator""_ms(long double x)
 static constexpr Second operator""_ms(long double x)
 {
 {
-	return x / 1000.0;
+	return Second(x) / 1000.0;
 }
 }
 
 
 static constexpr Second operator""_ns(long double x)
 static constexpr Second operator""_ns(long double x)
 {
 {
-	return x / 1000000000.0;
+	return Second(x) / 1000000000.0;
 }
 }
 /// @}
 /// @}
 
 

+ 4 - 2
Tests/Gr/Gr.cpp

@@ -364,7 +364,9 @@ static ShaderPtr createShader(CString src, ShaderType type, GrManager& gr,
 {
 {
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	StringAuto header(alloc);
 	StringAuto header(alloc);
-	ShaderProgramParser::generateAnkiShaderHeader(type, ShaderCompilerOptions(), header);
+	ShaderCompilerOptions compilerOptions;
+	compilerOptions.m_bindlessLimits = gr.getBindlessLimits();
+	ShaderProgramParser::generateAnkiShaderHeader(type, compilerOptions, header);
 	header.append(src);
 	header.append(src);
 	DynamicArrayAuto<U8> spirv(alloc);
 	DynamicArrayAuto<U8> spirv(alloc);
 	ANKI_TEST_EXPECT_NO_ERR(compilerGlslToSpirv(header, type, alloc, spirv));
 	ANKI_TEST_EXPECT_NO_ERR(compilerGlslToSpirv(header, type, alloc, spirv));
@@ -2188,7 +2190,7 @@ ANKI_TEST(Gr, Bindless)
 	static const char* PROG_SRC = R"(
 	static const char* PROG_SRC = R"(
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 
 
-ANKI_BINDLESS_SET(0);
+ANKI_BINDLESS_SET(0u);
 
 
 layout(set = 1, binding = 0) writeonly buffer ss_
 layout(set = 1, binding = 0) writeonly buffer ss_
 {
 {