Pārlūkot izejas kodu

Fixing a potential problem in shader program. Optimizing a bit the uniform passing of sampler arrays

Panagiotis Christopoulos Charitos 13 gadi atpakaļ
vecāks
revīzija
732ea0921c

+ 4 - 1
include/anki/Config.h.cmake

@@ -24,9 +24,12 @@
 #endif
 
 #if defined(NDEBUG)
-#	define ANKI_DEBUG NDEBUG
+#	define ANKI_DEBUG !NDEBUG
 #else
 #	define ANKI_DEBUG 0
 #endif
 
+#define ANKI_FILE __BASE_FILE__
+#define ANKI_FUNC __func__
+
 #endif

+ 2 - 1
include/anki/core/Logger.h

@@ -3,6 +3,7 @@
 
 #include "anki/util/Observer.h"
 #include "anki/util/Singleton.h"
+#include "anki/Config.h"
 #include <array>
 #include <mutex>
 #include <sstream> // For the macros
@@ -58,7 +59,7 @@ typedef Singleton<Logger> LoggerSingleton;
 	{ \
 		std::stringstream ss; \
 		ss << msg; \
-		LoggerSingleton::get().write(__FILE__, __LINE__, __func__, \
+		LoggerSingleton::get().write(ANKI_FILE, __LINE__, ANKI_FUNC, \
 			t, ss.str().c_str()); \
 	} while(false);
 

+ 1 - 1
include/anki/gl/GlException.h

@@ -11,7 +11,7 @@ void glConditionalThrowException(const char* file, int line, const char* func);
 
 #if ANKI_DEBUG
 #	define ANKI_CHECK_GL_ERROR() \
-		glConditionalThrowException(__FILE__, __LINE__, __func__)
+		glConditionalThrowException(ANKI_FILE, __LINE__, ANKI_FUNC)
 #else
 #	define ANKI_CHECK_GL_ERROR() ((void)0)
 #endif

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

@@ -144,6 +144,8 @@ public:
 	}
 	void set(const Texture& tex) const;
 
+	void set(const Texture* const texes[], const U32 count) const;
+
 	void set(const F32 x[], uint size) const;
 	void set(const Vec2 x[], uint size) const;
 	void set(const Vec3 x[], uint size) const;

+ 1 - 1
include/anki/util/Assert.h

@@ -18,7 +18,7 @@ extern void akassert(bool expr, const char* exprTxt, const char* file,
 
 } // end namespace
 
-#	define ANKI_ASSERT(x) akassert((x), #x, __FILE__, __LINE__, __func__)
+#	define ANKI_ASSERT(x) akassert((x), #x, ANKI_FILE, __LINE__, ANKI_FUNC)
 #	define ANKI_ASSERTS_ENABLED 1
 
 #endif

+ 7 - 6
include/anki/util/Barrier.h

@@ -2,6 +2,7 @@
 #define ANKI_UTIL_BARRIER_H
 
 #include "anki/util/Assert.h"
+#include "anki/util/StdTypes.h"
 #include <thread>
 #include <condition_variable>
 #include <mutex>
@@ -12,16 +13,16 @@ namespace anki {
 class Barrier
 {
 public:
-	Barrier(uint32_t count_)
+	Barrier(U32 count_)
 		: threshold(count_), count(count_), generation(0)
 	{
 		ANKI_ASSERT(count_ != 0);
 	}
 
-	bool wait()
+	Bool wait()
 	{
 		std::unique_lock<std::mutex> lock(mtx);
-		uint32_t gen = generation;
+		U32 gen = generation;
 
 		if(--count == 0)
 		{
@@ -41,9 +42,9 @@ public:
 private:
 	std::mutex mtx;
 	std::condition_variable cond;
-	uint32_t threshold;
-	uint32_t count;
-	uint32_t generation;
+	U32 threshold;
+	U32 count;
+	U32 generation;
 };
 
 } // end namespace anki

+ 3 - 2
include/anki/util/BinaryStream.h

@@ -2,6 +2,7 @@
 #define ANKI_UTIL_BINARY_STREAM_H
 
 #include "anki/util/Exception.h"
+#include "anki/util/StdTypes.h"
 #include <iostream>
 
 namespace anki {
@@ -30,11 +31,11 @@ public:
 
 	/// Read unsigned int (32bit)
 	/// @exception Exception
-	uint32_t readUint();
+	U32 readUint();
 
 	/// Read float (32bit)
 	/// @exception Exception
-	float readFloat();
+	F32 readFloat();
 
 	/// Read a string. It reads the size as an unsigned int and then it
 	/// reads the characters

+ 2 - 1
include/anki/util/Exception.h

@@ -1,6 +1,7 @@
 #ifndef ANKI_UTIL_EXCEPTION_H
 #define ANKI_UTIL_EXCEPTION_H
 
+#include "anki/Config.h"
 #include <exception>
 #include <string>
 
@@ -45,6 +46,6 @@ private:
 
 /// Macro for easy throwing
 #define ANKI_EXCEPTION(x) Exception((std::string() + x).c_str(), \
-	__FILE__, __LINE__, __func__)
+	ANKI_FILE, __LINE__, ANKI_FUNC)
 
 #endif

+ 33 - 0
src/gl/ShaderProgram.cpp

@@ -122,6 +122,24 @@ void ShaderProgramUniformVariable::set(const Texture& tex) const
 	glUniform1i(getLocation(), tex.bind());
 }
 
+//==============================================================================
+void ShaderProgramUniformVariable::set(const Texture* const texes[], 
+	const U32 count) const
+{
+	doCommonSetCode();
+	ANKI_ASSERT(count > 128);
+	ANKI_ASSERT(count <= size);
+	Array<GLint, 128> units;
+
+	for(U32 i = 0; i < count; i++)
+	{
+		const Texture* tex = texes[i];
+		units[i] = tex->bind();
+	}
+
+	glUniform1iv(getLocation(), count, &units[0]);
+}
+
 //==============================================================================
 /// XXX
 template<typename T>
@@ -590,6 +608,21 @@ void ShaderProgram::initUniAndAttribVars()
 			&size, &type, &name_[0]);
 		name_[length] = '\0';
 
+		// In case of uniform arrays some implementations (nVidia) on 
+		// GL_ACTIVE_UNIFORMS they return the number of uniforms that are inside 
+		// that uniform array in addition to the first element (it will count 
+		// for example the floats[1]). Some other implementations don't (Mali 
+		// T6xx). Also in some cases with big arrays (IS shader) this will 
+		// overpopulate the uniforms vector and hash map. So, to solve this if 
+		// the uniform name has something like this "[N]" where N != 0 then 
+		// ignore the uniform
+		if(strchr(&name_[0], '[') != nullptr 
+			&& strstr(&name_[0], "[0]") != nullptr)
+		{
+			ANKI_ASSERT(size > 1);
+			continue;
+		}
+
 		// -1 means in uniform block
 		GLint loc = glGetUniformLocation(glId, &name_[0]);
 

+ 3 - 13
src/renderer/Is.cpp

@@ -755,6 +755,9 @@ void Is::lightPass()
 		r->getMs().getDepthFai());
 
 #if 1
+	lightPassProg->findUniformVariable("shadowMaps[0]").set(
+		&shadowmaps[0], (U32)spotsShadowCount);
+#else
 	for(U i = 0; i < spotsShadowCount; i++)
 	{
 		char str[128];
@@ -764,19 +767,6 @@ void Is::lightPass()
 	}
 #endif
 
-#if 0
-	{
-	SpotLight& light = *visibleSpotShadowLights[0];
-	static const Mat4 biasMat4(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 
-				0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
-	Mat4 matrix = biasMat4 * light.getProjectionMatrix() *
-				Mat4::combineTransformations(light.getViewMatrix(),
-				Mat4(cam->getWorldTransform()));
-
-	lightPassProg->findUniformVariable("matrix").set(matrix);
-	}
-#endif
-
 	r->drawQuadInstanced(TILES_Y_COUNT * TILES_X_COUNT);
 }
 

+ 1 - 1
testapp/Main.cpp

@@ -110,7 +110,7 @@ void init()
 	spot->setSpecularColor(Vec4(1.0));
 	spot->loadTexture("gfx/lights/flashlight.tga");
 	spot->setDistance(30.0);
-	spot->setShadowEnabled(false);
+	spot->setShadowEnabled(true);
 
 
 	spot = new SpotLight("spot1", &scene, Movable::MF_NONE, nullptr);