Procházet zdrojové kódy

Testing compute shaders. They work

Panagiotis Christopoulos Charitos před 12 roky
rodič
revize
cd5752288b

+ 26 - 5
include/anki/gl/BufferObject.h

@@ -47,13 +47,19 @@ public:
 
 	/// @name Accessors
 	/// @{
-	GLenum getBufferTarget() const
+	GLenum getTarget() const
 	{
 		ANKI_ASSERT(isCreated());
 		return target;
 	}
 
-	GLenum getBufferUsage() const
+	void setTarget(GLenum target_)
+	{
+		ANKI_ASSERT(isCreated());
+		target = target_;
+	}
+
+	GLenum getUsage() const
 	{
 		ANKI_ASSERT(isCreated());
 		return usage;
@@ -66,13 +72,21 @@ public:
 	}
 	/// @}
 
-	/// Bind BO
+	/// Bind
 	void bind() const
 	{
 		ANKI_ASSERT(isCreated());
 		glBindBuffer(target, glId);
 	}
 
+	/// Bind and change target
+	void bind(GLenum target_)
+	{
+		ANKI_ASSERT(isCreated());
+		setTarget(target_);
+		glBindBuffer(target, glId);
+	}
+
 	/// Unbind BO
 	void unbind() const
 	{
@@ -139,8 +153,15 @@ public:
 	/// Set the binding for this buffer
 	void setBinding(GLuint binding) const
 	{
-		ANKI_ASSERT(target == GL_TRANSFORM_FEEDBACK_BUFFER 
-			|| target == GL_UNIFORM_BUFFER);
+		Bool correctTarget = target == GL_TRANSFORM_FEEDBACK_BUFFER 
+#if ANKI_GL == ANKI_GL_DESKTOP
+			|| target == GL_SHADER_STORAGE_BUFFER
+#endif
+			|| target == GL_UNIFORM_BUFFER;
+
+		ANKI_ASSERT(correctTarget);
+		(void)correctTarget;
+		
 		bind();
 		glBindBufferBase(target, binding, glId);
 	}

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

@@ -8,11 +8,14 @@ namespace anki {
 /// @addtogroup OpenGL
 /// @{
 
+// Enable the exception on debug. Calling glGetError calls serialization
+
+#if ANKI_DEBUG
+
 /// The function throws an exception if there is an OpenGL error. Use it with
 /// the ANKI_CHECK_GL_ERROR macro
 void glConditionalThrowException(const char* file, int line, const char* func);
 
-#if ANKI_DEBUG
 #	define ANKI_CHECK_GL_ERROR() \
 		glConditionalThrowException(ANKI_FILE, __LINE__, ANKI_FUNC)
 #else

+ 2 - 2
shaders/IsLp.glsl

@@ -321,9 +321,9 @@ void main()
 #endif
 
 #if 0
-	if(tiles[vInstanceId].lightsCount[0] > 0)
+	if(tiles[vInstanceId].lightsCount[3] == 666U)
 	{
-		fColor += vec3(0.2, 0.0, 0.0);
+		fColor += vec3(0.5, 0.0, 0.0);
 	}
 #endif
 

+ 2 - 1
shaders/IsUpdateTiles.glsl

@@ -16,5 +16,6 @@ layout(std140, binding = 0) buffer tilesBuffer
 
 void main()
 {
-	tiles[gl_WorkGroupID.x * TILES_Y_COUNT + gl_WorkGroupID.y] = 0.1;
+	tiles[gl_WorkGroupID.x * TILES_Y_COUNT + gl_WorkGroupID.y].
+		lightsCount.w = 665U;
 }

+ 2 - 2
src/gl/Vao.cpp

@@ -31,7 +31,7 @@ void Vao::attachArrayBufferVbo(const Vbo* vbo, const GLint attribVarLocation,
 {
 	ANKI_ASSERT(isCreated());
 	checkNonSharable();
-	ANKI_ASSERT(vbo->getBufferTarget() == GL_ARRAY_BUFFER
+	ANKI_ASSERT(vbo->getTarget() == GL_ARRAY_BUFFER
 		&& "Only GL_ARRAY_BUFFER is accepted");
 	ANKI_ASSERT(vbo->isCreated());
 
@@ -63,7 +63,7 @@ void Vao::attachElementArrayBufferVbo(const Vbo* vbo)
 {
 	ANKI_ASSERT(isCreated());
 	checkNonSharable();
-	ANKI_ASSERT(vbo->getBufferTarget() == GL_ELEMENT_ARRAY_BUFFER
+	ANKI_ASSERT(vbo->getTarget() == GL_ELEMENT_ARRAY_BUFFER
 		&& "Only GL_ELEMENT_ARRAY_BUFFER is accepted");
 	ANKI_ASSERT(vbo->isCreated());
 

+ 17 - 4
src/renderer/Is.cpp

@@ -28,7 +28,8 @@ namespace shader {
 
 struct Light
 {
-	Vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
+	/// xyz: Light pos in eye space. w: The radius. In viewspace
+	Vec4 posAndRadius;
 	Vec4 diffuseColorShadowmapId;
 	Vec4 specularColor;
 };
@@ -506,7 +507,7 @@ void Is::lightPass()
 	// Write the lights UBOs
 	//
 
-	// Map points
+	// Write pointlights
 	if(visiblePointLightsCount > 0)
 	{
 		shader::PointLights clientBuffer;
@@ -531,7 +532,7 @@ void Is::lightPass()
 			sizeof(shader::PointLight) * visiblePointLightsCount);
 	}
 
-	// Map spots
+	// Write spots
 	if(visibleSpotLightsCount > 0)
 	{
 		shader::SpotLights clientBuffer;
@@ -594,7 +595,19 @@ void Is::lightPass()
 
 	threadPool.waitForAllJobsToFinish();
 
-	tilesUbo.write(&clientBuffer, 0, sizeof(shader::Tiles));
+	tilesUbo.write(&clientBuffer);
+
+	// XXX
+	{
+		tilesUbo.bind(GL_SHADER_STORAGE_BUFFER);
+		tilesUbo.setBinding(0);
+
+		tilerProg->bind();
+
+		glDispatchCompute(Tiler::TILES_X_COUNT, Tiler::TILES_Y_COUNT, 1);
+
+		tilesUbo.bind(GL_UNIFORM_BUFFER);
+	}
 
 	//
 	// Setup shader and draw

+ 23 - 10
src/resource/ShaderProgramPrePreprocessor.cpp

@@ -23,7 +23,7 @@ static Array<const char*, 9> commands = {{
 	"#pragma anki transformFeedbackVaryings separate",
 	"#pragma anki transformFeedbackVaryings interleaved"}};
 
-static_assert(ST_VERTEX == 0 && ST_FRAGMENT == 4, "See file");
+static_assert(ST_VERTEX == 0 && ST_COMPUTE == 5, "See file");
 
 static const char* ENTRYPOINT_NOT_DEFINED = "Entry point not defined: ";
 
@@ -141,12 +141,16 @@ void ShaderProgramPrePreprocessor::parseFile(const char* filename)
 //==============================================================================
 void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 {
-	// parse master file
+	ShaderType firstShader; // Before that shader there is global code
+
+	// Parse master file
 	parseFileForPragmas(filename);
 
-	// sanity checks
+	// Sanity checks and some calculations
 	if(!shaderStarts[ST_COMPUTE].isDefined())
 	{
+		// If not compute then vertex and fragment shaders should be defined
+
 		if(!shaderStarts[ST_VERTEX].isDefined())
 		{
 			throw ANKI_EXCEPTION(ENTRYPOINT_NOT_DEFINED 
@@ -158,9 +162,13 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 			throw ANKI_EXCEPTION(ENTRYPOINT_NOT_DEFINED 
 				+ commands[ST_FRAGMENT]);
 		}
+
+		firstShader = ST_VERTEX;
 	}
 	else
 	{
+		// If compute is defined everything else should not be
+
 		if(shaderStarts[ST_VERTEX].isDefined() 
 			|| shaderStarts[ST_TE].isDefined()
 			|| shaderStarts[ST_TC].isDefined()
@@ -169,9 +177,11 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 		{
 			throw ANKI_EXCEPTION("Compute shader should be alone");
 		}
+
+		firstShader = ST_COMPUTE;
 	}
 
-	// construct each shaders' source code
+	// Construct each shaders' source code
 	for(U i = 0; i < ST_NUM; i++)
 	{
 		// If not defined bb
@@ -183,7 +193,7 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 		std::string& src = shaderSources[i];
 		src = "";
 
-		// Sanity check: Check the correct order of i
+		// The i-nth shader should be defined after the [0, i-1]
 		I32 k = (I32)i - 1;
 		while(k > -1)
 		{
@@ -196,6 +206,7 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 			--k;
 		}
 
+		// And shouldn't be defined before the [i+1, ST_NUM-1]
 		k = (I32)i + 1;
 		while(k < ST_NUM)
 		{
@@ -208,16 +219,18 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 			++k;
 		}
 
-		// put global source code
-		for(I32 j = 0; j < shaderStarts[ST_VERTEX].definedLine; ++j)
+		// Append the global source code
+		ANKI_ASSERT(shaderStarts[firstShader].definedLine != -1);
+		for(I32 j = 0; j < shaderStarts[firstShader].definedLine; ++j)
 		{
 			src += sourceLines[j] + "\n";
 		}
 
-		// put the actual code
+		// Put the actual code
 		U32 from = i;
 		U32 to;
 
+		// Calculate the "to". If i is vertex the to could be anything
 		for(to = i + 1; to < ST_NUM; to++)
 		{
 			if(shaderStarts[to].definedLine != -1)
@@ -226,8 +239,8 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 			}
 		}
 
-		I32 toLine = (to == ST_NUM) ? sourceLines.size() 
-			: shaderStarts[to].definedLine;
+		I32 toLine = (to != ST_NUM) ? shaderStarts[to].definedLine
+			: sourceLines.size();
 
 		for(I32 j = shaderStarts[from].definedLine; j < toLine; ++j)
 		{

+ 1 - 1
src/scene/SceneGraph.cpp

@@ -46,7 +46,7 @@ static void updateSceneNode(SceneNode& sn, F32 prevUpdateTime,
 		if(sp->getSpatialTimestamp() >= Timestamp::getTimestamp())
 		{
 			sp->update();
-			sectorGroup.placeSceneNode(&sn);
+			//sectorGroup.placeSceneNode(&sn);
 		}
 		sp->resetFrame();
 	}