瀏覽代碼

Fix some validation errors

Panagiotis Christopoulos Charitos 1 月之前
父節點
當前提交
d7a04af03f

+ 4 - 13
AnKi/Gr/Common.h

@@ -245,14 +245,13 @@ using GrAllocator = HeapAllocator<T>;
 class GrBaseInitInfo
 {
 public:
-	/// @name The name of the object.
+	// The name of the object
 	GrBaseInitInfo(CString name)
 	{
 		setName(name);
 	}
 
 	GrBaseInitInfo()
-		: GrBaseInitInfo(CString())
 	{
 	}
 
@@ -269,24 +268,16 @@ public:
 
 	CString getName() const
 	{
-		return (m_name[0] != '\0') ? CString(&m_name[0]) : CString();
+		return m_name;
 	}
 
 	void setName(CString name)
 	{
-		// Zero it because the derived classes may be hashed.
-		zeroMemory(m_name);
-
-		U32 len;
-		if(name && (len = name.getLength()) > 0)
-		{
-			len = min(len, kMaxGrObjectNameLength);
-			memcpy(&m_name[0], &name[0], len);
-		}
+		m_name = (name.getLength()) ? name : "N/A";
 	}
 
 private:
-	Array<char, kMaxGrObjectNameLength + 1> m_name;
+	GrString m_name;
 };
 
 enum class ColorBit : U8

+ 14 - 16
AnKi/Gr/Sampler.h

@@ -9,11 +9,8 @@
 
 namespace anki {
 
-/// @addtogroup graphics
-/// @{
-
-/// Sampler initializer.
-class alignas(4) SamplerInitInfo : public GrBaseInitInfo
+// Sampler initializer
+class SamplerInitInfo : public GrBaseInitInfo
 {
 public:
 	F32 m_minLod = -1000.0f;
@@ -24,7 +21,6 @@ public:
 	CompareOperation m_compareOperation = CompareOperation::kAlways;
 	U8 m_anisotropyLevel = 0;
 	SamplingAddressing m_addressing = SamplingAddressing::kRepeat;
-	U8 _m_padding[3] = {0, 0, 0};
 
 	SamplerInitInfo() = default;
 
@@ -35,15 +31,21 @@ public:
 
 	U64 computeHash() const
 	{
-		const U8* first = reinterpret_cast<const U8*>(&m_minLod);
-		const U8* last = reinterpret_cast<const U8*>(&m_addressing) + sizeof(m_addressing);
-		const U32 size = U32(last - first);
-		ANKI_ASSERT(size == sizeof(F32) * 3 + sizeof(SamplingFilter) * 2 + sizeof(CompareOperation) + sizeof(I8) + sizeof(SamplingAddressing));
-		return anki::computeHash(first, size);
+		Array<U32, 8> arr;
+		U32 count = 0;
+		arr[count++] = asU32(m_minLod);
+		arr[count++] = asU32(m_maxLod);
+		arr[count++] = asU32(m_lodBias);
+		arr[count++] = U32(m_minMagFilter);
+		arr[count++] = U32(m_mipmapFilter);
+		arr[count++] = U32(m_compareOperation);
+		arr[count++] = m_anisotropyLevel;
+		arr[count++] = U32(m_addressing);
+		return computeObjectHash(arr);
 	}
 };
 
-/// GPU sampler.
+// GPU sampler
 class Sampler : public GrObject
 {
 	ANKI_GR_OBJECT
@@ -52,21 +54,17 @@ public:
 	static constexpr GrObjectType kClassType = GrObjectType::kSampler;
 
 protected:
-	/// Construct.
 	Sampler(CString name)
 		: GrObject(kClassType, name)
 	{
 	}
 
-	/// Destroy.
 	~Sampler()
 	{
 	}
 
 private:
-	/// Allocate and initialize a new instance.
 	[[nodiscard]] static Sampler* newInstance(const SamplerInitInfo& init);
 };
-/// @}
 
 } // end namespace anki

+ 13 - 10
AnKi/Gr/Texture.h

@@ -16,7 +16,7 @@ class TextureSubresourceDesc;
 /// @{
 
 /// Texture initializer.
-class alignas(4) TextureInitInfo : public GrBaseInitInfo
+class TextureInitInfo : public GrBaseInitInfo
 {
 public:
 	U32 m_width = 0;
@@ -33,8 +33,6 @@ public:
 
 	U8 m_samples = 1;
 
-	U8 _m_padding[1] = {0};
-
 	TextureInitInfo() = default;
 
 	TextureInitInfo(CString name)
@@ -44,13 +42,18 @@ public:
 
 	U64 computeHash() const
 	{
-		const U8* first = reinterpret_cast<const U8*>(&m_width);
-		const U8* last = reinterpret_cast<const U8*>(&m_samples) + sizeof(m_samples);
-		const U size = U(last - first);
-		ANKI_ASSERT(size
-					== sizeof(m_width) + sizeof(m_height) + sizeof(m_depth) + sizeof(m_layerCount) + sizeof(m_format) + sizeof(m_usage)
-						   + sizeof(m_type) + sizeof(m_mipmapCount) + sizeof(m_samples));
-		return anki::computeHash(first, size);
+		Array<U64, 9> arr;
+		U32 count = 0;
+		arr[count++] = m_width;
+		arr[count++] = m_height;
+		arr[count++] = m_depth;
+		arr[count++] = m_layerCount;
+		arr[count++] = U64(m_format);
+		arr[count++] = U64(m_usage);
+		arr[count++] = U64(m_type);
+		arr[count++] = m_mipmapCount;
+		arr[count++] = m_samples;
+		return computeObjectHash(arr);
 	}
 
 	Bool isValid() const

+ 6 - 0
AnKi/Gr/Vulkan/VkGrManager.cpp

@@ -1712,6 +1712,12 @@ VkBool32 GrManagerImpl::debugReportCallbackEXT(VkDebugUtilsMessageSeverityFlagBi
 		return false;
 	}
 
+	if(pCallbackData->messageIdNumber == -1094381206)
+	{
+		// Complains that CullPrimitiveEXT is not a bool array, which is wrong
+		return false;
+	}
+
 	// Get all names of affected objects
 	GrString objectNames;
 	if(pCallbackData->objectCount)

+ 1 - 1
AnKi/Renderer/Bloom.cpp

@@ -58,7 +58,7 @@ Error Bloom::init()
 		ANKI_CHECK(loadShaderProgram("ShaderBinaries/Bloom.ankiprogbin", {}, m_prog, m_upscaleGrProg, "Upscale"));
 
 		// Textures
-		ANKI_CHECK(ResourceManager::getSingleton().loadResource("EngineAssets/LensDirt.ankitex", m_lensDirtImg));
+		ANKI_CHECK(ResourceManager::getSingleton().loadResource("EngineAssets/LensDirt.ankitex", m_lensDirtImg, false));
 	}
 
 	return Error::kNone;

+ 5 - 8
AnKi/Resource/ImageResource.cpp

@@ -63,7 +63,6 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 
 	TextureInitInfo init(filenameExt);
 	init.m_usage = TextureUsageBit::kAllSrv | TextureUsageBit::kCopyDestination;
-	U32 faces = 0;
 
 	ResourceFilePtr file;
 	ANKI_CHECK(openFile(filename, file));
@@ -81,26 +80,22 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	case ImageBinaryType::k2D:
 		init.m_type = TextureType::k2D;
 		init.m_depth = 1;
-		faces = 1;
 		init.m_layerCount = 1;
 		break;
 	case ImageBinaryType::kCube:
 		init.m_type = TextureType::kCube;
 		init.m_depth = 1;
-		faces = 6;
 		init.m_layerCount = 1;
 		break;
 	case ImageBinaryType::k2DArray:
 		init.m_type = TextureType::k2DArray;
 		init.m_layerCount = loader.getLayerCount();
 		init.m_depth = 1;
-		faces = 1;
 		break;
 	case ImageBinaryType::k3D:
 		init.m_type = TextureType::k3D;
 		init.m_depth = loader.getDepth();
 		init.m_layerCount = 1;
-		faces = 1;
 		break;
 	default:
 		ANKI_ASSERT(0);
@@ -194,6 +189,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 
 	// mipmapsCount
 	init.m_mipmapCount = U8(loader.getMipmapCount());
+	m_pendingLoadedMips.setNonAtomically(init.m_mipmapCount);
 
 	// Create the texture
 	m_tex = GrManager::getSingleton().newTexture(init);
@@ -235,7 +231,7 @@ Error ImageResource::loadAsync(LoadingContext& ctx) const
 			U32 mip, layer, face;
 			unflatten3dArrayIndex(m_tex->getLayerCount(), faceCount, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
 
-			barriers[barrierCount++] = {TextureView(m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)), TextureUsageBit::kAllSrv,
+			barriers[barrierCount++] = {TextureView(m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)), TextureUsageBit::kNone,
 										TextureUsageBit::kCopyDestination};
 		}
 		cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
@@ -290,7 +286,7 @@ Error ImageResource::loadAsync(LoadingContext& ctx) const
 			unflatten3dArrayIndex(m_tex->getLayerCount(), faceCount, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
 
 			barriers[barrierCount++] = {TextureView(m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)),
-										TextureUsageBit::kCopyDestination, TextureUsageBit::kSrvPixel | TextureUsageBit::kSrvGeometry};
+										TextureUsageBit::kCopyDestination, TextureUsageBit::kAllSrv};
 		}
 		cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
 
@@ -306,7 +302,8 @@ Error ImageResource::loadAsync(LoadingContext& ctx) const
 		cmdb.reset(nullptr);
 	}
 
-	m_loadedMipCount.store(m_tex->getMipmapCount());
+	[[maybe_unused]] const U32 prevVal = m_pendingLoadedMips.fetchSub(m_tex->getMipmapCount());
+	ANKI_ASSERT(prevVal == m_tex->getMipmapCount());
 	return Error::kNone;
 }
 

+ 2 - 2
AnKi/Resource/ImageResource.h

@@ -43,7 +43,7 @@ public:
 
 	Bool isLoaded() const
 	{
-		return m_loadedMipCount.load() == m_tex->getMipmapCount();
+		return m_pendingLoadedMips.load() == 0;
 	}
 
 private:
@@ -56,7 +56,7 @@ private:
 
 	Vec4 m_avgColor = Vec4(0.0f);
 
-	mutable Atomic<U32> m_loadedMipCount = {0};
+	mutable Atomic<U32> m_pendingLoadedMips = {0};
 
 	Error loadAsync(LoadingContext& ctx) const;
 };

+ 14 - 1
AnKi/Resource/MaterialResource.cpp

@@ -651,7 +651,15 @@ const MaterialVariant& MaterialResource::getOrCreateVariant(const RenderingKey&
 
 Bool MaterialResource::isLoaded() const
 {
-	Bool loaded = true;
+	// Check the atomic first
+	U32 loaded = m_loaded.load();
+	if(loaded) [[likely]]
+	{
+		return true;
+	}
+
+	// Do expensive check after
+	loaded = 1;
 	for(const MaterialVariable& var : m_vars)
 	{
 		if(var.m_image)
@@ -660,6 +668,11 @@ Bool MaterialResource::isLoaded() const
 		}
 	}
 
+	if(loaded)
+	{
+		m_loaded.store(1);
+	}
+
 	return loaded;
 }
 

+ 2 - 0
AnKi/Resource/MaterialResource.h

@@ -260,6 +260,8 @@ private:
 	RenderingTechniqueBit m_techniquesMask = RenderingTechniqueBit::kNone;
 	ShaderTechniqueBit m_shaderTechniques = ShaderTechniqueBit::kNone;
 
+	mutable Atomic<U32> m_loaded = {0};
+
 	Error parseMutators(XmlElement mutatorsEl);
 	Error parseShaderProgram(XmlElement techniqueEl, Bool async);
 	Error parseInput(XmlElement inputEl, Bool async, BitSet<128>& varsSet);

+ 1 - 1
AnKi/Resource/ParticleEmitterResource2.h

@@ -64,7 +64,7 @@ public:
 // This is the a particle emitter resource containing shader and properties.
 // XML format:
 //	<particleEmitter>
-//		<shaderProgram name="name of the shader" />
+//		<shaderProgram name="name of the shader">
 //			[<mutation>
 //				<mutator name="str" value="value"/>
 //			</mutation>]

+ 6 - 3
AnKi/Resource/ShaderProgramResource.cpp

@@ -156,6 +156,7 @@ ShaderProgramResourceVariant* ShaderProgramResource::createNewVariant(const Shad
 {
 	// Get the binary program variant
 	const ShaderBinaryVariant* binaryVariant = nullptr;
+	U32 binaryVariantIdx = kMaxU32;
 	U64 mutationHash = 0;
 	if(m_binary->m_mutators.getSize())
 	{
@@ -174,6 +175,7 @@ ShaderProgramResourceVariant* ShaderProgramResource::createNewVariant(const Shad
 					return nullptr;
 				}
 
+				binaryVariantIdx = mutation.m_variantIndex;
 				binaryVariant = &m_binary->m_variants[mutation.m_variantIndex];
 				break;
 			}
@@ -194,10 +196,11 @@ ShaderProgramResourceVariant* ShaderProgramResource::createNewVariant(const Shad
 		String fname;
 		getFilepathFilename(getFilename(), fname);
 
-		ResourceString progName = fname.cstr();
+		ResourceString progName;
+		progName.sprintf("%s var%05u", fname.cstr(), binaryVariantIdx);
 		for(ShaderType shaderType : EnumBitsIterable<ShaderType, ShaderTypeBit>(info.m_shaderTypes))
 		{
-			progName += "_";
+			progName += " ";
 			progName += info.m_techniqueNames[shaderType].getBegin();
 		}
 
@@ -210,7 +213,7 @@ ShaderProgramResourceVariant* ShaderProgramResource::createNewVariant(const Shad
 			const U32 techniqueIdx = findTechnique(info.m_techniqueNames[shaderType].getBegin());
 			ANKI_ASSERT(!!(m_binary->m_techniques[techniqueIdx].m_shaderTypes & shaderBit));
 
-			const ResourceString shaderName = (progName + "_" + m_binary->m_techniques[techniqueIdx].m_name.getBegin()).cstr();
+			const ResourceString shaderName = (progName + " " + m_binary->m_techniques[techniqueIdx].m_name.getBegin()).cstr();
 			ShaderInitInfo inf(shaderName);
 			inf.m_shaderType = shaderType;
 			const ShaderBinaryCodeBlock& binBlock =

+ 1 - 1
AnKi/Shaders/GBufferGeneric.ankiprog

@@ -373,7 +373,7 @@ main(U32 svGroupId : SV_GROUPID, U32 svGroupIndex : SV_GROUPINDEX, out vertices
 #	endif
 
 #	if REALLY_VELOCITY
-			velocity(worldTransform, prevWorldTransform, prevPos, output.m_svPosition, output.m_prevClipXyw, output.m_prevClipXyw);
+			velocity(worldTransform, prevWorldTransform, prevPos, output.m_svPosition, output.m_prevClipXyw, output.m_crntClipXyw);
 #	endif
 
 			verts[idx] = output;

+ 3 - 2
AnKi/Ui/UiCanvas.cpp

@@ -529,7 +529,8 @@ void UiCanvas::endBuilding()
 
 				tex->SetStatus(ImTextureStatus_OK);
 			}
-			else if(status == ImTextureStatus_WantDestroy && tex->UnusedFrames >= kMaxFramesInFlight + 2) // kMaxFramesInFlight + 2 to be 100% sure
+			else if(status == ImTextureStatus_WantDestroy
+					&& tex->UnusedFrames >= I32(kMaxFramesInFlight + 2)) // kMaxFramesInFlight + 2 to be 100% sure
 			{
 				ImTextureID id = tex->GetTexID();
 				ANKI_ASSERT(id.m_textureIsRefcounted);
@@ -577,7 +578,7 @@ void UiCanvas::appendGraphicsCommands(CommandBuffer& cmdb) const
 		ImDrawIdx* indices;
 		indicesToken = RebarTransientMemoryPool::getSingleton().allocate(drawData.TotalIdxCount * sizeof(ImDrawIdx), sizeof(ImDrawIdx), indices);
 
-		for(I n = 0; n < drawData.CmdListsCount; ++n)
+		for(I32 n = 0; n < drawData.CmdListsCount; ++n)
 		{
 			const ImDrawList& cmdList = *drawData.CmdLists[n];
 			memcpy(verts, cmdList.VtxBuffer.Data, cmdList.VtxBuffer.Size * sizeof(ImDrawVert));

+ 58 - 57
AnKi/Util/StdTypes.h

@@ -8,79 +8,77 @@
 #include <AnKi/Util/Common.h>
 #include <cstdint>
 #include <cstddef>
+#include <cstring>
 #include <limits>
 #include <type_traits>
 
 namespace anki {
 
-/// @addtogroup util_other
-/// @{
-
-using I8 = int8_t; ///< Integer 8bit
+using I8 = int8_t; // Integer 8bit
 constexpr I8 kMaxI8 = std::numeric_limits<I8>::max();
 constexpr I8 kMinI8 = std::numeric_limits<I8>::min();
 
-using I16 = int16_t; ///< Integer 16bit
+using I16 = int16_t; // Integer 16bit
 constexpr I16 kMaxI16 = std::numeric_limits<I16>::max();
 constexpr I16 kMinI16 = std::numeric_limits<I16>::min();
 
-using I32 = int32_t; ///< Integer 32bit
+using I32 = int32_t; // Integer 32bit
 constexpr I32 kMaxI32 = std::numeric_limits<I32>::max();
 constexpr I32 kMinI32 = std::numeric_limits<I32>::min();
 
-using I64 = int64_t; ///< Integer 64bit
+using I64 = int64_t; // Integer 64bit
 constexpr I64 kMaxI64 = std::numeric_limits<I64>::max();
 constexpr I64 kMinI64 = std::numeric_limits<I64>::min();
 
-using I = int_fast32_t; ///< Fast signed integer at least 32bit
+using I = int_fast32_t; // Fast signed integer at least 32bit
 constexpr I kMaxI = std::numeric_limits<I>::max();
 constexpr I kMinI = std::numeric_limits<I>::min();
 
-using U8 = uint8_t; ///< Unsigned integer 8bit
+using U8 = uint8_t; // Unsigned integer 8bit
 constexpr U8 kMaxU8 = std::numeric_limits<U8>::max();
 constexpr U8 kMinU8 = std::numeric_limits<U8>::min();
 
-using U16 = uint16_t; ///< Unsigned integer 16bit
+using U16 = uint16_t; // Unsigned integer 16bit
 constexpr U16 kMaxU16 = std::numeric_limits<U16>::max();
 constexpr U16 kMinU16 = std::numeric_limits<U16>::min();
 
-using U32 = uint32_t; ///< Unsigned integer 32bit
+using U32 = uint32_t; // Unsigned integer 32bit
 constexpr U32 kMaxU32 = std::numeric_limits<U32>::max();
 constexpr U32 kMinU32 = std::numeric_limits<U32>::min();
 
-using U64 = uint64_t; ///< Unsigned integer 64bit
+using U64 = uint64_t; // Unsigned integer 64bit
 constexpr U64 kMaxU64 = std::numeric_limits<U64>::max();
 constexpr U64 kMinU64 = std::numeric_limits<U64>::min();
 
-using U = uint_fast32_t; ///< Fast unsigned integer at least 32bit
+using U = uint_fast32_t; // Fast unsigned integer at least 32bit
 constexpr U kMaxU = std::numeric_limits<U>::max();
 constexpr U kMinU = std::numeric_limits<U>::min();
 
-using PtrSize = size_t; ///< Like size_t
+using PtrSize = size_t; // Like size_t
 constexpr PtrSize kMaxPtrSize = std::numeric_limits<PtrSize>::max();
 constexpr PtrSize kMinPtrSize = std::numeric_limits<PtrSize>::min();
 static_assert(sizeof(PtrSize) == sizeof(void*), "Wrong size for size_t");
 
-using F32 = float; ///< Floating point 32bit
+using F32 = float; // Floating point 32bit
 constexpr F32 kMaxF32 = std::numeric_limits<F32>::max();
 constexpr F32 kMinF32 = -std::numeric_limits<F32>::max();
 
-using F64 = double; ///< Floating point 64bit
+using F64 = double; // Floating point 64bit
 constexpr F64 kMaxF64 = std::numeric_limits<F64>::max();
 constexpr F64 kMinF64 = -std::numeric_limits<F64>::max();
 
-using Bool = bool; ///< 1 byte boolean type. The same as C++'s bool.
+using Bool = bool; // 1 byte boolean type. The same as C++'s bool.
 static_assert(sizeof(bool) == 1, "Wrong size for bool");
 
 using Bool32 = I32;
 using Char = char;
 using WChar = wchar_t;
 
-using Second = F64; ///< The base time unit is second.
+using Second = F64; // The base time unit is second.
 constexpr Second kMaxSecond = kMaxF64;
 constexpr Second kMinSecond = kMinF64;
 
-using Timestamp = U64; ///< Timestamp type.
+using Timestamp = U64; // Timestamp type.
 constexpr Timestamp kMaxTimestamp = kMaxU64;
 
 // Numeric limits
@@ -115,68 +113,60 @@ ANKI_DO_LIMIT(F64, kMinF64, kMaxF64)
 
 #undef ANKI_DO_LIMIT
 
-/// Representation of error and a wrapper on top of error codes.
+// Representation of error and a wrapper on top of error codes.
 class [[nodiscard]] Error
 {
 public:
-	/// @name Error codes
-	/// @{
+	// Error codes
 	static constexpr I32 kNone = 0;
 	static constexpr I32 kOutOfMemory = 1;
-	static constexpr I32 kFunctionFailed = 2; ///< External operation failed
+	static constexpr I32 kFunctionFailed = 2; // External operation failed
 	static constexpr I32 kUserData = 3;
 
 	// File errors
 	static constexpr I32 kFileNotFound = 4;
-	static constexpr I32 kFileAccess = 5; ///< Read/write access error
+	static constexpr I32 kFileAccess = 5; // Read/write access error
 
 	static constexpr I32 kUnknown = 6;
-	/// @}
 
-	/// Construct using an error code.
+	// Construct using an error code.
 	Error(I32 code)
 		: m_code(code)
 	{
 	}
 
-	/// Copy.
 	Error(const Error& b)
 		: m_code(b.m_code)
 	{
 	}
 
-	/// Copy.
 	Error& operator=(const Error& b)
 	{
 		m_code = b.m_code;
 		return *this;
 	}
 
-	/// Compare.
 	Bool operator==(const Error& b) const
 	{
 		return m_code == b.m_code;
 	}
 
-	/// Compare.
 	Bool operator==(I32 code) const
 	{
 		return m_code == code;
 	}
 
-	/// Compare.
 	Bool operator!=(const Error& b) const
 	{
 		return m_code != b.m_code;
 	}
 
-	/// Compare.
 	Bool operator!=(I32 code) const
 	{
 		return m_code != code;
 	}
 
-	/// Check if it is an error.
+	// Check if it is an error.
 	explicit operator Bool() const
 	{
 		if(m_code != kNone) [[unlikely]]
@@ -189,19 +179,17 @@ public:
 		}
 	}
 
-	/// @privatesection
-	/// @{
+	// Private
 	I32 _getCode() const
 	{
 		return m_code;
 	}
-	/// @}
 
 private:
 	I32 m_code = kNone;
 };
 
-/// Macro to check if a method/function returned an error. It will return on error.
+// Macro to check if a method/function returned an error. It will return on error.
 #define ANKI_CHECK(x_) \
 	do \
 	{ \
@@ -212,14 +200,14 @@ private:
 		} \
 	} while(0)
 
-/// Macro to check if a method/function returned an error. It will abort on error.
+// Macro to check if a method/function returned an error. It will abort on error.
 #define ANKI_CHECKF(x_) \
 	if(x_) \
 	{ \
 		ANKI_LOGF("Failed and won't recover"); \
 	}
 
-/// Macro to check if a method/function returned an error.
+// Macro to check if a method/function returned an error.
 #define ANKI_CHECK_AND_IGNORE(x_) \
 	do \
 	{ \
@@ -232,8 +220,7 @@ private:
 #	define ANKI_DEBUG_CODE(x)
 #endif
 
-/// @name AnKi type user literals.
-/// @{
+// AnKi type user literals.
 inline constexpr U8 operator""_U8(unsigned long long arg) noexcept
 {
 	return U8(arg);
@@ -258,10 +245,8 @@ inline constexpr PtrSize operator""_PtrSize(unsigned long long arg) noexcept
 {
 	return PtrSize(arg);
 }
-/// @}
 
-/// @name Size user literals
-/// @{
+// Size user literals
 inline constexpr PtrSize operator""_B(unsigned long long int x)
 {
 	return x;
@@ -281,10 +266,8 @@ inline constexpr PtrSize operator""_GB(unsigned long long int x)
 {
 	return x * (1024 * 1024 * 1024);
 }
-/// @}
 
-/// @name Time user literals
-/// @{
+// Time user literals
 inline constexpr Second operator""_hour(long double x)
 {
 	return Second(x) * 60.0;
@@ -304,10 +287,8 @@ inline constexpr Second operator""_ns(long double x)
 {
 	return Second(x) / 1000000000.0;
 }
-/// @}
 
-/// @name Distance user literals
-/// @{
+// Distance user literals
 inline constexpr F32 operator""_m(long double x)
 {
 	return F32(x);
@@ -327,29 +308,49 @@ inline constexpr F32 operator""_mm(long double x)
 {
 	return F32(x) / 1000.0f;
 }
-/// @}
 
-/// @name Other user literals
-/// @{
+// @name Other user literals
 inline constexpr F32 operator""_degrees(long double x)
 {
 	constexpr F32 kPi = 3.14159265358979323846f;
 	return F32(x) * (kPi / 180.0f);
 }
-/// @}
 
-/// Convenience macro that defines the type of a class.
+// Convenience macro that defines the type of a class.
 #define ANKI_DEFINE_CLASS_SELF(selfType) \
 	typedef auto _selfFn##selfType()->decltype(*this); \
 	using _SelfRef##selfType = decltype(((_selfFn##selfType*)0)()); \
 	using selfType = std::remove_reference<_SelfRef##selfType>::type;
 
-/// Instead of using bool to break a loop, which it's difficult to tell if it means stop or continue, use this enum
+// Instead of using bool to break a loop, which it's difficult to tell if it means stop or continue, use this enum
 enum class FunctorContinue
 {
 	kContinue,
 	kStop
 };
-/// @}
+
+// Same thing as HLSL's asfloat
+ANKI_FORCE_INLINE F32 asF32(U32 i)
+{
+	F32 out;
+	memcpy(&out, &i, 4);
+	return out;
+}
+
+// Same thing as HLSL's asfloat
+ANKI_FORCE_INLINE F32 asF32(I32 i)
+{
+	F32 out;
+	memcpy(&out, &i, 4);
+	return out;
+}
+
+// Same thing as HLSL's asuint
+ANKI_FORCE_INLINE U32 asU32(F32 f)
+{
+	U32 out;
+	memcpy(&out, &f, 4);
+	return out;
+}
 
 } // end namespace anki

+ 1 - 1
AnKi/Window/NativeWindowAndroid.cpp

@@ -66,7 +66,7 @@ NativeWindowAndroid::~NativeWindowAndroid()
 	m_nativeWindowAndroid = nullptr;
 }
 
-Error NativeWindowAndroid::initInternal(U32 targetFps, CString title)
+Error NativeWindowAndroid::initInternal(U32 targetFps, [[maybe_unused]] CString title)
 {
 	ANKI_WIND_LOGI("Initializing Android window");