瀏覽代碼

Changing handling of rendering thread errors

Panagiotis Christopoulos Charitos 11 年之前
父節點
當前提交
90e4a58644

+ 24 - 15
include/anki/gl/GlCommon.h

@@ -11,7 +11,7 @@
 #include "anki/util/NonCopyable.h"
 #include "anki/util/NonCopyable.h"
 #include "anki/util/Assert.h"
 #include "anki/util/Assert.h"
 #include "anki/util/Array.h"
 #include "anki/util/Array.h"
-#include "anki/util/StdTypes.h"
+#include "anki/util/Enum.h"
 #include "anki/Math.h"
 #include "anki/Math.h"
 
 
 #if ANKI_GL == ANKI_GL_DESKTOP
 #if ANKI_GL == ANKI_GL_DESKTOP
@@ -76,23 +76,22 @@ public:
 
 
 /// @}
 /// @}
 
 
-/// @addtogroup opengl_other
-
-/// A function that returns an index from a shader type GLenum
-U computeShaderTypeIndex(const GLenum glType);
-
-/// A function that returns a GLenum from an index
-GLenum computeGlShaderType(const U idx, GLbitfield* bit = nullptr);
-
-/// GL generic callback
-using GlCallback = void(*)(void*);
-using GlMakeCurrentCallback = void(*)(void*, void*);
-
-/// @}
-
 /// @addtogroup opengl_containers
 /// @addtogroup opengl_containers
 /// @{
 /// @{
 
 
+/// Shader type
+enum class ShaderType: U8
+{
+	VERTEX,
+	TESSELLATION_CONTROL,
+	TESSELLATION_EVALUATION,
+	GEOMETRY,
+	FRAGMENT,
+	COMPUTE,
+	COUNT
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ShaderType, inline)
+
 /// Shader program variable. The type is attribute or uniform
 /// Shader program variable. The type is attribute or uniform
 class GlProgramVariable
 class GlProgramVariable
 {
 {
@@ -319,6 +318,16 @@ public:
 	U32 m_baseInstance = 0;	
 	U32 m_baseInstance = 0;	
 };
 };
 
 
+/// A function that returns an index from a shader type GLenum
+ShaderType computeShaderTypeIndex(const GLenum glType);
+
+/// A function that returns a GLenum from an index
+GLenum computeGlShaderType(const ShaderType idx, GLbitfield* bit = nullptr);
+
+/// GL generic callback
+using GlCallback = void(*)(void*);
+using GlMakeCurrentCallback = void(*)(void*, void*);
+
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

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

@@ -129,8 +129,6 @@ private:
 	GlCommandBufferHandle m_syncCommands;
 	GlCommandBufferHandle m_syncCommands;
 	GlClientSyncHandle m_sync;
 	GlClientSyncHandle m_sync;
 
 
-	char* m_error = nullptr;
-
 	/// The function that the thread runs
 	/// The function that the thread runs
 	static I threadCallback(Thread::Info&);
 	static I threadCallback(Thread::Info&);
 	void threadLoop();
 	void threadLoop();

+ 2 - 1
include/anki/resource/Material.h

@@ -364,7 +364,8 @@ private:
 	U64 m_hash;
 	U64 m_hash;
 
 
 	/// Get a program resource
 	/// Get a program resource
-	ProgramResourcePointer& getProgram(const RenderingKey key, U32 shaderId);
+	ProgramResourcePointer& getProgram(
+		const RenderingKey key, ShaderType shaderId);
 
 
 	/// Parse what is within the @code <material></material> @endcode
 	/// Parse what is within the @code <material></material> @endcode
 	void parseMaterialTag(const XmlElement& el, ResourceInitializer& rinit);
 	void parseMaterialTag(const XmlElement& el, ResourceInitializer& rinit);

+ 2 - 1
include/anki/resource/MaterialProgramCreator.h

@@ -57,8 +57,9 @@ public:
 	~MaterialProgramCreator();
 	~MaterialProgramCreator();
 
 
 	/// Get the shader program source code
 	/// Get the shader program source code
-	MPString getProgramSource(U shaderType) const
+	MPString getProgramSource(ShaderType shaderType_) const
 	{
 	{
+		U shaderType = enumToType(shaderType_);
 		ANKI_ASSERT(m_source[shaderType].size() > 0);
 		ANKI_ASSERT(m_source[shaderType].size() > 0);
 		return m_source[shaderType].join(CString("\n"));
 		return m_source[shaderType].join(CString("\n"));
 	}
 	}

+ 1 - 12
include/anki/resource/ProgramPrePreprocessor.h

@@ -9,21 +9,10 @@
 #include "anki/resource/ResourceManager.h"
 #include "anki/resource/ResourceManager.h"
 #include "anki/util/StdTypes.h"
 #include "anki/util/StdTypes.h"
 #include "anki/util/StringList.h"
 #include "anki/util/StringList.h"
+#include "anki/gl/GlCommon.h"
 
 
 namespace anki {
 namespace anki {
 
 
-/// Shader type
-enum class ShaderType
-{
-	VERTEX,
-	TC,
-	TE,
-	GEOMETRY,
-	FRAGMENT,
-	COMPUTE,
-	COUNT
-};
-
 /// Helper class used for shader program loading
 /// Helper class used for shader program loading
 ///
 ///
 /// The class fills some of the GLSL spec deficiencies. It adds the include
 /// The class fills some of the GLSL spec deficiencies. It adds the include

+ 1 - 1
include/anki/resource/ResourcePointer.inl.h

@@ -12,7 +12,7 @@ template<typename T, typename TResourceManager>
 void ResourcePointer<T, TResourceManager>::load(
 void ResourcePointer<T, TResourceManager>::load(
 	const CString& filename, TResourceManager* resources)
 	const CString& filename, TResourceManager* resources)
 {
 {
-	ANKI_ASSERT(m_cb == nullptr);
+	ANKI_ASSERT(m_cb == nullptr && "Already loaded");
 	ANKI_ASSERT(resources != nullptr);
 	ANKI_ASSERT(resources != nullptr);
 
 
 	ResourcePointer other;
 	ResourcePointer other;

+ 26 - 11
shaders/MsCommonTessc.glsl

@@ -13,7 +13,14 @@ layout(vertices = 3) out;
 #define IN_POS3(i_) gl_in[i_].gl_Position.xyz
 #define IN_POS3(i_) gl_in[i_].gl_Position.xyz
 #define OUT_POS4(i_) gl_out[i_].gl_Position
 #define OUT_POS4(i_) gl_out[i_].gl_Position
 
 
+//
 // In
 // In
+//
+in gl_PerVertex
+{
+	vec4 gl_Position;
+} gl_in[];
+
 layout(location = 0) in vec2 inTexCoords[];
 layout(location = 0) in vec2 inTexCoords[];
 layout(location = 1) in mediump vec3 inNormal[];
 layout(location = 1) in mediump vec3 inNormal[];
 #if PASS == COLOR
 #if PASS == COLOR
@@ -23,7 +30,15 @@ layout(location = 2) in mediump vec4 inTangent[];
 layout(location = 3) flat in uint inInstanceId[];
 layout(location = 3) flat in uint inInstanceId[];
 #endif
 #endif
 
 
+//
 // Out
 // Out
+//
+
+out gl_PerVertex
+{
+	vec4 gl_Position;
+} gl_out[];
+
 layout(location = 0) out vec2 outTexCoord[];
 layout(location = 0) out vec2 outTexCoord[];
 layout(location = 1) out vec3 outNormal[];
 layout(location = 1) out vec3 outNormal[];
 #if PASS == COLOR
 #if PASS == COLOR
@@ -76,9 +91,9 @@ void calcPositions()
 	vec3 pos003 = IN_POS3(1);
 	vec3 pos003 = IN_POS3(1);
 	vec3 pos300 = IN_POS3(2);
 	vec3 pos300 = IN_POS3(2);
 
 
-	OUT_POS4(0) = IN_POS3(0);
-	OUT_POS4(1) = IN_POS3(1);
-	OUT_POS4(2) = IN_POS3(2);
+	OUT_POS4(0) = IN_POS4(0);
+	OUT_POS4(1) = IN_POS4(1);
+	OUT_POS4(2) = IN_POS4(2);
 
 
 	// edges are names according to the opposing vertex
 	// edges are names according to the opposing vertex
 	vec3 edgeB300 = pos003 - pos030;
 	vec3 edgeB300 = pos003 - pos030;
@@ -205,9 +220,9 @@ bool isFaceVisible(in mat4 mvp)
 }
 }
 
 
 // Used in phong method
 // Used in phong method
-float calcPhongTerm(int ivId, int i, int j)
+float calcPhongTerm(int ivId, int i, vec3 q)
 {
 {
-	vec3 qMinusP = IN_POS3(j) - IN_POS3(i);
+	vec3 qMinusP = q - IN_POS3(i);
 	return q[ivId] - dot(qMinusP, inNormal[i]) * inNormal[i][ivId];
 	return q[ivId] - dot(qMinusP, inNormal[i]) * inNormal[i][ivId];
 }
 }
 
 
@@ -281,12 +296,12 @@ void tessellatePhongPositionNormalTangentTexCoord(
 		outTangent[IID] = inTangent[IID];
 		outTangent[IID] = inTangent[IID];
 #endif
 #endif
 
 
-		phongPatch.terms[IID][0] = calcPhongTerm(IID, 0, 1) 
-			+ calcPhongTerm(IID, 1, 0);
-		phongPatch.terms[IID][1] = calcPhongTerm(IID, 1, 2) 
-			+ calcPhongTerm(IID, 2, 1);
-		phongPatch.terms[IID][2] = calcPhongTerm(IID, 2, 0) 
-			+ calcPhongTerm(IID, 0, 2);
+		phongPatch.terms[IID][0] = calcPhongTerm(IID, 0, IN_POS3(1))
+			+ calcPhongTerm(IID, 1, IN_POS3(0));
+		phongPatch.terms[IID][1] = calcPhongTerm(IID, 1, IN_POS3(2))
+			+ calcPhongTerm(IID, 2, IN_POS3(1));
+		phongPatch.terms[IID][2] = calcPhongTerm(IID, 2, IN_POS3(0))
+			+ calcPhongTerm(IID, 0, IN_POS3(2));
 	}
 	}
 }
 }
 
 

+ 11 - 11
src/gl/GlCommon.cpp

@@ -8,28 +8,28 @@
 namespace anki {
 namespace anki {
 
 
 //==============================================================================
 //==============================================================================
-U computeShaderTypeIndex(const GLenum glType)
+ShaderType computeShaderTypeIndex(const GLenum glType)
 {
 {
-	U idx = 0;
+	ShaderType idx = ShaderType::VERTEX;
 	switch(glType)
 	switch(glType)
 	{
 	{
 	case GL_VERTEX_SHADER:
 	case GL_VERTEX_SHADER:
-		idx = 0;
+		idx = ShaderType::VERTEX;
 		break;
 		break;
 	case GL_TESS_CONTROL_SHADER:
 	case GL_TESS_CONTROL_SHADER:
-		idx = 1;
+		idx = ShaderType::TESSELLATION_CONTROL;
 		break;
 		break;
 	case GL_TESS_EVALUATION_SHADER:
 	case GL_TESS_EVALUATION_SHADER:
-		idx = 2;
+		idx = ShaderType::TESSELLATION_EVALUATION;
 		break;
 		break;
 	case GL_GEOMETRY_SHADER:
 	case GL_GEOMETRY_SHADER:
-		idx = 3;
+		idx = ShaderType::GEOMETRY;
 		break;
 		break;
 	case GL_FRAGMENT_SHADER:
 	case GL_FRAGMENT_SHADER:
-		idx = 4;
+		idx = ShaderType::FRAGMENT;
 		break;
 		break;
 	case GL_COMPUTE_SHADER:
 	case GL_COMPUTE_SHADER:
-		idx = 5;
+		idx = ShaderType::COMPUTE;
 		break;
 		break;
 	default:
 	default:
 		ANKI_ASSERT(0);
 		ANKI_ASSERT(0);
@@ -39,7 +39,7 @@ U computeShaderTypeIndex(const GLenum glType)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-GLenum computeGlShaderType(const U idx, GLbitfield* bit)
+GLenum computeGlShaderType(const ShaderType idx, GLbitfield* bit)
 {
 {
 	static const Array<GLenum, 6> gltype = {{GL_VERTEX_SHADER, 
 	static const Array<GLenum, 6> gltype = {{GL_VERTEX_SHADER, 
 		GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER,
 		GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER,
@@ -52,10 +52,10 @@ GLenum computeGlShaderType(const U idx, GLbitfield* bit)
 
 
 	if(bit)
 	if(bit)
 	{
 	{
-		*bit = glbit[idx];
+		*bit = glbit[enumToType(idx)];
 	}
 	}
 
 
-	return gltype[idx];
+	return gltype[enumToType(idx)];
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 6 - 3
src/gl/GlProgramPipeline.cpp

@@ -30,7 +30,8 @@ GlProgramPipeline::GlProgramPipeline(
 		if(prog.isCreated())
 		if(prog.isCreated())
 		{
 		{
 			GLbitfield bit;
 			GLbitfield bit;
-			GLenum gltype = computeGlShaderType(i, &bit);
+			GLenum gltype = 
+				computeGlShaderType(static_cast<ShaderType>(i), &bit);
 			ANKI_ASSERT(prog.getType() == gltype && "Attached wrong shader");
 			ANKI_ASSERT(prog.getType() == gltype && "Attached wrong shader");
 			(void)gltype;
 			(void)gltype;
 			glUseProgramStages(m_glName, bit, prog._get().getGlName());
 			glUseProgramStages(m_glName, bit, prog._get().getGlName());
@@ -95,7 +96,8 @@ void GlProgramPipeline::attachProgramsInternal(
 	while(count-- != 0)
 	while(count-- != 0)
 	{
 	{
 		const GlProgramHandle& prog = progs[count];
 		const GlProgramHandle& prog = progs[count];
-		U idx = computeShaderTypeIndex(prog._get().getType());
+		ShaderType type = computeShaderTypeIndex(prog._get().getType());
+		U idx = enumToType(type);
 
 
 		ANKI_ASSERT(!m_progs[idx].isCreated() && "Attaching the same");
 		ANKI_ASSERT(!m_progs[idx].isCreated() && "Attaching the same");
 		m_progs[idx] = prog;
 		m_progs[idx] = prog;
@@ -137,7 +139,8 @@ void GlProgramPipeline::bind()
 GlProgramHandle GlProgramPipeline::getAttachedProgram(GLenum type) const
 GlProgramHandle GlProgramPipeline::getAttachedProgram(GLenum type) const
 {
 {
 	ANKI_ASSERT(isCreated());
 	ANKI_ASSERT(isCreated());
-	U idx = computeShaderTypeIndex(type);
+	ShaderType stype = computeShaderTypeIndex(type);
+	U idx = enumToType(stype);
 	GlProgramHandle prog = m_progs[idx];
 	GlProgramHandle prog = m_progs[idx];
 	ANKI_ASSERT(prog.isCreated() && "Asking for non-created program");
 	ANKI_ASSERT(prog.isCreated() && "Asking for non-created program");
 	return prog;
 	return prog;

+ 3 - 24
src/gl/GlQueue.cpp

@@ -12,14 +12,6 @@
 
 
 namespace anki {
 namespace anki {
 
 
-//==============================================================================
-#define CHECK_ERROR() \
-	if(m_error != nullptr) \
-	{ \
-		throw ANKI_EXCEPTION("GL rendering thread failed with error:\n%s", \
-			&m_error[0]); \
-	}
-
 //==============================================================================
 //==============================================================================
 GlQueue::GlQueue(GlDevice* device, 
 GlQueue::GlQueue(GlDevice* device, 
 	AllocAlignedCallback allocCb, void* allocCbUserData)
 	AllocAlignedCallback allocCb, void* allocCbUserData)
@@ -36,12 +28,7 @@ GlQueue::GlQueue(GlDevice* device,
 
 
 //==============================================================================
 //==============================================================================
 GlQueue::~GlQueue()
 GlQueue::~GlQueue()
-{
-	if(m_error)
-	{
-		m_allocCb(m_allocCbUserData, m_error, 0, 0);
-	}
-}
+{}
 
 
 //==============================================================================
 //==============================================================================
 void GlQueue::flushCommandBuffer(GlCommandBufferHandle& commands)
 void GlQueue::flushCommandBuffer(GlCommandBufferHandle& commands)
@@ -52,8 +39,6 @@ void GlQueue::flushCommandBuffer(GlCommandBufferHandle& commands)
 	{
 	{
 		LockGuard<Mutex> lock(m_mtx);
 		LockGuard<Mutex> lock(m_mtx);
 
 
-		CHECK_ERROR();
-
 		// Set commands
 		// Set commands
 		U64 diff = m_tail - m_head;
 		U64 diff = m_tail - m_head;
 
 
@@ -238,12 +223,8 @@ void GlQueue::threadLoop()
 		}
 		}
 		catch(const std::exception& e)
 		catch(const std::exception& e)
 		{
 		{
-			LockGuard<Mutex> lock(m_mtx);
-			I len = strlen(e.what());
-			m_error = reinterpret_cast<char*>(
-				m_allocCb(m_allocCbUserData, nullptr, len + 1, 1));
-
-			strcpy(m_error, e.what());
+			ANKI_LOGE("Exception in rendering thread. Aborting:\n%s", e.what());
+			abort();
 		}
 		}
 	}
 	}
 
 
@@ -256,8 +237,6 @@ void GlQueue::syncClientServer()
 #if !ANKI_QUEUE_DISABLE_ASYNC
 #if !ANKI_QUEUE_DISABLE_ASYNC
 	flushCommandBuffer(m_syncCommands);
 	flushCommandBuffer(m_syncCommands);
 	m_sync.wait();
 	m_sync.wait();
-
-	CHECK_ERROR();
 #endif
 #endif
 }
 }
 
 

+ 1 - 1
src/resource/AsyncLoader.cpp

@@ -11,7 +11,7 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 AsyncLoader::AsyncLoader(const HeapAllocator<U8>& alloc)
 AsyncLoader::AsyncLoader(const HeapAllocator<U8>& alloc)
 :	m_alloc(alloc),
 :	m_alloc(alloc),
-	m_thread("anki_async_loader")
+	m_thread("anki_asyload")
 {
 {
 	m_thread.start(this, threadCallback);
 	m_thread.start(this, threadCallback);
 }
 }

+ 25 - 17
src/resource/Material.cpp

@@ -147,7 +147,7 @@ Material::~Material()
 
 
 //==============================================================================
 //==============================================================================
 ProgramResourcePointer& Material::getProgram(
 ProgramResourcePointer& Material::getProgram(
-	const RenderingKey key, U32 shaderId)
+	const RenderingKey key, ShaderType shaderId)
 {
 {
 	ANKI_ASSERT((U)key.m_pass < m_passesCount);
 	ANKI_ASSERT((U)key.m_pass < m_passesCount);
 	ANKI_ASSERT(key.m_lod < m_lodsCount);
 	ANKI_ASSERT(key.m_lod < m_lodsCount);
@@ -162,25 +162,25 @@ ProgramResourcePointer& Material::getProgram(
 	U count = 0;
 	U count = 0;
 	switch(shaderId)
 	switch(shaderId)
 	{
 	{
-	case 4:
+	case ShaderType::FRAGMENT:
 		// Count of geom
 		// Count of geom
 		count += 0;
 		count += 0;
-	case 3:
+	case ShaderType::GEOMETRY:
 		// Count of tess
 		// Count of tess
 		if(m_tessellation)
 		if(m_tessellation)
 		{
 		{
 			count += m_passesCount * m_lodsCount;
 			count += m_passesCount * m_lodsCount;
 		}
 		}
-	case 2:
+	case ShaderType::TESSELLATION_EVALUATION:
 		// Count of tess
 		// Count of tess
 		if(m_tessellation)
 		if(m_tessellation)
 		{
 		{
 			count += m_passesCount * m_lodsCount;
 			count += m_passesCount * m_lodsCount;
 		}
 		}
-	case 1:
+	case ShaderType::TESSELLATION_CONTROL:
 		// Count of vert
 		// Count of vert
 		count += m_passesCount * m_lodsCount * tessCount;
 		count += m_passesCount * m_lodsCount * tessCount;
-	case 0:
+	case ShaderType::VERTEX:
 		break;
 		break;
 	default:
 	default:
 		ANKI_ASSERT(0);
 		ANKI_ASSERT(0);
@@ -190,13 +190,13 @@ ProgramResourcePointer& Material::getProgram(
 	U idx = 0;
 	U idx = 0;
 	switch(shaderId)
 	switch(shaderId)
 	{
 	{
-	case 0:
+	case ShaderType::VERTEX:
 		idx = (U)key.m_pass * m_lodsCount * tessCount + key.m_lod * tessCount 
 		idx = (U)key.m_pass * m_lodsCount * tessCount + key.m_lod * tessCount 
 			+ (key.m_tessellation ? 1 : 0);
 			+ (key.m_tessellation ? 1 : 0);
 		break;
 		break;
-	case 1:
-	case 2:
-	case 4:
+	case ShaderType::TESSELLATION_CONTROL:
+	case ShaderType::TESSELLATION_EVALUATION:
+	case ShaderType::FRAGMENT:
 		idx = (U)key.m_pass * m_lodsCount + key.m_lod;
 		idx = (U)key.m_pass * m_lodsCount + key.m_lod;
 		break;
 		break;
 	default:
 	default:
@@ -242,15 +242,19 @@ GlProgramPipelineHandle Material::getProgramPipeline(
 		Array<GlProgramHandle, 5> progs;
 		Array<GlProgramHandle, 5> progs;
 		U progCount = 0;
 		U progCount = 0;
 
 
-		progs[progCount++] = getProgram(key, 0)->getGlProgram();
+		progs[progCount++] = 
+			getProgram(key, ShaderType::VERTEX)->getGlProgram();
 
 
 		if(key.m_tessellation)
 		if(key.m_tessellation)
 		{
 		{
-			progs[progCount++] = getProgram(key, 1)->getGlProgram();
-			progs[progCount++] = getProgram(key, 2)->getGlProgram();
+			progs[progCount++] = getProgram(
+				key, ShaderType::TESSELLATION_CONTROL)->getGlProgram();
+			progs[progCount++] = getProgram(
+				key, ShaderType::TESSELLATION_EVALUATION)->getGlProgram();
 		}
 		}
 
 
-		progs[progCount++] = getProgram(key, 4)->getGlProgram();
+		progs[progCount++] = 
+			getProgram(key, ShaderType::FRAGMENT)->getGlProgram();
 
 
 		GlDevice& gl = m_resources->_getGlDevice();
 		GlDevice& gl = m_resources->_getGlDevice();
 		GlCommandBufferHandle cmdBuff(&gl);
 		GlCommandBufferHandle cmdBuff(&gl);
@@ -370,14 +374,18 @@ void Material::parseMaterialTag(const XmlElement& materialEl,
 	m_pplines.resize(m_passesCount * m_lodsCount * tessCount);
 	m_pplines.resize(m_passesCount * m_lodsCount * tessCount);
 
 
 	m_hash = 0;
 	m_hash = 0;
-	for(U shader = 0; shader < 5; shader++)
+	for(ShaderType shader = ShaderType::VERTEX; 
+		shader <= ShaderType::FRAGMENT; 
+		++shader)
 	{
 	{
-		if(!m_tessellation && (shader == 1 || shader == 2))
+		if(!m_tessellation 
+			&& (shader == ShaderType::TESSELLATION_CONTROL 
+				|| shader == ShaderType::TESSELLATION_EVALUATION))
 		{
 		{
 			continue;
 			continue;
 		}
 		}
 
 
-		if(shader == 3)
+		if(shader == ShaderType::GEOMETRY)
 		{
 		{
 			continue;
 			continue;
 		}
 		}

+ 1 - 1
src/resource/ProgramResource.cpp

@@ -34,7 +34,7 @@ void ProgramResource::load(const CString& filename, const CString& extraSrc,
 	std::strcpy(reinterpret_cast<char*>(glsource.getBaseAddress()), &source[0]);
 	std::strcpy(reinterpret_cast<char*>(glsource.getBaseAddress()), &source[0]);
 
 
 	m_prog = GlProgramHandle(jobs, 
 	m_prog = GlProgramHandle(jobs, 
-		computeGlShaderType((U)pars.getShaderType()), glsource);
+		computeGlShaderType(pars.getShaderType()), glsource);
 
 
 	jobs.flush();
 	jobs.flush();
 }
 }

+ 3 - 0
src/util/Exception.cpp

@@ -9,6 +9,9 @@
 #include <cstring>
 #include <cstring>
 #include <cstdarg>
 #include <cstdarg>
 #include <cstdio> // For vsnprintf
 #include <cstdio> // For vsnprintf
+#if ANKI_DEBUG == 1
+#	include "anki/util/Thread.h"
+#endif
 
 
 // Instead of throwing abort. Its easier to debug
 // Instead of throwing abort. Its easier to debug
 #define ANKI_ABORT_ON_THROW 0
 #define ANKI_ABORT_ON_THROW 0