Quellcode durchsuchen

Compute shader support continues

Panagiotis Christopoulos Charitos vor 12 Jahren
Ursprung
Commit
5ca90f4cb6

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

@@ -75,6 +75,7 @@ private:
 
 	/// Light shaders
 	ShaderProgramResourcePointer lightPassProg;
+	ShaderProgramResourcePointer tilerProg;
 
 	/// Shadow mapping
 	Sm sm;

+ 0 - 19
include/anki/resource/ShaderProgramCommon.h

@@ -1,19 +0,0 @@
-#ifndef ANKI_RESOURCE_SHADER_PROGRAM_COMMON_H
-#define ANKI_RESOURCE_SHADER_PROGRAM_COMMON_H
-
-namespace anki {
-
-/// Shader type
-enum ShaderType
-{
-	ST_VERTEX,
-	ST_TC,
-	ST_TE,
-	ST_GEOMETRY,
-	ST_FRAGMENT,
-	ST_NUM
-};
-
-} // end namespace anki
-
-#endif

+ 13 - 2
include/anki/resource/ShaderProgramPrePreprocessor.h

@@ -1,7 +1,6 @@
 #ifndef ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
 #define ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
 
-#include "anki/resource/ShaderProgramCommon.h"
 #include "anki/util/Vector.h"
 #include "anki/util/StdTypes.h"
 #include "anki/util/StringList.h"
@@ -10,6 +9,18 @@
 
 namespace anki {
 
+/// Shader type
+enum ShaderType
+{
+	ST_VERTEX,
+	ST_TC,
+	ST_TE,
+	ST_GEOMETRY,
+	ST_FRAGMENT,
+	ST_COMPUTE,
+	ST_NUM
+};
+
 /// Helper class used for shader program loading
 ///
 /// The class fills some of the GLSL spec deficiencies. It adds the include
@@ -20,7 +31,7 @@ namespace anki {
 /// The preprocessor pragmas are:
 ///
 /// - #pragma anki start <vertexShader | tcShader | teShader |
-///                       geometryShader | fragmentShader>
+///                       geometryShader | fragmentShader | computeShader>
 /// - #pragma anki include "<filename>"
 /// - #pragma anki transformFeedbackVaryings <separate|interleaved>
 ///   <varName> <varName>

+ 20 - 0
shaders/IsUpdateTiles.glsl

@@ -0,0 +1,20 @@
+#pragma anki start computeShader
+
+// Set workgroup XXX
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+
+struct Tile
+{
+	uvec4 lightsCount;
+	uvec4 lightIndices[MAX_LIGHTS_PER_TILE / 4];
+};
+
+layout(std140, binding = 0) buffer tilesBuffer
+{
+	Tile tiles[TILES_X_COUNT * TILES_Y_COUNT];
+};
+
+void main()
+{
+	tiles[gl_WorkGroupID.x * TILES_Y_COUNT + gl_WorkGroupID.y] = 0.1;
+}

+ 3 - 0
src/renderer/Is.cpp

@@ -323,6 +323,9 @@ void Is::initInternal(const RendererInitializer& initializer)
 	lightPassProg.load(ShaderProgramResource::createSrcCodeToCache(
 		"shaders/IsLp.glsl", pps.c_str()).c_str());
 
+	tilerProg.load(ShaderProgramResource::createSrcCodeToCache(
+		"shaders/IsUpdateTiles.glsl", pps.c_str()).c_str());
+
 	//
 	// Create FBOs
 	//

+ 2 - 0
src/renderer/Tiler.cpp

@@ -26,7 +26,9 @@ struct UpdatePlanesPerspectiveCameraJob: ThreadJob
 
 	void operator()(U threadId, U threadsCount)
 	{
+#if ANKI_TILER_ENABLE_GPU
 		ANKI_ASSERT(tiler && cam && pixels);
+#endif
 
 		U64 start, end;
 		Transform trf = Transform(cam->getWorldTransform());

+ 33 - 14
src/resource/ShaderProgramPrePreprocessor.cpp

@@ -12,12 +12,13 @@ namespace anki {
 
 // Keep the strings in that order so that the start pragmas will match to the
 // ShaderType enums
-static Array<const char*, 8> commands = {{
+static Array<const char*, 9> commands = {{
 	"#pragma anki start vertexShader",
 	"#pragma anki start teShader",
 	"#pragma anki start tcShader",
 	"#pragma anki start geometryShader",
 	"#pragma anki start fragmentShader",
+	"#pragma anki start computeShader",
 	"#pragma anki include",
 	"#pragma anki transformFeedbackVaryings separate",
 	"#pragma anki transformFeedbackVaryings interleaved"}};
@@ -87,22 +88,26 @@ void ShaderProgramPrePreprocessor::parseFileForPragmas(
 		{
 			parseStartPragma(ST_FRAGMENT, line);
 		}
-		else if((npos = line.find(commands[5])) == 0)
+		else if(line.find(commands[ST_COMPUTE]) == 0)
 		{
-			std::string filen = {line, strlen(commands[5]), std::string::npos};
+			parseStartPragma(ST_COMPUTE, line);
+		}
+		else if((npos = line.find(commands[6])) == 0)
+		{
+			std::string filen = {line, strlen(commands[6]), std::string::npos};
 			filen = trimString(filen, " \"");
 
 			parseFileForPragmas(filen, depth + 1);
 		}
-		else if((npos = line.find(commands[6])) == 0)
+		else if((npos = line.find(commands[7])) == 0)
 		{
-			std::string slist = {line, strlen(commands[6]), std::string::npos};
+			std::string slist = {line, strlen(commands[7]), std::string::npos};
 			trffbVaryings = StringList::splitString(slist.c_str(), ' ');
 			xfbBufferMode = XFBBM_SEPARATE;
 		}
-		else if((npos = line.find(commands[7])) == 0)
+		else if((npos = line.find(commands[8])) == 0)
 		{
-			std::string slist = {line, strlen(commands[7]), std::string::npos};
+			std::string slist = {line, strlen(commands[8]), std::string::npos};
 			trffbVaryings = StringList::splitString(slist.c_str(), ' ');
 			xfbBufferMode = XFBBM_INTERLEAVED;
 		}
@@ -140,16 +145,30 @@ void ShaderProgramPrePreprocessor::parseFileInternal(const char* filename)
 	parseFileForPragmas(filename);
 
 	// sanity checks
-	if(!shaderStarts[ST_VERTEX].isDefined())
+	if(!shaderStarts[ST_COMPUTE].isDefined())
 	{
-		throw ANKI_EXCEPTION(ENTRYPOINT_NOT_DEFINED 
-			+ commands[ST_VERTEX]);
-	}
+		if(!shaderStarts[ST_VERTEX].isDefined())
+		{
+			throw ANKI_EXCEPTION(ENTRYPOINT_NOT_DEFINED 
+				+ commands[ST_VERTEX]);
+		}
 
-	if(!shaderStarts[ST_FRAGMENT].isDefined())
+		if(!shaderStarts[ST_FRAGMENT].isDefined())
+		{
+			throw ANKI_EXCEPTION(ENTRYPOINT_NOT_DEFINED 
+				+ commands[ST_FRAGMENT]);
+		}
+	}
+	else
 	{
-		throw ANKI_EXCEPTION(ENTRYPOINT_NOT_DEFINED 
-			+ commands[ST_FRAGMENT]);
+		if(shaderStarts[ST_VERTEX].isDefined() 
+			|| shaderStarts[ST_TE].isDefined()
+			|| shaderStarts[ST_TC].isDefined()
+			|| shaderStarts[ST_FRAGMENT].isDefined()
+			|| shaderStarts[ST_GEOMETRY].isDefined())
+		{
+			throw ANKI_EXCEPTION("Compute shader should be alone");
+		}
 	}
 
 	// construct each shaders' source code

+ 30 - 11
src/resource/ShaderProgramResource.cpp

@@ -45,17 +45,36 @@ void ShaderProgramResource::load(const char* filename, const char* extraSrc)
 		}
 	}
 
-	std::string vertSrc = extraSrc + pars.getShaderSource(ST_VERTEX);
-	std::string fragSrc = extraSrc + pars.getShaderSource(ST_FRAGMENT);
-
-	create(vertSrc.c_str(),
-		nullptr,
-		nullptr,
-		nullptr,
-		fragSrc.c_str(),
-		nullptr,
-		&trfVarsArr[0],
-		xfbBufferMode);
+	// XXX Fix that nonsense
+	if(pars.getShaderSource(ST_VERTEX).size() != 0)
+	{
+		std::string vertSrc = extraSrc + pars.getShaderSource(ST_VERTEX);
+		std::string fragSrc = extraSrc + pars.getShaderSource(ST_FRAGMENT);
+
+		create(
+			vertSrc.c_str(),
+			nullptr,
+			nullptr,
+			nullptr,
+			fragSrc.c_str(),
+			nullptr,
+			&trfVarsArr[0],
+			xfbBufferMode);
+	}
+	else
+	{
+		std::string computeSrc = extraSrc + pars.getShaderSource(ST_COMPUTE);
+
+		create(
+			nullptr,
+			nullptr,
+			nullptr,
+			nullptr,
+			nullptr,
+			computeSrc.c_str(),
+			nullptr,
+			xfbBufferMode);
+	}
 }
 
 //==============================================================================