Browse Source

Fixing GL and trying to remove some dependencies from program pre preprocessor

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
f95adbc048

+ 2 - 0
include/anki/gl/Fbo.h

@@ -17,6 +17,8 @@ class Texture;
 /// mistakes. It only supports binding at both draw and read targets
 class Fbo
 {
+	ANKI_GL_NON_SHARABLE
+
 public:
 	/// @name Constructors/Destructor
 	/// @{

+ 22 - 0
include/anki/gl/Ogl.h

@@ -6,4 +6,26 @@
 #	error "Wrong GLEW included"
 #endif
 
+// The following macros are used for sanity checks in non sharable GL objects.
+// They help us avoid binding those objects from other than the creation 
+// threads. They are enabled only on debug
+#if !NDEBUG
+#	include <thread>
+
+#	define ANKI_GL_NON_SHARABLE std::thread::id creationThreadId;
+
+#	define ANKI_GL_NON_SHARABLE_INIT() \
+		creationThreadId = std::this_thread::get_id()
+
+#	define ANKI_GL_NON_SHARABLE_CHECK() \
+		ANKI_ASSERT(creationThreadId == std::this_thread::get_id() \
+			&& "FBO can be used only from the creation thread")
+#else
+#	define ANKI_GL_NON_SHARABLE
+
+#	define ANKI_GL_NON_SHARABLE_INIT() (void)
+
+#	define ANKI_GL_NON_SHARABLE_CHECK() (void)
+#endif
+
 #endif

+ 8 - 1
include/anki/gl/Vao.h

@@ -5,6 +5,7 @@
 #include "anki/gl/Ogl.h"
 #include "anki/util/Assert.h"
 #include "anki/util/NonCopyable.h"
+#include "anki/util/StdTypes.h"
 
 namespace anki {
 
@@ -14,6 +15,8 @@ class Vbo;
 /// Vertex array object. Non-copyable to avoid instantiating it in the stack
 class Vao: public NonCopyable
 {
+	ANKI_GL_NON_SHARABLE
+
 public:
 	/// @name Constructors/Destructor
 	/// @{
@@ -39,6 +42,7 @@ public:
 	void create()
 	{
 		ANKI_ASSERT(!isCreated());
+		ANKI_GL_NON_SHARABLE_INIT();
 		glGenVertexArrays(1, &glId);
 		ANKI_CHECK_GL_ERROR();
 	}
@@ -47,6 +51,7 @@ public:
 	void destroy()
 	{
 		ANKI_ASSERT(isCreated());
+		ANKI_GL_NON_SHARABLE_CHECK();
 		unbind();
 		glDeleteVertexArrays(1, &glId);
 	}
@@ -111,6 +116,7 @@ public:
 	void bind() const
 	{
 		ANKI_ASSERT(isCreated());
+		ANKI_GL_NON_SHARABLE_CHECK();
 		if(current != this)
 		{
 			glBindVertexArray(glId);
@@ -123,6 +129,7 @@ public:
 	void unbind() const
 	{
 		ANKI_ASSERT(isCreated());
+		ANKI_GL_NON_SHARABLE_CHECK();
 		if(current == this)
 		{
 			glBindVertexArray(0);
@@ -134,7 +141,7 @@ private:
 	static thread_local const Vao* current;
 	GLuint glId = 0; ///< The OpenGL id
 #if !defined(NDEBUG)
-	int attachments = 0;
+	U32 attachments = 0;
 #endif
 
 	bool isCreated() const

+ 11 - 44
include/anki/resource/ShaderProgramPrePreprocessor.h

@@ -2,19 +2,12 @@
 #define ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
 
 #include "anki/resource/ShaderProgramCommon.h"
-#include <limits>
-#include <boost/array.hpp>
 #include "anki/util/Vector.h"
-
+#include "anki/util/StdTypes.h"
+#include <limits>
 
 namespace anki {
 
-
-namespace scanner {
-class Scanner;
-}
-
-
 /// Helper class used for shader program loading
 ///
 /// The class fills some of the GLSL spec deficiencies. It adds the include
@@ -62,20 +55,11 @@ protected:
 	/// The pragma base class
 	struct Pragma
 	{
-		std::string definedInFile;
-		int definedInLine;
-
-		Pragma()
-			: definedInLine(-1)
-		{}
+		I32 definedLine = -1;
 
-		Pragma(const std::string& definedInFile_, int definedInLine_)
-			: definedInFile(definedInFile_), definedInLine(definedInLine_)
-		{}
-
-		bool isDefined() const
+		Bool isDefined() const
 		{
-			return definedInLine != -1;
+			return definedLine != -1;
 		}
 	};
 
@@ -86,24 +70,11 @@ protected:
 
 	struct TrffbVaryingPragma: Pragma
 	{
-		std::string name;
-
-		TrffbVaryingPragma(const std::string& definedInFile_,
-			int definedInLine_, const std::string& name_)
-			: Pragma(definedInFile_, definedInLine_), name(name_)
-		{}
+		StringList names;
 	};
 
 	struct CodeBeginningPragma: Pragma
-	{
-		/// The line number in the PrePreprocessor-compatible
-		/// file
-		int globalLine;
-
-		CodeBeginningPragma()
-			: globalLine(-1)
-		{}
-	};
+	{};
 
 	/// The output of the class packed in this struct
 	struct Output
@@ -112,15 +83,14 @@ protected:
 
 		/// Names and and ids for transform feedback varyings
 		Vector<TrffbVaryingPragma> trffbVaryings;
-		boost::array<std::string, ST_NUM> shaderSources;
+		Array<std::string, ST_NUM> shaderSources;
 	};
 
 	Output output; ///< The most important variable
-	Vector<std::string> trffbVaryings;
+	StringList trffbVaryings;
 	/// The parseFileForPragmas fills this
 	Vector<std::string> sourceLines;
-	boost::array<CodeBeginningPragma, ST_NUM> shaderStarts;
-	static boost::array<const char*, ST_NUM> startTokens; ///< XXX
+	Array<CodeBeginningPragma, ST_NUM> shaderStarts;
 
 	/// Parse a PrePreprocessor formated GLSL file. Use
 	/// the accessors to get the output
@@ -168,7 +138,6 @@ protected:
 	void addLinePreProcExpression(uint line, uint depth, const char* cmnt);
 };
 
-
 template<typename Type>
 typename Vector<Type>::const_iterator
 	ShaderProgramPrePreprocessor::findNamed(
@@ -182,8 +151,6 @@ typename Vector<Type>::const_iterator
 	return it;
 }
 
-
-} // end namespace
-
+} // end namespace anki
 
 #endif

+ 4 - 5
src/gl/Fbo.cpp

@@ -26,6 +26,7 @@ Fbo::~Fbo()
 void Fbo::create()
 {
 	ANKI_ASSERT(!isCreated());
+	ANKI_GL_NON_SHARABLE_INIT();
 	glGenFramebuffers(1, &glId);
 	ANKI_ASSERT(glId != 0);
 }
@@ -43,6 +44,7 @@ void Fbo::destroy()
 void Fbo::bind() const
 {
 	ANKI_ASSERT(isCreated());
+	ANKI_GL_NON_SHARABLE_CHECK();
 
 	if(current != this)
 	{
@@ -55,6 +57,7 @@ void Fbo::bind() const
 void Fbo::unbind() const
 {
 	ANKI_ASSERT(isCreated());
+	ANKI_GL_NON_SHARABLE_CHECK();
 
 	if(current == this)
 	{
@@ -76,8 +79,7 @@ void Fbo::unbindAll()
 //==============================================================================
 bool Fbo::isComplete() const
 {
-	ANKI_ASSERT(isCreated());
-	ANKI_ASSERT(glId == getCurrentFboGlId() && "Not binded");
+	bind();
 
 	GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 	return status == GL_FRAMEBUFFER_COMPLETE;
@@ -87,7 +89,6 @@ bool Fbo::isComplete() const
 void Fbo::setColorAttachments(const std::initializer_list<const Texture*>& 
 	textures)
 {
-	ANKI_ASSERT(isCreated());
 	ANKI_ASSERT(textures.size() > 0);
 
 	bind();
@@ -108,8 +109,6 @@ void Fbo::setColorAttachments(const std::initializer_list<const Texture*>&
 //==============================================================================
 void Fbo::setOtherAttachment(GLenum attachment, const Texture& tex)
 {
-	ANKI_ASSERT(isCreated());
-
 	bind();
 	glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
 		GL_TEXTURE_2D, tex.getGlId(), 0);

+ 1 - 1
src/gl/Vao.cpp

@@ -71,4 +71,4 @@ void Vao::attachElementArrayBufferVbo(const Vbo& vbo)
 #endif
 }
 
-} // end namespace
+} // end namespace anki

+ 61 - 54
src/resource/ShaderProgramPrePreprocessor.cpp

@@ -5,50 +5,49 @@
 #include <iomanip>
 #include <cstring>
 #include <iostream>
-#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
-
 
 namespace anki {
 
+//==============================================================================
 
-static const char* MULTIPLE_DEF_MSG = " already defined in the same place. "
-	"Check for circular or multiple includance";
-
+static Array<const char*, 3> commands = {{
+	"#pragma anki start",
+	"#pragma anki include",
+	"#pragma anki transformFeedbackVaryings"}};
 
-boost::array<const char*, ST_NUM>
-	ShaderProgramPrePreprocessor::startTokens = {{
+Array<const char*, ST_NUM> startTokens = {{
 	"vertexShader",
 	"tcShader",
 	"teShader",
 	"geometryShader",
 	"fragmentShader"}};
 
+static const char* MULTIPLE_DEF_MSG = " already defined in the same place. "
+	"Check for circular or multiple includance";
+
+static const char* ENTRY_POINT_DOT_DEFINED = "Entry point not defined: ";
+
+const U32 MAX_DEPTH = 99;
 
-//==============================================================================
-// printSourceLines                                                            =
 //==============================================================================
 void ShaderProgramPrePreprocessor::printSourceLines() const
 {
-	for(uint i = 0; i < sourceLines.size(); ++i)
+	for(U32 i = 0; i < sourceLines.size(); ++i)
 	{
-		std::cout << std::setw(3) << (i + 1) << ": " <<
-			sourceLines[i] << std::endl;
+		std::cout << std::setw(3) << (i + 1) << ": " 
+			<< sourceLines[i] << std::endl;
 	}
 }
 
-
-//==============================================================================
-// parseFileForPragmas                                                         =
 //==============================================================================
 void ShaderProgramPrePreprocessor::parseFileForPragmas(
 	const std::string& filename, int depth)
 {
 	// first check the depth
-	if(depth > 99)
+	if(depth > MAX_DEPTH)
 	{
-		throw ANKI_EXCEPTION("File \"" + filename +
-			"\": The include depth is too high. Probably circular includance");
+		throw ANKI_EXCEPTION("The include depth is too high. "
+			"Probably circular includance: " + filename);
 	}
 
 	// load file in lines
@@ -58,6 +57,25 @@ void ShaderProgramPrePreprocessor::parseFileForPragmas(
 		throw ANKI_EXCEPTION("Cannot open file or empty: " + filename);
 	}
 
+	for(const std::string& line : lines)
+	{
+		if(line.find_first_of(commands[0]) != std::string::npos)
+		{
+
+		}
+		else if(line.find_first_of(commands[1]) != std::string::npos)
+		{
+		}
+		else if(line.find_first_of(commands[2]) != std::string::npos)
+		{
+		}
+		else
+		{
+			sourceLines.push_back(line);
+		}
+	}
+
+#if 0
 	scanner::Scanner scanner(filename.c_str(), false);
 	const scanner::Token* token;
 
@@ -141,11 +159,9 @@ void ShaderProgramPrePreprocessor::parseFileForPragmas(
 			// It will never get here
 		}
 	} // end while
+#endif
 }
 
-
-//=============================================================================/
-// parseFile                                                                   =
 //==============================================================================
 void ShaderProgramPrePreprocessor::parseFile(const char* filename)
 {
@@ -157,18 +173,18 @@ void ShaderProgramPrePreprocessor::parseFile(const char* filename)
 		// sanity checks
 		if(!shaderStarts[ST_VERTEX].isDefined())
 		{
-			throw ANKI_EXCEPTION("Entry point \""+ startTokens[ST_VERTEX] +
-				"\" is not defined");
+			throw ANKI_EXCEPTION(ENTRY_POINT_DOT_DEFINED 
+				+ startTokens[ST_VERTEX]);
 		}
 
 		if(!shaderStarts[ST_FRAGMENT].isDefined())
 		{
-			throw ANKI_EXCEPTION("Entry point \""+ startTokens[ST_FRAGMENT] +
-				"\" is not defined");
+			throw ANKI_EXCEPTION(ENTRY_POINT_DOT_DEFINED 
+				+ startTokens[ST_FRAGMENT]);
 		}
 
-		// construct shaders' source code
-		for(uint i = 0; i < ST_NUM; i++)
+		// construct each shaders' source code
+		for(U i = 0; i < ST_NUM; i++)
 		{
 			std::string& src = output.shaderSources[i];
 
@@ -181,39 +197,39 @@ void ShaderProgramPrePreprocessor::parseFile(const char* filename)
 			}
 
 			// Sanity check: Check the correct order of i
-			int k = (int)i - 1;
+			I32 k = (I32)i - 1;
 			while(k > -1)
 			{
-				if(shaderStarts[k].isDefined() &&
-					shaderStarts[k].globalLine >= shaderStarts[i].globalLine)
+				if(shaderStarts[k].isDefined() 
+					&& shaderStarts[k].globalLine >= shaderStarts[i].globalLine)
 				{
-					throw ANKI_EXCEPTION(startTokens[i] + " must be after " +
-						startTokens[k]);
+					throw ANKI_EXCEPTION(startTokens[i] + " must be after " 
+						+ startTokens[k]);
 				}
 				--k;
 			}
 
-			k = (int)i + 1;
+			k = (I32)i + 1;
 			while(k < ST_NUM)
 			{
-				if(shaderStarts[k].isDefined() &&
-					shaderStarts[k].globalLine <= shaderStarts[i].globalLine)
+				if(shaderStarts[k].isDefined() 
+					&& shaderStarts[k].globalLine <= shaderStarts[i].globalLine)
 				{
-					throw ANKI_EXCEPTION(startTokens[k] + " must be after " +
-						startTokens[i]);
+					throw ANKI_EXCEPTION(startTokens[k] + " must be after " 
+						+ startTokens[i]);
 				}
 				++k;
 			}
 
 			// put global source code
-			for(int j = 0; j < shaderStarts[ST_VERTEX].globalLine - 1; ++j)
+			for(I32 j = 0; j < shaderStarts[ST_VERTEX].globalLine - 1; ++j)
 			{
 				src += sourceLines[j] + "\n";
 			}
 
 			// put the actual code
-			uint from = i;
-			uint to;
+			U32 from = i;
+			U32 to;
 
 			for(to = i + 1; to < ST_NUM; to++)
 			{
@@ -223,21 +239,15 @@ void ShaderProgramPrePreprocessor::parseFile(const char* filename)
 				}
 			}
 
-			int toLine = (to == ST_NUM) ? sourceLines.size():
-				shaderStarts[to].globalLine - 1;
+			I32 toLine = (to == ST_NUM) ? sourceLines.size() 
+				: shaderStarts[to].globalLine - 1;
 
-			for(int j = shaderStarts[from].globalLine - 1; j < toLine; ++j)
+			for(I32 j = shaderStarts[from].globalLine - 1; j < toLine; ++j)
 			{
 				src += sourceLines[j] + "\n";
 			}
 		}
 
-		// TRF feedback varyings
-		BOOST_FOREACH(const TrffbVaryingPragma& trffbv, output.trffbVaryings)
-		{
-			trffbVaryings.push_back(trffbv.name);
-		}
-
 		//PRINT("vertShaderBegins.globalLine: " << vertShaderBegins.globalLine)
 		//PRINT("fragShaderBegins.globalLine: " << fragShaderBegins.globalLine)
 		//printSourceLines();
@@ -245,13 +255,10 @@ void ShaderProgramPrePreprocessor::parseFile(const char* filename)
 	}
 	catch(Exception& e)
 	{
-		throw ANKI_EXCEPTION("Started from \"" + filename + "\"") << e;
+		throw ANKI_EXCEPTION("Loading file failed: " + filename) << e;
 	}
 }
 
-
-//==============================================================================
-// parseStartPragma                                                            =
 //==============================================================================
 void ShaderProgramPrePreprocessor::parseStartPragma(scanner::Scanner& scanner,
 	const std::string& filename, uint depth,