Browse Source

Enable RTP on Android

Panagiotis Christopoulos Charitos 9 tháng trước cách đây
mục cha
commit
bc8a0ec50d

+ 23 - 24
AnKi/Gr/Vulkan/VkGrManager.cpp

@@ -1480,29 +1480,37 @@ void GrManagerImpl::printPipelineShaderInfo(VkPipeline ppline, CString name, U64
 
 Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString name, U64 hash) const
 {
-	if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties))
+	if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties) && Logger::getSingleton().verbosityEnabled())
 	{
-		GrStringList log;
-
 		VkPipelineInfoKHR pplineInf = {};
 		pplineInf.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
 		pplineInf.pipeline = ppline;
 		U32 executableCount = 0;
 		ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, nullptr));
 		GrDynamicArray<VkPipelineExecutablePropertiesKHR> executableProps;
-		executableProps.resize(executableCount);
-		for(VkPipelineExecutablePropertiesKHR& prop : executableProps)
+
+		LockGuard lock(m_shaderStatsMtx); // Lock so that all messages appear together
+
+		ANKI_VK_LOGV("Pipeline info \"%s\" (0x%016" PRIx64 "):", name.cstr(), hash);
+		if(executableCount > 0)
 		{
-			prop = {};
-			prop.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
+			executableProps.resize(executableCount);
+			for(VkPipelineExecutablePropertiesKHR& prop : executableProps)
+			{
+				prop = {};
+				prop.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
+			}
+			ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, &executableProps[0]));
+		}
+		else
+		{
+			ANKI_VK_LOGV("\tNo executable count!!!");
 		}
-		ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, &executableProps[0]));
 
-		log.pushBackSprintf("Pipeline info \"%s\" (0x%016" PRIx64 "): ", name.cstr(), hash);
 		for(U32 i = 0; i < executableCount; ++i)
 		{
 			const VkPipelineExecutablePropertiesKHR& p = executableProps[i];
-			log.pushBackSprintf("%s: ", p.description);
+			ANKI_VK_LOGV("\tDescription: %s, stages: 0x%X:", p.description, p.stages);
 
 			// Get stats
 			VkPipelineExecutableInfoKHR exeInf = {};
@@ -1527,33 +1535,24 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 				switch(ss.format)
 				{
 				case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
-					log.pushBackSprintf("%s: %u, ", ss.name, ss.value.b32);
+					ANKI_VK_LOGV("\t\t%s: %u", ss.name, ss.value.b32);
 					break;
 				case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
-					log.pushBackSprintf("%s: %" PRId64 ", ", ss.name, ss.value.i64);
+					ANKI_VK_LOGV("\t\t%s: %" PRId64, ss.name, ss.value.i64);
 					break;
 				case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
-					log.pushBackSprintf("%s: %" PRIu64 ", ", ss.name, ss.value.u64);
+					ANKI_VK_LOGV("\t\t%s: %" PRIu64, ss.name, ss.value.u64);
 					break;
 				case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
-					log.pushBackSprintf("%s: %f, ", ss.name, ss.value.f64);
+					ANKI_VK_LOGV("\t\t%s: %f", ss.name, ss.value.f64);
 					break;
 				default:
 					ANKI_ASSERT(0);
 				}
 			}
 
-			log.pushBackSprintf("Subgroup size: %u", p.subgroupSize);
-
-			if(i < executableCount - 1)
-			{
-				log.pushBack(", ");
-			}
+			ANKI_VK_LOGV("\t\tSubgroup size: %u", p.subgroupSize);
 		}
-
-		GrString finalLog;
-		log.join("", finalLog);
-		ANKI_VK_LOGV("%s", finalLog.cstr());
 	}
 
 	return Error::kNone;

+ 1 - 2
AnKi/Gr/Vulkan/VkGrManager.h

@@ -176,8 +176,7 @@ private:
 
 	VkDebugUtilsMessengerEXT m_debugUtilsMessager = VK_NULL_HANDLE;
 
-	mutable File m_shaderStatsFile;
-	mutable SpinLock m_shaderStatsFileMtx;
+	mutable SpinLock m_shaderStatsMtx;
 
 	/// @name Surface_related
 	/// @{

+ 2 - 0
AnKi/Gr/Vulkan/VkGraphicsState.cpp

@@ -367,6 +367,8 @@ void GraphicsPipelineFactory::flushState(GraphicsStateTracker& state, VkCommandB
 
 		ANKI_VK_CHECKF(vkCreateGraphicsPipelines(getVkDevice(), PipelineCache::getSingleton().m_cacheHandle, 1, &ci, nullptr, &pso));
 
+		getGrManagerImpl().printPipelineShaderInfo(pso, prog.getName());
+
 #if ANKI_PLATFORM_MOBILE
 		if(PipelineCache::getSingleton().m_globalCreatePipelineMtx)
 		{

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

@@ -398,6 +398,10 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 		ci.pGroups = &groups[0];
 		ci.maxPipelineRayRecursionDepth = inf.m_rayTracingShaders.m_maxRecursionDepth;
 		ci.layout = m_pplineLayout->getHandle();
+		if(!!(getGrManagerImpl().getExtensions() & VulkanExtensions::kKHR_pipeline_executable_properties))
+		{
+			ci.flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
+		}
 
 		{
 			ANKI_TRACE_SCOPED_EVENT(VkPipelineCreate);
@@ -420,6 +424,8 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 		void* mapped = m_rt.m_allHandlesBuff->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite);
 		memcpy(mapped, m_rt.m_allHandles.getBegin(), m_rt.m_allHandles.getSizeInBytes());
 		m_rt.m_allHandlesBuff->unmap();
+
+		getGrManagerImpl().printPipelineShaderInfo(m_rt.m_ppline, getName());
 	}
 
 	// Get shader sizes and a few other things

+ 54 - 18
AnKi/Resource/ResourceFilesystem.cpp

@@ -5,7 +5,6 @@
 
 #include <AnKi/Resource/ResourceFilesystem.h>
 #include <AnKi/Util/Filesystem.h>
-#include <AnKi/Util/CVarSet.h>
 #include <AnKi/Util/Tracer.h>
 #include <ZLib/contrib/minizip/unzip.h>
 #if ANKI_OS_ANDROID
@@ -14,11 +13,6 @@
 
 namespace anki {
 
-StringCVar g_dataPathsCVar("Rsrc", "DataPaths", ".",
-						   "The engine loads assets only in from these paths. Separate them with : (it's smart enough to identify drive letters in "
-						   "Windows). After a path you can add an optional | and what follows it is a number of words to include or exclude paths. "
-						   "eg. my_path|include_this,include_that,+exclude_this");
-
 static Error tokenizePath(CString path, ResourceString& actualPath, ResourceStringList& includedWords, ResourceStringList& excludedWords)
 {
 	ResourceStringList tokens;
@@ -282,6 +276,9 @@ Error ResourceFilesystem::init()
 #if ANKI_OS_ANDROID
 	// Add the external storage
 	ANKI_CHECK(addNewPath(g_androidApp->activity->externalDataPath, {}, {}));
+
+	// ...and then the apk assets
+	ANKI_CHECK(addNewPath(".apk assets", {}, {}));
 #endif
 
 	return Error::kNone;
@@ -367,6 +364,30 @@ Error ResourceFilesystem::addNewPath(CString filepath, const ResourceStringList&
 
 		path.m_isArchive = true;
 	}
+#if ANKI_OS_ANDROID
+	else if(filepath == ".apk assets")
+	{
+		File dirStructureFile;
+		ANKI_CHECK(dirStructureFile.open("DirStructure.txt", FileOpenFlag::kRead | FileOpenFlag::kSpecial));
+
+		ResourceString fileTxt;
+		ANKI_CHECK(dirStructureFile.readAllText(fileTxt));
+
+		ResourceStringList lines;
+		lines.splitString(fileTxt, '\n');
+
+		for(const auto& line : lines)
+		{
+			if(includePath(line))
+			{
+				path.m_files.pushBack(line);
+				++fileCount;
+			}
+		}
+
+		path.m_isSpecial = true;
+	}
+#endif
 	else
 	{
 		// It's simple directory
@@ -427,6 +448,7 @@ Error ResourceFilesystem::openFile(const ResourceFilename& filename, ResourceFil
 
 Error ResourceFilesystem::openFileInternal(const ResourceFilename& filename, ResourceFile*& rfile) const
 {
+	ANKI_RESOURCE_LOGV("Opening resource file: %s", filename.cstr());
 	rfile = nullptr;
 
 	// Search for the fname in reverse order
@@ -450,11 +472,25 @@ Error ResourceFilesystem::openFileInternal(const ResourceFilename& filename, Res
 			else
 			{
 				ResourceString newFname;
-				newFname.sprintf("%s/%s", &p.m_path[0], &filename[0]);
+				if(!p.m_isSpecial)
+				{
+					newFname.sprintf("%s/%s", &p.m_path[0], &filename[0]);
+				}
+				else
+				{
+					newFname = filename;
+				}
 
 				CResourceFile* file = newInstance<CResourceFile>(ResourceMemoryPool::getSingleton());
 				rfile = file;
-				ANKI_CHECK(file->m_file.open(newFname, FileOpenFlag::kRead));
+
+				FileOpenFlag openFlags = FileOpenFlag::kRead;
+				if(p.m_isSpecial)
+				{
+					openFlags |= FileOpenFlag::kSpecial;
+				}
+
+				ANKI_CHECK(file->m_file.open(newFname, openFlags));
 
 #if 0
 				printf("Opening asset %s\n", &newFname[0]);
@@ -468,22 +504,22 @@ Error ResourceFilesystem::openFileInternal(const ResourceFilename& filename, Res
 		}
 	} // end for all paths
 
-	// File not found? On Win/Linux try to find it outside the resource dirs. On Android try the archive
+#if !ANKI_OS_ANDROID
+	// File not found? On Win/Linux try to find it outside the resource dirs
 	if(!rfile)
 	{
 		CResourceFile* file = newInstance<CResourceFile>(ResourceMemoryPool::getSingleton());
 		rfile = file;
-
-		FileOpenFlag openFlags = FileOpenFlag::kRead;
-#if ANKI_OS_ANDROID
-		openFlags |= FileOpenFlag::kSpecial;
-#endif
-		ANKI_CHECK(file->m_file.open(filename, openFlags));
-
-#if !ANKI_OS_ANDROID
+		ANKI_CHECK(file->m_file.open(filename, FileOpenFlag::kRead));
 		ANKI_RESOURCE_LOGW("Loading resource outside the resource paths/archives. This is only OK for tools and debugging: %s", filename.cstr());
-#endif
 	}
+#else
+	if(!rfile)
+	{
+		ANKI_RESOURCE_LOGE("Couldn't find file: %s", filename.cstr());
+		return Error::kFileNotFound;
+	}
+#endif
 
 	return Error::kNone;
 }

+ 8 - 3
AnKi/Resource/ResourceFilesystem.h

@@ -14,12 +14,15 @@
 
 namespace anki {
 
-// Forward
-extern StringCVar g_dataPathsCVar;
-
 /// @addtogroup resource
 /// @{
 
+inline StringCVar
+	g_dataPathsCVar("Rsrc", "DataPaths", ".",
+					"The engine loads assets only in from these paths. Separate them with : (it's smart enough to identify drive letters in "
+					"Windows). After a path you can add an optional | and what follows it is a number of words to include or exclude paths. "
+					"eg. my_path|include_this,include_that,+exclude_this");
+
 /// Resource filesystem file. An interface that abstracts the resource file.
 class ResourceFile
 {
@@ -121,6 +124,7 @@ private:
 		ResourceStringList m_files; ///< Files inside the directory.
 		ResourceString m_path; ///< A directory or an archive.
 		Bool m_isArchive = false;
+		Bool m_isSpecial = false;
 
 		Path() = default;
 
@@ -138,6 +142,7 @@ private:
 			m_files = std::move(b.m_files);
 			m_path = std::move(b.m_path);
 			m_isArchive = b.m_isArchive;
+			m_isSpecial = b.m_isSpecial;
 			return *this;
 		}
 	};

+ 9 - 2
AnKi/Resource/ShaderProgramResource.cpp

@@ -191,8 +191,15 @@ ShaderProgramResourceVariant* ShaderProgramResource::createNewVariant(const Shad
 	if(!!(info.m_shaderTypes & (ShaderTypeBit::kAllGraphics | ShaderTypeBit::kCompute)))
 	{
 		// Create the program name
-		String progName;
-		getFilepathFilename(getFilename(), progName);
+		String fname;
+		getFilepathFilename(getFilename(), fname);
+
+		ResourceString progName = fname.cstr();
+		for(ShaderType shaderType : EnumBitsIterable<ShaderType, ShaderTypeBit>(info.m_shaderTypes))
+		{
+			progName += "_";
+			progName += info.m_techniqueNames[shaderType].getBegin();
+		}
 
 		ShaderProgramInitInfo progInf(progName);
 		Array<ShaderPtr, U32(ShaderType::kCount)> shaderRefs; // Just for refcounting

+ 0 - 52
AnKi/Shaders/ApplyIrradianceToReflection.ankiprog

@@ -1,52 +0,0 @@
-// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma anki technique comp
-
-#include <AnKi/Shaders/PackFunctions.hlsl>
-#include <AnKi/Shaders/LightFunctions.hlsl>
-
-SamplerState g_nearestAnyClampSampler : register(s0);
-TextureCube<Vec4> g_gbufferTex[3u] : register(t0);
-StructuredBuffer<Vec4> g_irradianceDice : register(t3);
-RWTexture2D<Vec4> g_cubeTex[6u] : register(u0); // RWTexture2D because there is no RWTextureCube
-
-[numthreads(8, 8, 6)] void main(UVec3 svDispatchThreadId : SV_DISPATCHTHREADID, UVec3 svGroupThreadId : SV_GROUPTHREADID)
-{
-	const U32 faceIdx = svGroupThreadId.z;
-
-	// Compute the UVs to read the gbuffer from
-	UVec2 cubeSizeu;
-	g_cubeTex[0].GetDimensions(cubeSizeu.x, cubeSizeu.y);
-	const Vec2 cubeSize = Vec2(cubeSizeu);
-	const UVec2 dispatchThreadId = min(svDispatchThreadId.xy, cubeSizeu - 1u);
-
-	const Vec2 uv = (Vec2(dispatchThreadId) + 0.5) / Vec2(cubeSize);
-	const Vec3 sampleUv = getCubemapDirection(uv, faceIdx);
-
-	// Read the gbuffer
-	GbufferInfo<F32> gbuffer = (GbufferInfo<F32>)0;
-	unpackGBufferNoVelocity(g_gbufferTex[0u].SampleLevel(g_nearestAnyClampSampler, sampleUv, 0.0),
-							g_gbufferTex[1u].SampleLevel(g_nearestAnyClampSampler, sampleUv, 0.0),
-							g_gbufferTex[2u].SampleLevel(g_nearestAnyClampSampler, sampleUv, 0.0), gbuffer);
-
-	// Sample
-	const RVec3 irradiance =
-		sampleAmbientDice<RF32>(g_irradianceDice[0u].xyz, g_irradianceDice[1u].xyz, g_irradianceDice[2u].xyz, g_irradianceDice[3u].xyz,
-								g_irradianceDice[4u].xyz, g_irradianceDice[5u].xyz, gbuffer.m_normal * Vec3(1.0, 1.0, -1.0));
-
-	// Compute the indirect term
-	const RVec3 indirect = gbuffer.m_diffuse * irradiance;
-
-	// Read the prev color and apply indirect
-	const RVec3 prevColor = g_cubeTex[faceIdx][dispatchThreadId].xyz;
-	const RVec3 prevColorWithIndirectDiffuse = prevColor + gbuffer.m_diffuse * indirect;
-
-	// Barrier just in case
-	GroupMemoryBarrierWithGroupSync();
-
-	// Write it back
-	g_cubeTex[faceIdx][dispatchThreadId] = RVec4(prevColorWithIndirectDiffuse, 0.0);
-}

+ 1 - 1
AnKi/Shaders/IndirectDiffuseClipmaps.ankiprog

@@ -258,7 +258,7 @@ SamplerState g_linearAnyRepeatSampler : register(s0);
 	UVec2 noiseTexSize;
 	g_blueNoiseTex.GetDimensions(noiseTexSize.x, noiseTexSize.y);
 	Vec3 noise3 = g_blueNoiseTex[svDispatchThreadId % noiseTexSize];
-	noise3 = animateBlueNoise2(noise3, g_globalRendererConstants.m_frame);
+	noise3 = animateBlueNoise(noise3, g_globalRendererConstants.m_frame);
 
 	F32 noise = noise3.x;
 

+ 5 - 0
AnKi/Util/Logger.h

@@ -88,6 +88,11 @@ public:
 		m_verbosityEnabled = enable;
 	}
 
+	Bool verbosityEnabled() const
+	{
+		return m_verbosityEnabled;
+	}
+
 private:
 	class Handler
 	{

+ 15 - 0
Tools/Android/GenerateAndroidProject.py

@@ -88,6 +88,21 @@ def main():
     else:
         print("Asset directory (%s) already exists. Skipping" % assets_dir)
 
+    # Write the asset directory structure to a file
+    dir_structure_file = open(os.path.join(assets_dir, "DirStructure.txt"), "w", newline="\n")
+    for root, dirs, files in os.walk(assets_dir, followlinks=True):
+        for f in files:
+            if f.find("DirStructure.txt") >= 0:
+                continue
+
+            filename = os.path.join(root, f)
+            filename = filename.replace(assets_dir, "")
+            filename = filename.replace("\\", "/")
+            if filename[0] == '/':
+                filename = filename[1:]
+            dir_structure_file.write("%s\n" % filename)
+    dir_structure_file.close()
+
     # strings.xml
     replace_in_file(os.path.join(project_dir, "app/src/main/res/values/strings.xml"), "%APP_NAME%", ctx.target)