Browse Source

Some more work on the compiler

Panagiotis Christopoulos Charitos 5 years ago
parent
commit
344c445594

+ 3 - 1
src/anki/core/App.cpp

@@ -745,8 +745,10 @@ Error App::compileAllShaders()
 			fname, iface, m_heapAlloc, m_gr->getDeviceCapabilities(), m_gr->getBindlessLimits(), binary));
 
 		// Save the binary to the cache
+		StringAuto baseFname(m_heapAlloc);
+		getFilepathFilename(fname, baseFname);
 		StringAuto storeFname(m_heapAlloc);
-		storeFname.sprintf("%s/%s.ankiprogbin", m_cacheDir.cstr(), fname.cstr());
+		storeFname.sprintf("%s/%sbin", m_cacheDir.cstr(), baseFname.cstr());
 		ANKI_CHECK(binary.serializeToFile(storeFname));
 
 		return Error::NONE;

+ 1 - 1
src/anki/shader_compiler/ShaderProgramCompiler.cpp

@@ -430,7 +430,7 @@ static void disassembleBlock(const ShaderProgramBinaryBlock& block, StringListAu
 	}
 }
 
-void disassembleShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable)
+void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable)
 {
 	GenericMemoryPoolAllocator<U8> alloc = humanReadable.getAllocator();
 	StringListAuto lines(alloc);

+ 1 - 1
src/anki/shader_compiler/ShaderProgramCompiler.h

@@ -64,7 +64,7 @@ ANKI_USE_RESULT Error compileShaderProgram(CString fname,
 	ShaderProgramBinaryWrapper& binary);
 
 /// Create a human readable representation of the shader binary.
-void disassembleShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable);
+void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable);
 /// @}
 
 } // end namespace anki

+ 9 - 9
src/anki/shader_compiler/ShaderProgramParser.cpp

@@ -173,7 +173,7 @@ Error ShaderProgramParser::parsePragmaStart(const StringAuto* begin, const Strin
 		ANKI_PP_ERROR_MALFORMED();
 	}
 
-	m_codeLines.pushBackSprintf("#ifdef ANKI_%s", SHADER_STAGE_NAMES[shaderType].cstr());
+	m_codeLines.pushBackSprintf("#ifdef ANKI_%s_SHADER", SHADER_STAGE_NAMES[shaderType].cstr());
 
 	++begin;
 	if(begin != end)
@@ -508,7 +508,6 @@ Error ShaderProgramParser::parseLine(CString line, CString fname, Bool& foundPra
 	else if((token < end) && ((foundAloneHash && *token == "pragma") || *token == "#pragma"))
 	{
 		// We may have a #pragma once or a #pragma anki or something else
-
 		++token;
 
 		if(*token == "once")
@@ -618,12 +617,6 @@ Error ShaderProgramParser::parseFile(CString fname, U32 depth)
 		m_codeLines.pushBack("#endif // Include guard");
 	}
 
-	if(m_insideShader)
-	{
-		ANKI_SHADER_COMPILER_LOGE("Forgot a \"pragma anki end\"");
-		return Error::USER_DATA;
-	}
-
 	return Error::NONE;
 }
 
@@ -661,6 +654,12 @@ Error ShaderProgramParser::parse()
 				return Error::USER_DATA;
 			}
 		}
+
+		if(m_insideShader)
+		{
+			ANKI_SHADER_COMPILER_LOGE("Forgot a \"pragma anki end\"");
+			return Error::USER_DATA;
+		}
 	}
 
 	// Create the code lines
@@ -716,7 +715,8 @@ Error ShaderProgramParser::generateVariant(
 		StringAuto finalSource(m_alloc);
 		finalSource.append(header);
 		finalSource.append(mutatorDefines);
-		finalSource.append(StringAuto(m_alloc).sprintf("#define ANKI_%s 1\n", SHADER_STAGE_NAMES[shaderType].cstr()));
+		finalSource.append(
+			StringAuto(m_alloc).sprintf("#define ANKI_%s_SHADER 1\n", SHADER_STAGE_NAMES[shaderType].cstr()));
 		finalSource.append(m_codeSource);
 
 		// Move the source

+ 5 - 0
src/anki/util/Filesystem.h

@@ -20,6 +20,7 @@ Bool fileExists(const CString& filename);
 void getFilepathExtension(const CString& filename, StringAuto& out);
 
 /// Get path filename.
+/// On path/to/file.ext return file.ext
 void getFilepathFilename(const CString& filename, StringAuto& out);
 
 /// Return true if directory exists?
@@ -46,6 +47,10 @@ ANKI_USE_RESULT Error createDirectory(const CString& dir);
 /// Write the home directory to @a buff. The @a buffSize is the size of the @a buff. If the @buffSize is not enough the
 /// function will throw an exception.
 ANKI_USE_RESULT Error getHomeDirectory(StringAuto& out);
+
+/// Get the time the file was last modified.
+ANKI_USE_RESULT Error getFileModificationTime(
+	CString filename, U32& year, U32& month, U32& day, U32& hour, U32& min, U32& second);
 /// @}
 
 } // end namespace anki

+ 20 - 0
src/anki/util/FilesystemPosix.cpp

@@ -18,6 +18,7 @@
 #include <cerrno>
 #include <ftw.h> // For walkDirectoryTree
 #include <cstdlib>
+#include <time.h>
 
 #ifndef USE_FDS
 #	define USE_FDS 15
@@ -208,4 +209,23 @@ Error getHomeDirectory(StringAuto& out)
 	return Error::NONE;
 }
 
+Error getFileModificationTime(CString filename, U32& year, U32& month, U32& day, U32& hour, U32& min, U32& second)
+{
+	struct stat buff;
+	if(lstat(filename.cstr(), &buff))
+	{
+		ANKI_UTIL_LOGE("stat() failed");
+		return Error::NONE;
+	}
+
+	const struct tm& t = *localtime(&buff.st_mtim.tv_sec);
+	year = 1900 + t.tm_year;
+	month = t.tm_mon + 1;
+	day = t.tm_mday;
+	hour = t.tm_hour;
+	second = t.tm_sec;
+
+	return Error::NONE;
+}
+
 } // end namespace anki

+ 1 - 1
tests/shader_compiler/ShaderProgramCompiler.cpp

@@ -156,7 +156,7 @@ void main()
 
 #if 0
 	StringAuto dis(alloc);
-	disassembleShaderProgramBinary(binary.getBinary(), dis);
+	dumpShaderProgramBinary(binary.getBinary(), dis);
 	ANKI_LOGI("Binary disassembly:\n%s\n", dis.cstr());
 #endif
 }

+ 1 - 0
tools/CMakeLists.txt

@@ -1 +1,2 @@
 add_subdirectory(gltf_importer)
+add_subdirectory(shader)

+ 7 - 0
tools/shader/CMakeLists.txt

@@ -0,0 +1,7 @@
+include_directories("../../src")
+
+file(GLOB_RECURSE SOURCES *.cpp)
+
+add_executable(shader_dump ${SOURCES})
+target_link_libraries(shader_dump anki)
+installExecutable(shader_dump)

+ 45 - 0
tools/shader/ShaderProgramBinaryDumpMain.cpp

@@ -0,0 +1,45 @@
+// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/shader_compiler/ShaderProgramCompiler.h>
+
+using namespace anki;
+
+static const char* USAGE = R"(Dump the shader binary to stdout
+Usage: %s in_file
+)";
+
+Error dump(const char* fname)
+{
+	HeapAllocator<U8> alloc(allocAligned, nullptr);
+
+	ShaderProgramBinaryWrapper bin(alloc);
+	ANKI_CHECK(bin.deserializeFromFile(fname));
+
+	StringAuto txt(alloc);
+	dumpShaderProgramBinary(bin.getBinary(), txt);
+
+	printf("%s\n", txt.cstr());
+
+	return Error::NONE;
+}
+
+int main(int argc, char** argv)
+{
+	if(argc != 2)
+	{
+		ANKI_LOGE(USAGE, argv[0]);
+		return 1;
+	}
+
+	const Error err = dump(argv[1]);
+	if(err)
+	{
+		ANKI_LOGE("Can't dump due to an error. Bye");
+		return 1;
+	}
+
+	return 0;
+}