Przeglądaj źródła

Fixing bugs in GLES3 path

Panagiotis Christopoulos Charitos 12 lat temu
rodzic
commit
70fb7d616a

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

@@ -96,10 +96,6 @@
 #define ANKI_MAX_INSTANCES 64
 
 // Renderer and rendering related config options
-#define ANKI_RENDERER_MAX_POINT_LIGHTS (512 - 16)
-#define ANKI_RENDERER_MAX_SPOT_LIGHTS 8
-#define ANKI_RENDERER_MAX_SPOT_TEX_LIGHTS 8
-
 #define ANKI_RENDERER_MAX_POINT_LIGHTS_PER_TILE 48
 #define ANKI_RENDERER_MAX_SPOT_LIGHTS_PER_TILE 4
 #define ANKI_RENDERER_MAX_SPOT_TEX_LIGHTS_PER_TILE 4

+ 11 - 4
include/anki/core/App.h

@@ -3,6 +3,7 @@
 
 #include "anki/core/Logger.h"
 #include "anki/util/Singleton.h"
+#include "anki/util/StringList.h"
 
 namespace anki {
 
@@ -42,15 +43,15 @@ public:
 
 	/// @name Accessors
 	/// @{
-	float getTimerTick() const
+	F32 getTimerTick() const
 	{
 		return timerTick;
 	}
-	float& getTimerTick()
+	F32& getTimerTick()
 	{
 		return timerTick;
 	}
-	void setTimerTick(const float x)
+	void setTimerTick(const F32 x)
 	{
 		timerTick = x;
 	}
@@ -64,6 +65,11 @@ public:
 	{
 		return cachePath;
 	}
+
+	const StringList& getDataPaths() const
+	{
+		return dataPaths;
+	}
 	/// @}
 
 private:
@@ -71,7 +77,8 @@ private:
 	std::string settingsPath;
 	/// This is used as a cache
 	std::string cachePath;
-	float timerTick;
+	StringList dataPaths;
+	F32 timerTick;
 
 	void parseCommandLineArgs(int argc, char* argv[]);
 

+ 1 - 9
include/anki/gl/BufferObject.h

@@ -194,15 +194,7 @@ class Ubo: public BufferObject
 {
 public:
 	/// Create a UBO
-	void create(PtrSize size, const void* data, U objectCount = SINGLE_OBJECT)
-	{
-		GLint64 maxBufferSize;
-		glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);
-		ANKI_ASSERT(size <= (PtrSize)maxBufferSize);
-
-		BufferObject::create(GL_UNIFORM_BUFFER, size, data, GL_DYNAMIC_DRAW,
-			objectCount);
-	}
+	void create(PtrSize size, const void* data, U objectCount = SINGLE_OBJECT);
 };
 
 /// Pixel buffer object

+ 2 - 0
include/anki/math/Mat4.h

@@ -226,6 +226,7 @@ public:
 		{
 			arr1[i] = b.arr1[i];
 		}
+		return *this;
 	}
 
 	TMat4 operator+(const TMat4& b) const
@@ -367,6 +368,7 @@ public:
 		{
 			arr1[i] *= f;
 		}
+		return *this;
 	}
 
 	TMat4 operator/(const T f) const

+ 7 - 0
include/anki/renderer/Is.h

@@ -91,6 +91,10 @@ private:
 	Vao quadVao; ///< This VAO is used everywhere except material stage
 	/// @}
 
+	U16 maxPointLights;
+	U8 maxSpotLights;
+	U8 maxSpotTexLights;
+
 	/// Called by init
 	void initInternal(const RendererInitializer& initializer);
 
@@ -99,6 +103,9 @@ private:
 
 	/// Prepare GL for rendering
 	void setState();
+
+	/// Calculate the size of the lights UBO
+	PtrSize calcLightsUboSize() const;
 };
 
 } // end namespace anki

+ 3 - 0
include/anki/renderer/Renderer.h

@@ -46,6 +46,9 @@ struct RendererInitializer
 			U32 maxLights = 4;
 		} sm;
 		Bool groundLightEnabled = true;
+		U32 maxPointLights = 512 - 16;
+		U32 maxSpotLights = 8;
+		U32 maxSpotTexLights = 4;
 	} is;
 
 	// Pps

+ 2 - 3
shaders/IsLp.glsl

@@ -210,9 +210,8 @@ float calcShadowFactor(in SpotTexLight light, in vec3 fragPosVspace,
 #if PCF == 1
 	float shadowFactor = pcfLow(shadowMapArr, texCoords3);
 #else
-	float shadowFactor = 
-		texture(shadowMapArr, 
-		vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z)).r;
+	vec4 tcoord = vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z);
+	float shadowFactor = texture(shadowMapArr, tcoord);
 #endif
 
 	return shadowFactor;

+ 13 - 9
src/core/App.cpp

@@ -106,6 +106,7 @@ void App::init(int argc, char* argv[])
 //==============================================================================
 void App::initDirs()
 {
+	// Settings path
 	settingsPath = std::string(getenv("HOME")) + "/.anki";
 	if(!directoryExists(settingsPath.c_str()))
 	{
@@ -113,6 +114,7 @@ void App::initDirs()
 		createDirectory(settingsPath.c_str());
 	}
 
+	// Cache
 	cachePath = settingsPath + "/cache";
 	if(directoryExists(cachePath.c_str()))
 	{
@@ -122,19 +124,21 @@ void App::initDirs()
 
 	ANKI_LOGI("Creating cache dir: " << cachePath);
 	createDirectory(cachePath.c_str());
+
+	// Data
+	if(getenv("ANKI_DATA_PATH"))
+	{
+		dataPaths = StringList::splitString(getenv("ANKI_DATA_PATH"), ':');
+	}
+	else
+	{
+		dataPaths.push_back("./");
+	}
 }
 
 //==============================================================================
 void App::quit(int code)
-{
-#if 0
-	SDL_FreeSurface(iconImage);
-	SDL_GL_DeleteContext(glContext);
-	SDL_DestroyWindow(windowId);
-	SDL_Quit();
-	exit(code);
-#endif
-}
+{}
 
 //==============================================================================
 void App::printAppInfo()

+ 21 - 0
src/gl/BufferObject.cpp

@@ -51,6 +51,16 @@ void BufferObject::create(GLenum target_, U32 sizeInBytes_,
 {
 	ANKI_ASSERT(!isCreated());
 
+	if(target_ == GL_UNIFORM_BUFFER)
+	{
+		GLint64 maxBufferSize;
+		glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);
+		if(sizeInBytes_ > (PtrSize)maxBufferSize)
+		{
+			throw ANKI_EXCEPTION("Buffer size exceeds GL implementation max");
+		}
+	}
+
 	usage = usage_;
 	target = target_;
 	sizeInBytes = sizeInBytes_;
@@ -178,4 +188,15 @@ void BufferObject::setBindingRange(
 	ANKI_CHECK_GL_ERROR();
 }
 
+//==============================================================================
+// Ubo                                                                         =
+//==============================================================================
+
+//==============================================================================
+void Ubo::create(PtrSize size, const void* data, U objectCount)
+{
+	BufferObject::create(GL_UNIFORM_BUFFER, size, data, GL_DYNAMIC_DRAW,
+		objectCount);
+}
+
 } // end namespace anki

+ 2 - 0
src/gl/Fbo.cpp

@@ -166,7 +166,9 @@ void Fbo::setOtherAttachment(GLenum attachment, const Texture& tex,
 	switch(tex.getTarget())
 	{
 	case GL_TEXTURE_2D:
+#if ANKI_GL == ANKI_GL_DESKTOP
 	case GL_TEXTURE_2D_MULTISAMPLE:
+#endif
 		ANKI_ASSERT(layer < 0 && face < 0);
 		glFramebufferTexture2D(target, attachment,
 			tex.getTarget(), tex.getGlId(), 0);

+ 4 - 0
src/gl/GlState.cpp

@@ -13,6 +13,7 @@ namespace anki {
 // GlStateCommon                                                               = 
 //==============================================================================
 
+#if ANKI_GL == ANKI_GL_DESKTOP
 struct GlDbg
 {
 	GLenum token;
@@ -73,6 +74,7 @@ static void oglMessagesCallback(GLenum source,
 		break;
 	}
 }
+#endif
 
 //==============================================================================
 void GlStateCommon::init(const U32 major_, const U32 minor_, 
@@ -95,6 +97,7 @@ void GlStateCommon::init(const U32 major_, const U32 minor_,
 	}
 
 	// Enable debug messages
+#if ANKI_GL == ANKI_GL_DESKTOP
 	if(registerDebugMessages)
 	{
 		glDebugMessageCallback(oglMessagesCallback, nullptr);
@@ -112,6 +115,7 @@ void GlStateCommon::init(const U32 major_, const U32 minor_,
 			}
 		}
 	}
+#endif
 }
 
 //==============================================================================

+ 11 - 2
src/gl/ShaderProgram.cpp

@@ -144,12 +144,21 @@ void ShaderProgramUniformVariable::set(const Mat4 x[], U32 size) const
 void ShaderProgramUniformVariable::set(const Texture& tex) const
 {
 	doCommonSetCode();
-	ANKI_ASSERT(getGlDataType() == GL_SAMPLER_2D 
+
+	// Don't put that inside the assert because the compiler complains that 
+	// it's inside a macro
+	Bool correctSamplerType = getGlDataType() == GL_SAMPLER_2D 
 		|| getGlDataType() == GL_SAMPLER_2D_SHADOW
 		|| getGlDataType() == GL_UNSIGNED_INT_SAMPLER_2D
 		|| getGlDataType() == GL_SAMPLER_2D_ARRAY_SHADOW
 		|| getGlDataType() == GL_SAMPLER_2D_ARRAY
-		|| getGlDataType() == GL_SAMPLER_2D_MULTISAMPLE);
+#if ANKI_GL == ANKI_GL_DESKTOP
+		|| getGlDataType() == GL_SAMPLER_2D_MULTISAMPLE
+#endif
+		;
+	(void)correctSamplerType;
+
+	ANKI_ASSERT(correctSamplerType);
 	
 	glUniform1i(getLocation(), tex.bind());
 }

+ 5 - 0
src/gl/Texture.cpp

@@ -426,7 +426,12 @@ void Texture::create2dFai(U w, U h,
 	init.width = w;
 	init.height = h;
 	init.depth = 0;
+#if ANKI_GL == ANKI_GL_DESKTOP
 	init.target = (samples_ == 1) ? GL_TEXTURE_2D : GL_TEXTURE_2D_MULTISAMPLE;
+#else
+	ANKI_ASSERT(samples_ == 1);
+	init.target = GL_TEXTURE_2D;
+#endif
 	init.internalFormat = internalFormat_;
 	init.format = format_;
 	init.type = type_;

+ 11 - 1
src/renderer/Dbg.cpp

@@ -21,7 +21,17 @@ void Dbg::init(const Renderer::Initializer& initializer)
 	try
 	{
 		fbo.create();
-		fbo.setColorAttachments({&r->getPps().getFai()});
+
+		// Chose the correct color FAI
+		if(r->getPps().getEnabled())
+		{
+			fbo.setColorAttachments({&r->getPps().getFai()});
+		}
+		else
+		{
+			fbo.setColorAttachments({&r->getIs().getFai()});
+		}
+
 		fbo.setOtherAttachment(GL_DEPTH_ATTACHMENT, r->getMs().getDepthFai());
 
 		if(!fbo.isComplete())

+ 47 - 51
src/renderer/Is.cpp

@@ -17,12 +17,6 @@ static const U MAX_SPOT_LIGHTS_PER_TILE =
 static const U MAX_SPOT_TEX_LIGHTS_PER_TILE = 
 	ANKI_RENDERER_MAX_SPOT_TEX_LIGHTS_PER_TILE;
 
-static const U MAX_POINT_LIGHTS = ANKI_RENDERER_MAX_POINT_LIGHTS;
-static const U MAX_SPOT_LIGHTS = ANKI_RENDERER_MAX_SPOT_LIGHTS;
-static const U MAX_SPOT_TEX_LIGHTS = ANKI_RENDERER_MAX_SPOT_TEX_LIGHTS;
-static const U MAX_LIGHTS = 
-	MAX_POINT_LIGHTS + MAX_SPOT_LIGHTS + MAX_SPOT_TEX_LIGHTS;
-
 static const U TILES_X_COUNT = ANKI_RENDERER_TILES_X_COUNT;
 static const U TILES_Y_COUNT = ANKI_RENDERER_TILES_Y_COUNT;
 static const U TILES_COUNT = TILES_X_COUNT * TILES_Y_COUNT;
@@ -100,33 +94,6 @@ struct CommonUniforms
 
 } // end namespace shader
 
-//==============================================================================
-static const PtrSize MIN_LIGHTS_UBO_SIZE = 
-	MAX_POINT_LIGHTS * sizeof(shader::PointLight)
-	+ MAX_SPOT_LIGHTS * sizeof(shader::SpotLight)
-	+ MAX_SPOT_TEX_LIGHTS * sizeof(shader::SpotTexLight);
-
-/// Align everything to make UBOs happy
-static PtrSize calcLigthsUboSize()
-{
-	PtrSize size;
-	PtrSize uboAlignment = BufferObject::getUniformBufferOffsetAlignment();
-
-	size = alignSizeRoundUp(
-		uboAlignment,
-		MAX_POINT_LIGHTS * sizeof(shader::PointLight));
-
-	size += alignSizeRoundUp(
-		uboAlignment,
-		MAX_SPOT_LIGHTS * sizeof(shader::SpotLight));
-
-	size += alignSizeRoundUp(
-		uboAlignment,
-		MAX_SPOT_TEX_LIGHTS * sizeof(shader::SpotTexLight));
-
-	return size;
-}
-
 //==============================================================================
 // Use compute shaders on GL >= 4.3
 static Bool useCompute()
@@ -217,7 +184,7 @@ struct WriteLightsJob: ThreadJob
 	{
 		// Get GPU light
 		I i = pointLightsCount->fetch_add(1);
-		if(i >= (I)MAX_POINT_LIGHTS)
+		if(i >= (I)is->maxPointLights)
 		{
 			return -1;
 		}
@@ -250,7 +217,7 @@ struct WriteLightsJob: ThreadJob
 			// Spot tex light
 
 			i = spotTexLightsCount->fetch_add(1);
-			if(i >= (I)MAX_SPOT_TEX_LIGHTS)
+			if(i >= (I)is->maxSpotTexLights)
 			{
 				return -1;
 			}
@@ -277,7 +244,7 @@ struct WriteLightsJob: ThreadJob
 			// Spot light without texture
 
 			i = spotLightsCount->fetch_add(1);
-			if(i >= (I)MAX_SPOT_LIGHTS)
+			if(i >= (I)is->maxSpotLights)
 			{
 				return -1;
 			}
@@ -423,6 +390,14 @@ void Is::init(const RendererInitializer& initializer)
 void Is::initInternal(const RendererInitializer& initializer)
 {
 	groundLightEnabled = initializer.is.groundLightEnabled;
+	maxPointLights = initializer.is.maxPointLights;
+	maxSpotLights = initializer.is.maxSpotLights;
+	maxSpotTexLights = initializer.is.maxSpotTexLights;
+
+	if(maxPointLights < 1 || maxSpotLights < 1 || maxSpotTexLights < 1)
+	{
+		throw ANKI_EXCEPTION("Incorrect number of max lights");
+	}
 
 	//
 	// Init the passes
@@ -445,9 +420,9 @@ void Is::initInternal(const RendererInitializer& initializer)
 		<< "\n"
 		<< "#define MAX_SPOT_TEX_LIGHTS_PER_TILE " 
 		<< MAX_SPOT_TEX_LIGHTS_PER_TILE << "\n"
-		<< "#define MAX_POINT_LIGHTS " << MAX_POINT_LIGHTS << "\n"
-		<< "#define MAX_SPOT_LIGHTS " << MAX_SPOT_LIGHTS << "\n"
-		<< "#define MAX_SPOT_TEX_LIGHTS " << MAX_SPOT_TEX_LIGHTS << "\n"
+		<< "#define MAX_POINT_LIGHTS " << (U32)maxPointLights << "\n"
+		<< "#define MAX_SPOT_LIGHTS " << (U32)maxSpotLights << "\n"
+		<< "#define MAX_SPOT_TEX_LIGHTS " << (U32)maxSpotTexLights << "\n"
 		<< "#define GROUND_LIGHT " << groundLightEnabled << "\n"
 		<< "#define USE_MRT " << ANKI_RENDERER_USE_MRT << "\n";
 
@@ -514,7 +489,7 @@ void Is::initInternal(const RendererInitializer& initializer)
 	commonUbo.create(sizeof(shader::CommonUniforms), nullptr);
 
 	// lights UBO
-	lightsUbo.create(calcLigthsUboSize(), nullptr);
+	lightsUbo.create(calcLightsUboSize(), nullptr);
 	uboAlignment = BufferObject::getUniformBufferOffsetAlignment();
 
 	// tiles BO
@@ -524,7 +499,7 @@ void Is::initInternal(const RendererInitializer& initializer)
 		nullptr, 
 		GL_DYNAMIC_DRAW);
 
-	ANKI_LOGI("Creating BOs: lights: " << calcLigthsUboSize() << "B tiles: "
+	ANKI_LOGI("Creating BOs: lights: " << calcLightsUboSize() << "B tiles: "
 		<< sizeof(shader::Tiles) << "B");
 
 	// Sanity checks
@@ -553,7 +528,7 @@ void Is::initInternal(const RendererInitializer& initializer)
 
 	ublock = &lightPassProg->findUniformBlock("pointLightsBlock");
 	ublock->setBinding(POINT_LIGHTS_BLOCK_BINDING);
-	if(ublock->getSize() != sizeof(shader::PointLight) * MAX_POINT_LIGHTS
+	if(ublock->getSize() != sizeof(shader::PointLight) * maxPointLights
 		|| ublock->getBinding() != POINT_LIGHTS_BLOCK_BINDING)
 	{
 		throw ANKI_EXCEPTION("Problem with the pointLightsBlock");
@@ -564,7 +539,7 @@ void Is::initInternal(const RendererInitializer& initializer)
 	{
 		ublock = &rejectProg->findUniformBlock("pointLightsBlock");
 		ublock->setBinding(POINT_LIGHTS_BLOCK_BINDING);
-		if(ublock->getSize() != sizeof(shader::PointLight) * MAX_POINT_LIGHTS
+		if(ublock->getSize() != sizeof(shader::PointLight) * maxPointLights
 			|| ublock->getBinding() != POINT_LIGHTS_BLOCK_BINDING)
 		{
 			throw ANKI_EXCEPTION("Problem with the pointLightsBlock");
@@ -574,7 +549,7 @@ void Is::initInternal(const RendererInitializer& initializer)
 
 	ublock = &lightPassProg->findUniformBlock("spotLightsBlock");
 	ublock->setBinding(SPOT_LIGHTS_BLOCK_BINDING);
-	if(ublock->getSize() != sizeof(shader::SpotLight) * MAX_SPOT_LIGHTS
+	if(ublock->getSize() != sizeof(shader::SpotLight) * maxSpotLights
 		|| ublock->getBinding() != SPOT_LIGHTS_BLOCK_BINDING)
 	{
 		throw ANKI_EXCEPTION("Problem with the spotLightsBlock");
@@ -582,7 +557,7 @@ void Is::initInternal(const RendererInitializer& initializer)
 
 	ublock = &lightPassProg->findUniformBlock("spotTexLightsBlock");
 	ublock->setBinding(SPOT_TEX_LIGHTS_BLOCK_BINDING);
-	if(ublock->getSize() != sizeof(shader::SpotTexLight) * MAX_SPOT_TEX_LIGHTS
+	if(ublock->getSize() != sizeof(shader::SpotTexLight) * maxSpotTexLights
 		|| ublock->getBinding() != SPOT_TEX_LIGHTS_BLOCK_BINDING)
 	{
 		throw ANKI_EXCEPTION("Problem with the spotTexLightsBlock");
@@ -656,9 +631,9 @@ void Is::lightPass()
 	}
 
 	// Sanitize the counters
-	clamp(visiblePointLightsCount, MAX_POINT_LIGHTS);
-	clamp(visibleSpotLightsCount, MAX_SPOT_LIGHTS);
-	clamp(visibleSpotTexLightsCount, MAX_SPOT_TEX_LIGHTS);
+	clamp(visiblePointLightsCount, maxPointLights);
+	clamp(visibleSpotLightsCount, maxSpotLights);
+	clamp(visibleSpotTexLightsCount, maxSpotTexLights);
 
 	//
 	// Do shadows pass
@@ -685,13 +660,13 @@ void Is::lightPass()
 		sizeof(shader::SpotTexLight) * visibleSpotTexLightsCount;
 	spotTexLightsSize = alignSizeRoundUp(uboAlignment, spotTexLightsSize);
 
-	ANKI_ASSERT(spotTexLightsOffset + spotTexLightsSize <= calcLigthsUboSize());
+	ANKI_ASSERT(spotTexLightsOffset + spotTexLightsSize <= calcLightsUboSize());
 
 	// Fire the super jobs
 	Array<WriteLightsJob, ThreadPool::MAX_THREADS> jobs;
 
-	U8 clientBuffer[MIN_LIGHTS_UBO_SIZE * 2]; // Aproximate size
-	ANKI_ASSERT(MIN_LIGHTS_UBO_SIZE * 2 >= calcLigthsUboSize());
+	U8 clientBuffer[32 * 1024]; // Aproximate size
+	ANKI_ASSERT(sizeof(clientBuffer) >= calcLightsUboSize());
 	shader::Tiles clientTiles;
 
 	std::atomic<U32> pointLightsAtomicCount(0);
@@ -910,4 +885,25 @@ void Is::run()
 	lightPass();
 }
 
+//==============================================================================
+PtrSize Is::calcLightsUboSize() const
+{
+	PtrSize size;
+	PtrSize uboAlignment = BufferObject::getUniformBufferOffsetAlignment();
+
+	size = alignSizeRoundUp(
+		uboAlignment,
+		maxPointLights * sizeof(shader::PointLight));
+
+	size += alignSizeRoundUp(
+		uboAlignment,
+		maxSpotLights * sizeof(shader::SpotLight));
+
+	size += alignSizeRoundUp(
+		uboAlignment,
+		maxSpotTexLights * sizeof(shader::SpotTexLight));
+
+	return size;
+}
+
 } // end namespace anki

+ 4 - 2
src/renderer/Ms.cpp

@@ -112,7 +112,8 @@ void Ms::run()
 		fbo[0].bind(Fbo::FT_READ);
 		glReadBuffer(GL_COLOR_ATTACHMENT1);
 		fbo[1].bind(Fbo::FT_DRAW);
-		glDrawBuffer(GL_COLOR_ATTACHMENT1);
+		static const GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT1};
+		glDrawBuffers(1, drawBuffers);
 
 		glBlitFramebuffer(
 			0, 0, r->width, r->height, 
@@ -121,7 +122,8 @@ void Ms::run()
 			GL_NEAREST);
 
 		glReadBuffer(GL_COLOR_ATTACHMENT0);
-		glDrawBuffer(GL_COLOR_ATTACHMENT0);
+		static const GLenum drawBuffers2[] = {GL_COLOR_ATTACHMENT0};
+		glDrawBuffers(1, drawBuffers2);
 
 		glBlitFramebuffer(
 			0, 0, r->width, r->height, 

+ 5 - 0
testapp/Main.cpp

@@ -569,6 +569,11 @@ void initSubsystems(int argc, char* argv[])
 	initializer.lodDistance = 20.0;
 	initializer.samples = 16;
 
+#if ANKI_GL == ANKI_GL_ES
+	initializer.samples = 1;
+	initializer.pps.enabled = false;
+#endif
+
 	MainRendererSingleton::get().init(initializer);
 
 	// Stdin listener