Browse Source

Some work in pipeline

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
6145a3a0de

+ 8 - 2
CMakeLists.txt

@@ -107,7 +107,9 @@ endif()
 add_definitions(-fno-exceptions)
 
 # static libstdc++
-set(CXX_FLAGS "${CXX_FLAGS} -static-libstdc++ ")
+if(${CMAKE_C_COMPILER_ID} MATCHES "GNU")
+	set(CXX_FLAGS "${CXX_FLAGS} -static-libstdc++ ")
+endif()
 
 # SSE
 if(ANKI_ENABLE_SIMD)
@@ -121,7 +123,11 @@ endif()
 if(${ANKI_BUILD_TYPE} STREQUAL "Debug")
 	# Debug
 
-	set(COMPILER_FLAGS "${COMPILER_FLAGS} -g3 -O0 -fstack-check ")
+	set(COMPILER_FLAGS "${COMPILER_FLAGS} -g3 -O0 ")
+
+	if(${CMAKE_C_COMPILER_ID} MATCHES "GNU")
+		set(COMPILER_FLAGS "${COMPILER_FLAGS} -fstack-check ")
+	endif()
 else()
 	# Release
 

+ 0 - 3
include/anki/gr/Common.h

@@ -214,9 +214,6 @@ public:
 
 /// 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);
 /// @}
 
 } // end namespace anki

+ 17 - 2
include/anki/gr/Enums.h

@@ -113,7 +113,12 @@ enum class ComponentFormat: U8
 	R8G8B8_S3TC, ///< DXT1
 	R8G8B8_ETC2,
 	R8G8B8A8_S3TC, ///< DXT5
-	R8G8B8A8_ETC2
+	R8G8B8A8_ETC2,
+
+	// Depth
+	D16,
+	D24,
+	D32
 };
 
 enum class TransformFormat: U8
@@ -179,7 +184,17 @@ ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ShaderVariableDataType, inline)
 /// Format for images and vertex attributes.
 struct PixelFormat
 {
-	ComponentFormat m_components = ComponentFormat::R8;
+	PixelFormat() = default;
+
+	PixelFormat(const PixelFormat&) = default;
+
+	PixelFormat(ComponentFormat cf, TransformFormat tf, Bool srgb)
+	:	m_components(cf),
+		m_transform(tf),
+		m_srgb(srgb)
+	{}
+
+	ComponentFormat m_components = ComponentFormat::R8G8B8A8;
 	TransformFormat m_transform = TransformFormat::UNORM;
 	Bool8 m_srgb = false;
 };

+ 18 - 10
include/anki/gr/PipelineCommon.h

@@ -49,8 +49,6 @@ struct TessellationStateInfo
 struct ViewportStateInfo
 {
 	Bool8 m_scissorEnabled = false;
-	Array<U32, 4> m_scissorRect = {{0, 0, 0, 0}};
-	Array<U32, 4> m_viewport = {{0, 0, 0, 0}};
 };
 
 struct RasterizerStateInfo
@@ -59,19 +57,27 @@ struct RasterizerStateInfo
 	CullMode m_cullMode = CullMode::BACK;
 };
 
-struct DepthStateInfo
+struct DepthStencilStateInfo
 {
-	Bool8 m_writeEnabled = false;
-	DepthCompareFunction m_compareFunction;
+	Bool8 m_depthWriteEnabled = false;
+	DepthCompareFunction m_depthCompareFunction = DepthCompareFunction::LESS;
+	PixelFormat m_format;
+};
+
+struct ColorAttachmentStateInfo
+{
+	BlendMethod m_srcBlendMethod = BlendMethod::ONE;
+	BlendMethod m_dstBlendMethod = BlendMethod::ZERO;
+	BlendFunction m_blendFunction = BlendFunction::ADD;
+	PixelFormat m_format;
 };
 
 struct ColorStateInfo
 {
 	Bool8 m_alphaToCoverageEnabled = false;
 	Bool8 m_blendEnabled = false;
-	BlendMethod m_srcBlendMethod = BlendMethod::ONE;
-	BlendMethod m_dstBlendMethod = BlendMethod::ONE;
-	BlendFunction m_blendFunction = BlendFunction::ADD;
+	U8 m_colorAttachmentsCount = 0;
+	Array<ColorAttachmentStateInfo, MAX_COLOR_ATTACHMENTS> m_attachments;
 	U8 m_channelWriteMask = 15;
 };
 
@@ -84,7 +90,9 @@ enum class SubStateBit: U16
 	VIEWPORT = 1 << 3,
 	RASTERIZER = 1 << 4,
 	DEPTH = 1 << 5,
-	COLOR = 1 << 6
+	COLOR = 1 << 6,
+	ALL = VERTEX | INPUT_ASSEMBLER | TESSELLATION | VIEWPORT | RASTERIZER 
+		| DEPTH | COLOR
 };
 
 /// Pipeline initializer.
@@ -95,7 +103,7 @@ struct PipelineInitializer
 	TessellationStateInfo m_tessellation;
 	ViewportStateInfo m_viewport;
 	RasterizerStateInfo m_rasterizer;
-	DepthStateInfo m_depthStencil;
+	DepthStencilStateInfo m_depthStencil;
 	ColorStateInfo m_color;
 
 	Array<ShaderHandle, 6> m_shaders;

+ 2 - 13
include/anki/gr/PipelineHandle.h

@@ -19,6 +19,7 @@ class PipelineHandle: public GrHandle<PipelineImpl>
 {
 public:
 	using Base = GrHandle<PipelineImpl>;
+	using Initializer = PipelineInitializer;
 
 	PipelineHandle();
 
@@ -27,22 +28,10 @@ public:
 	/// Create a pipeline
 	ANKI_USE_RESULT Error create(
 		CommandBufferHandle& commands,
-		const ShaderHandle* progsBegin, const ShaderHandle* progsEnd)
-	{
-		return commonConstructor(commands, progsBegin, progsEnd);
-	}
-
-	/// Create using initializer list
-	ANKI_USE_RESULT Error create(
-		CommandBufferHandle& commands,
-		std::initializer_list<ShaderHandle> progs);
+		const Initializer& init);
 
 	/// Bind it to the state
 	void bind(CommandBufferHandle& commands);
-
-public:
-	ANKI_USE_RESULT Error commonConstructor(CommandBufferHandle& commands,
-		const ShaderHandle* progsBegin, const ShaderHandle* progsEnd);
 };
 /// @}
 

+ 3 - 3
include/anki/gr/gl/PipelineImpl.h

@@ -19,6 +19,7 @@ class PipelineImpl: public GlObject
 {
 public:
 	using Base = GlObject;
+	using Initializer = PipelineInitializer;
 
 	PipelineImpl(GrManager* manager)
 	:	Base(manager)
@@ -29,8 +30,7 @@ public:
 		destroy();
 	}
 
-	ANKI_USE_RESULT Error create(
-		const ShaderHandle* progsBegin, const ShaderHandle* progsEnd);
+	ANKI_USE_RESULT Error create(const Initializer& init);
 
 	/// Bind the pipeline to the state
 	void bind();
@@ -42,7 +42,7 @@ private:
 	void createPpline();
 
 	/// Attach all the programs
-	void attachProgramsInternal(const ShaderHandle* progs, PtrSize count);
+	void attachProgramsInternal(const Initializer& init);
 
 	void destroy();
 };

+ 16 - 0
include/anki/renderer/Common.h

@@ -6,11 +6,27 @@
 #ifndef ANKI_RENDERER_COMMON_H
 #define ANKI_RENDERER_COMMON_H
 
+#include "anki/Gr.h"
+
 namespace anki {
 
 // Forward
 class Fs;
 
+// Render target formats
+const U MS_COLOR_ATTACHMENTS_COUNT = 2;
+
+const Array<PixelFormat, MS_COLOR_ATTACHMENTS_COUNT> 
+	MS_COLOR_ATTACHMENTS_PIXEL_FORMAT = {{
+	{ComponentFormat::R8G8B8A8, TransformFormat::UNORM, false},
+	{ComponentFormat::R8G8B8A8, TransformFormat::UNORM, false}}};
+
+const PixelFormat MS_DEPTH_STENCIL_ATTACHMENT_FORMAT = {
+	ComponentFormat::D24, TransformFormat::FLOAT, false};
+
+const PixelFormat FS_COLOR_ATTACHMENT_FORMAT = {
+	ComponentFormat::R8G8B8, TransformFormat::UNORM, false};
+
 } // end namespace anki
 
 #endif

+ 35 - 0
include/anki/resource/MaterialCommon.h

@@ -0,0 +1,35 @@
+// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#ifndef ANKI_RESOURSE_MATERIAL_COMMON_H
+#define ANKI_RESOURSE_MATERIAL_COMMON_H
+
+#include "anki/resource/Common.h"
+#include "anki/resource/RenderingKey.h"
+#include "anki/util/NonCopyable.h"
+#include "anki/Gr.h"
+
+namespace anki {
+
+/// @addtogroup resource
+/// @{
+
+/// Data that will be used in material loading.
+class MaterialResourceData: public NonCopyable
+{
+public:
+	PipelineHandle m_pipelines[U(Pass::COUNT)];
+
+	MaterialResourceData() = default;
+	~MaterialResourceData() = default;
+
+	ANKI_USE_RESULT Error create(ResourceManager& manager);
+};
+/// @}
+
+} // end namespace anki
+
+#endif
+

+ 8 - 1
include/anki/resource/ResourceManager.h

@@ -20,6 +20,7 @@ class GrManager;
 class PhysicsWorld;
 class ResourceManager;
 class AsyncLoader;
+class MaterialResourceData;
 
 // NOTE: Add resources in 3 places
 #define ANKI_RESOURCE(rsrc_, name_) \
@@ -241,6 +242,12 @@ public:
 	{
 		return *m_asyncLoader;
 	}
+
+	MaterialResourceData& getMaterialData()
+	{
+		ANKI_ASSERT(m_materialData);
+		return *m_materialData;
+	}
 	/// @}
 
 private:
@@ -254,10 +261,10 @@ private:
 	U32 m_textureAnisotropy;
 	String m_shadersPrependedSource;
 	AsyncLoader* m_asyncLoader = nullptr; ///< Async loading thread
+	MaterialResourceData* m_materialData = nullptr;
 };
 
 #undef ANKI_RESOURCE
-
 /// @}
 
 } // end namespace anki

+ 0 - 20
src/gr/Common.cpp

@@ -38,26 +38,6 @@ ShaderType computeShaderTypeIndex(const GLenum glType)
 	return idx;
 }
 
-//==============================================================================
-GLenum computeGlShaderType(const ShaderType idx, GLbitfield* bit)
-{
-	static const Array<GLenum, 6> gltype = {{GL_VERTEX_SHADER, 
-		GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER,
-		GL_FRAGMENT_SHADER, GL_COMPUTE_SHADER}};
-
-	static const Array<GLuint, 6> glbit = {{
-		GL_VERTEX_SHADER_BIT, GL_TESS_CONTROL_SHADER_BIT, 
-		GL_TESS_EVALUATION_SHADER_BIT, GL_GEOMETRY_SHADER_BIT,
-		GL_FRAGMENT_SHADER_BIT, GL_COMPUTE_SHADER_BIT}};
-
-	if(bit)
-	{
-		*bit = glbit[enumToType(idx)];
-	}
-
-	return gltype[enumToType(idx)];
-}
-
 //==============================================================================
 template<typename T>
 void writeShaderBlockMemorySanityChecks(

+ 9 - 34
src/gr/gl/PipelineHandle.cpp

@@ -17,25 +17,17 @@ class CreatePipelineCommand final: public GlCommand
 {
 public:
 	PipelineHandle m_ppline;
-	Array<ShaderHandle, 6> m_progs;
-	U8 m_progsCount;
+	PipelineInitializer m_init;
 
-	CreatePipelineCommand(PipelineHandle& ppline, 
-		const ShaderHandle* progsBegin, const ShaderHandle* progsEnd)
-	:	m_ppline(ppline)
-	{
-		m_progsCount = 0;
-		const ShaderHandle* prog = progsBegin;
-		do
-		{
-			m_progs[m_progsCount++] = *prog;
-		} while(++prog != progsEnd);
-	}
+	CreatePipelineCommand(
+		PipelineHandle& ppline, 
+		const PipelineInitializer& init)
+	:	m_init(init)
+	{}
 
 	Error operator()(CommandBufferImpl* cmdb)
 	{
-		Error err = m_ppline.get().create(
-			&m_progs[0], &m_progs[0] + m_progsCount);
+		Error err = m_ppline.get().create(m_init);
 
 		GlObject::State oldState = m_ppline.get().setStateAtomically(
 			err ? GlObject::State::ERROR : GlObject::State::CREATED);
@@ -86,31 +78,14 @@ PipelineHandle::~PipelineHandle()
 //==============================================================================
 Error PipelineHandle::create(
 	CommandBufferHandle& commands,
-	std::initializer_list<ShaderHandle> iprogs)
-{
-	Array<ShaderHandle, 6> progs;
-
-	U count = 0;
-	for(ShaderHandle prog : iprogs)
-	{
-		progs[count++] = prog;
-	}
-
-	return commonConstructor(commands, &progs[0], &progs[0] + count);
-}
-
-//==============================================================================
-Error PipelineHandle::commonConstructor(
-	CommandBufferHandle& commands,
-	const ShaderHandle* progsBegin, const ShaderHandle* progsEnd)
+	const Initializer& init)
 {
 	using DeleteCommand = DeleteObjectCommand<PipelineImpl>;
 	using Deleter = DeferredDeleter<PipelineImpl, DeleteCommand>;
 
 	Base::create(commands.get().getManager(), Deleter());
 	get().setStateAtomically(GlObject::State::TO_BE_CREATED);
-	commands.get().pushBackNewCommand<CreatePipelineCommand>(
-		*this, progsBegin, progsEnd);
+	commands.get().pushBackNewCommand<CreatePipelineCommand>(*this, init);
 
 	return ErrorCode::NONE;
 }

+ 32 - 20
src/gr/gl/PipelineImpl.cpp

@@ -10,15 +10,31 @@
 namespace anki {
 
 //==============================================================================
-Error PipelineImpl::create(
-	const ShaderHandle* progsBegin, const ShaderHandle* progsEnd)
+static GLenum computeGlShaderType(const ShaderType idx, GLbitfield* bit)
 {
-	ANKI_ASSERT(progsBegin != nullptr && progsEnd != nullptr);
-	ANKI_ASSERT(progsBegin != progsEnd);
+	static const Array<GLenum, 6> gltype = {{GL_VERTEX_SHADER, 
+		GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER,
+		GL_FRAGMENT_SHADER, GL_COMPUTE_SHADER}};
 
+	static const Array<GLuint, 6> glbit = {{
+		GL_VERTEX_SHADER_BIT, GL_TESS_CONTROL_SHADER_BIT, 
+		GL_TESS_EVALUATION_SHADER_BIT, GL_GEOMETRY_SHADER_BIT,
+		GL_FRAGMENT_SHADER_BIT, GL_COMPUTE_SHADER_BIT}};
+
+	if(bit)
+	{
+		*bit = glbit[enumToType(idx)];
+	}
+
+	return gltype[enumToType(idx)];
+}
+
+//==============================================================================
+Error PipelineImpl::create(const Initializer& init)
+{
 	Error err = ErrorCode::NONE;
 
-	attachProgramsInternal(progsBegin, progsEnd - progsBegin);
+	attachProgramsInternal(init);
 
 	// Create and attach programs
 	glGenProgramPipelines(1, &m_glName);
@@ -26,18 +42,14 @@ Error PipelineImpl::create(
 
 	glBindProgramPipeline(m_glName);
 
-	for(U i = 0; i < m_shaders.size(); i++)
+	for(U i = 0; i < m_shaders.getSize(); i++)
 	{
 		ShaderHandle& shader = m_shaders[i];
 
 		if(shader.isCreated())
 		{
 			GLbitfield bit;
-			GLenum gltype = 
-				computeGlShaderType(static_cast<ShaderType>(i), &bit);
-			ANKI_ASSERT(shader.get().getGlType() == gltype 
-				&& "Attached wrong shader");
-			(void)gltype;
+			computeGlShaderType(static_cast<ShaderType>(i), &bit);
 			glUseProgramStages(m_glName, bit, shader.get().getGlName());
 		}
 	}
@@ -81,19 +93,19 @@ void PipelineImpl::destroy()
 }
 
 //==============================================================================
-void PipelineImpl::attachProgramsInternal(
-	const ShaderHandle* progs, PtrSize count)
+void PipelineImpl::attachProgramsInternal(const Initializer& init)
 {
 	U mask = 0;
+	U count = 6;
 	while(count-- != 0)
 	{
-		const ShaderHandle& prog = progs[count];
-		ShaderType type = prog.get().getType();
-		U idx = enumToType(type);
-
-		ANKI_ASSERT(!m_shaders[idx].isCreated() && "Attaching the same");
-		m_shaders[idx] = prog;
-		mask |= 1 << idx;
+		const ShaderHandle& shader = init.m_shaders[count];
+		if(shader.isCreated())
+		{
+			ANKI_ASSERT(count == enumToType(shader.get().getType()));
+			m_shaders[count] = shader;
+			mask |= 1 << count;
+		}
 	}
 
 	// Check what we attached

+ 5 - 2
src/renderer/DebugDrawer.cpp

@@ -49,8 +49,11 @@ Error DebugDrawer::create(Renderer* r)
 
 	if(!err)
 	{
-		err = m_ppline.create(jobs, 
-			{m_vert->getGrShader(), m_frag->getGrShader()});
+		PipelineHandle::Initializer init;
+		init.m_shaders[U(ShaderType::VERTEX)] = m_vert->getGrShader();
+		init.m_shaders[U(ShaderType::FRAGMENT)] = m_frag->getGrShader();
+
+		err = m_ppline.create(jobs, init);
 	}
 
 	if(!err)

+ 4 - 2
src/renderer/Is.cpp

@@ -212,8 +212,10 @@ Error Is::initInternal(const ConfigSet& config)
 	ANKI_CHECK(m_lightFrag.loadToCache(&getResourceManager(),
 		"shaders/IsLp.frag.glsl", pps.toCString(), "r_"));
 
-	ANKI_CHECK(m_lightPpline.create(cmdBuff, 
-		{m_lightVert->getGrShader(), m_lightFrag->getGrShader()}));
+	PipelineHandle::Initializer init;
+		init.m_shaders[U(ShaderType::VERTEX)] = m_lightVert->getGrShader();
+		init.m_shaders[U(ShaderType::FRAGMENT)] = m_lightFrag->getGrShader();
+	ANKI_CHECK(m_lightPpline.create(cmdBuff, init));
 
 	//
 	// Create framebuffer

+ 9 - 4
src/renderer/Lf.cpp

@@ -97,8 +97,10 @@ Error Lf::initSprite(const ConfigSet& config,
 	ANKI_CHECK(m_realFrag.loadToCache(&getResourceManager(), 
 		"shaders/PpsLfSpritePass.frag.glsl", pps.toCString(), "r_"));
 
-	ANKI_CHECK(m_realPpline.create(cmdBuff,
-		{m_realVert->getGrShader(), m_realFrag->getGrShader()}));
+	PipelineHandle::Initializer init;
+	init.m_shaders[U(ShaderType::VERTEX)] = m_realVert->getGrShader();
+	init.m_shaders[U(ShaderType::FRAGMENT)] = m_realFrag->getGrShader();
+	ANKI_CHECK(m_realPpline.create(cmdBuff, init));
 
 	// Create buffer
 	PtrSize uboAlignment = 
@@ -142,8 +144,11 @@ Error Lf::initOcclusion(
 	ANKI_CHECK(m_occlusionFrag.load("shaders/PpsLfOcclusion.frag.glsl",
 		&getResourceManager()));
 
-	ANKI_CHECK(m_occlusionPpline.create(cmdBuff,
-		{m_occlusionVert->getGrShader(), m_occlusionFrag->getGrShader()}));
+	PipelineHandle::Initializer init;
+		init.m_shaders[U(ShaderType::VERTEX)] = m_occlusionVert->getGrShader();
+		init.m_shaders[U(ShaderType::FRAGMENT)] = 
+			m_occlusionFrag->getGrShader();
+	ANKI_CHECK(m_occlusionPpline.create(cmdBuff, init));
 
 	return ErrorCode::NONE;
 }

+ 4 - 3
src/renderer/Renderer.cpp

@@ -291,10 +291,11 @@ Error Renderer::createDrawQuadPipeline(
 
 	if(!err)
 	{
-		Array<ShaderHandle, 2> progs = 
-			{{m_drawQuadVert->getGrShader(), frag}};
+		PipelineHandle::Initializer init;
+		init.m_shaders[U(ShaderType::VERTEX)] = m_drawQuadVert->getGrShader();
+		init.m_shaders[U(ShaderType::FRAGMENT)] = frag;
 
-		err = ppline.create(cmdBuff, &progs[0], &progs[0] + 2);
+		err = ppline.create(cmdBuff, init);
 	}
 
 	if(!err)

+ 8 - 7
src/resource/Material.cpp

@@ -320,28 +320,29 @@ Error Material::getProgramPipeline(
 	// Lazily create it
 	if(ANKI_UNLIKELY(!ppline.isCreated()))
 	{
-		Array<ShaderHandle, 5> progs;
-		U progCount = 0;
+		PipelineHandle::Initializer pplineInit;
 
-		progs[progCount++] = 
+		pplineInit.m_shaders[U(ShaderType::VERTEX)] = 
 			getProgram(key, ShaderType::VERTEX)->getGrShader();
 
 		if(key.m_tessellation)
 		{
-			progs[progCount++] = getProgram(
+			pplineInit.m_shaders[U(ShaderType::TESSELLATION_CONTROL)] = 
+				getProgram(
 				key, ShaderType::TESSELLATION_CONTROL)->getGrShader();
-			progs[progCount++] = getProgram(
+			pplineInit.m_shaders[U(ShaderType::TESSELLATION_EVALUATION)] = 
+				getProgram(
 				key, ShaderType::TESSELLATION_EVALUATION)->getGrShader();
 		}
 
-		progs[progCount++] = 
+		pplineInit.m_shaders[U(ShaderType::FRAGMENT)] = 
 			getProgram(key, ShaderType::FRAGMENT)->getGrShader();
 
 		GrManager& gl = m_resources->getGrManager();
 		CommandBufferHandle cmdBuff;
 		ANKI_CHECK(cmdBuff.create(&gl));
 
-		ANKI_CHECK(ppline.create(cmdBuff, &progs[0], &progs[0] + progCount));
+		ANKI_CHECK(ppline.create(cmdBuff, pplineInit));
 
 		cmdBuff.flush();
 	}

+ 30 - 0
src/resource/MaterialCommon.cpp

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "anki/resource/MaterialCommon.h"
+#include "anki/resource/ResourceManager.h"
+#include "anki/resource/Mesh.h"
+#include "anki/renderer/Common.h"
+
+namespace anki {
+
+//==============================================================================
+Error MaterialResourceData::create(ResourceManager& resources)
+{
+	PipelineHandle::Initializer init;
+	init.m_depthStencil.m_depthWriteEnabled = true;
+	init.m_color.m_colorAttachmentsCount = MS_COLOR_ATTACHMENTS_COUNT;
+	for(U i = 0; i < MS_COLOR_ATTACHMENTS_COUNT; ++i)
+	{
+		init.m_color.m_attachments[i].m_format = 
+			MS_COLOR_ATTACHMENTS_PIXEL_FORMAT[i];
+	}
+	init.m_depthStencil.m_format = MS_DEPTH_STENCIL_ATTACHMENT_FORMAT;
+
+	return ErrorCode::NONE;
+}
+
+} // end namespace anki
+