浏览代码

Some GPU opts for mobile GPUs

Panagiotis Christopoulos Charitos 13 年之前
父节点
当前提交
0ad11959b1

+ 13 - 3
include/anki/gl/GlState.h

@@ -21,6 +21,14 @@ class ShaderProgram;
 class GlStateCommon
 {
 public:
+	/// Knowing the ventor allows some optimizations
+	enum Gpu
+	{
+		GPU_UNKNOWN,
+		GPU_ARM,
+		GPU_NVIDIA
+	};
+
 	U32 getMajorVersion() const
 	{
 		ANKI_ASSERT(major != -1);
@@ -32,15 +40,17 @@ public:
 		return (U32)minor;
 	}
 
-	void init(const U32 major_, const U32 minor_)
+	Gpu getGpu() const
 	{
-		major = (I32)major_;
-		minor = (I32)minor_;
+		return gpu;
 	}
 
+	void init(const U32 major_, const U32 minor_);
+
 private:
 	/// Minor major GL version
 	I32 major = -1, minor = -1;
+	Gpu gpu = GPU_UNKNOWN;
 };
 
 typedef Singleton<GlStateCommon> GlStateCommonSingleton;

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

@@ -281,6 +281,11 @@ public:
 	/// Use the tiler to do visibility tests
 	Bool doVisibilityTests(const CollisionShape& cs) const;
 
+	/// On some GPUs its optimal to clean after binding to an FBO and there is
+	/// no use for it's previous contents. For other GPUs the clear will be 
+	/// skipped
+	void clearAfterBindingFbo(const GLenum cap);
+
 protected:
 	/// @name Rendering stages
 	/// @{

+ 29 - 0
src/gl/GlState.cpp

@@ -4,9 +4,38 @@
 #include "anki/gl/Vao.h"
 #include "anki/util/Assert.h"
 #include <limits>
+#include <algorithm>
 
 namespace anki {
 
+//==============================================================================
+// GlStateCommon                                                               = 
+//==============================================================================
+
+//==============================================================================
+void GlStateCommon::init(const U32 major_, const U32 minor_)
+{
+	major = (I32)major_;
+	minor = (I32)minor_;
+
+	std::string glstr = (const char*)glGetString(GL_VENDOR);
+	glstr += (const char*)glGetString(GL_RENDERER);
+	std::transform(glstr.begin(), glstr.end(), glstr.begin(), ::tolower);
+
+	if(glstr.find("arm") != std::string::npos)
+	{
+		gpu = GPU_ARM;
+	}
+	else if(glstr.find("nvidia") != std::string::npos)
+	{
+		gpu = GPU_NVIDIA;
+	}
+}
+
+//==============================================================================
+// GlState                                                                     = 
+//==============================================================================
+
 //==============================================================================
 static Array<GLenum, 7> glCaps = {{
 	GL_DEPTH_TEST,

+ 3 - 0
src/renderer/Hdr.cpp

@@ -107,6 +107,7 @@ void Hdr::run()
 
 	// pass 0
 	vblurFbo.bind();
+	r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 	toneSProg->bind();
 
 	if(parameterUpdateTimestamp > commonUboUpdateTimestamp)
@@ -124,6 +125,7 @@ void Hdr::run()
 	{
 		// hpass
 		hblurFbo.bind();
+		r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 		hblurSProg->bind();
 		if(i == 0)
 		{
@@ -133,6 +135,7 @@ void Hdr::run()
 
 		// vpass
 		vblurFbo.bind();
+		r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 		vblurSProg->bind();
 		if(i == 0)
 		{

+ 4 - 0
src/renderer/Is.cpp

@@ -476,6 +476,8 @@ void Is::lightPass()
 	{
 		ANKI_ASSERT(!r->getPps().getEnabled());
 		Fbo::bindDefault();
+		r->clearAfterBindingFbo(
+			GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 		GlStateSingleton::get().setViewport(
 			0, 0, width, height);
 	}
@@ -483,6 +485,8 @@ void Is::lightPass()
 	{
 		ANKI_ASSERT(r->getPps().getEnabled());
 		fbo.bind();
+		r->clearAfterBindingFbo(
+			GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 		GlStateSingleton::get().setViewport(
 			0, 0, r->getWidth(), r->getHeight());
 	}

+ 2 - 2
src/renderer/Ms.cpp

@@ -44,8 +44,8 @@ void Ms::init(const RendererInitializer& initializer)
 void Ms::run()
 {
 	fbo.bind();
-
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+	r->clearAfterBindingFbo(
+		GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
 	/*if(ez.getEnabled())
 	{

+ 9 - 0
src/renderer/Renderer.cpp

@@ -197,4 +197,13 @@ Bool Renderer::doVisibilityTests(const CollisionShape& cs) const
 	return tiler.testAll(cs, true);
 }
 
+//==============================================================================
+void Renderer::clearAfterBindingFbo(const GLenum cap)
+{
+	if(GlStateCommonSingleton::get().getGpu() == GlStateCommon::GPU_ARM)
+	{
+		glClear(cap);
+	}
+}
+
 } // end namespace anki

+ 1 - 0
src/renderer/Sm.cpp

@@ -198,6 +198,7 @@ Sm::Shadowmap* Sm::doLight(Light& light)
 	// Render
 	//
 	sm.fbo.bind();
+	r->clearAfterBindingFbo(GL_DEPTH_BUFFER_BIT);
 	glClear(GL_DEPTH_BUFFER_BIT);
 
 	//std::cout << "Shadowmap for: " << &sm << std::endl;

+ 3 - 1
src/renderer/Ssao.cpp

@@ -16,7 +16,6 @@ struct ShaderCommonUniforms
 //==============================================================================
 void Ssao::createFbo(Fbo& fbo, Texture& fai, F32 width, F32 height)
 {
-
 	Renderer::createFai(width, height, GL_RED, GL_RED, GL_FLOAT, fai);
 	fai.setFiltering(Texture::TFT_LINEAR);
 
@@ -144,6 +143,7 @@ void Ssao::run()
 		vblurFbo.bind();
 		GlStateSingleton::get().setViewport(0, 0, bWidth, bHeight);
 	}
+	r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 	ssaoSProg->bind();
 	commonUbo.setBinding(0);
 
@@ -194,6 +194,7 @@ void Ssao::run()
 	{
 		// hpass
 		hblurFbo.bind();
+		r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 		hblurSProg->bind();
 		if(i == 0)
 		{
@@ -203,6 +204,7 @@ void Ssao::run()
 
 		// vpass
 		vblurFbo.bind();
+		r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 		vblurSProg->bind();
 		if(i == 0)
 		{

+ 1 - 0
src/renderer/Tiler.cpp

@@ -201,6 +201,7 @@ void Tiler::updateTiles(Camera& cam, const Texture& depthMap)
 	update4Planes(cam, &jobs4);
 
 	fbo.bind(); // Flush prev FBO to force flush on Mali
+	r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 	GlStateSingleton::get().setViewport(0, 0, TILES_X_COUNT, TILES_Y_COUNT);
 	prog->bind();
 	prog->findUniformVariable("depthMap").set(depthMap);