فهرست منبع

Added discard framebuffer resources after use.

Branimir Karadžić 11 سال پیش
والد
کامیت
bb96d76c0a
10فایلهای تغییر یافته به همراه148 افزوده شده و 49 حذف شده
  1. 5 9
      examples/09-hdr/hdr.cpp
  2. 2 2
      include/bgfx.c99.h
  3. 2 2
      include/bgfx.h
  4. 30 7
      include/bgfxdefines.h
  5. 4 4
      src/bgfx.cpp
  6. 14 8
      src/bgfx_p.h
  7. 3 3
      src/glcontext_glx.cpp
  8. 12 3
      src/glimports.h
  9. 73 9
      src/renderer_gl.cpp
  10. 3 2
      src/renderer_gl.h

+ 5 - 9
examples/09-hdr/hdr.cpp

@@ -8,12 +8,7 @@
 #include "imgui/imgui.h"
 #include "imgui/imgui.h"
 
 
 static float s_texelHalf = 0.0f;
 static float s_texelHalf = 0.0f;
-static bool s_originBottomLeft = false;
-
-inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far)
-{
-	bx::mtxProj(_result, _fovy, _aspect, _near, _far, s_originBottomLeft);
-}
+static bool  s_originBottomLeft = false;
 
 
 struct PosColorTexCoord0Vertex
 struct PosColorTexCoord0Vertex
 {
 {
@@ -232,7 +227,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	uint32_t oldWidth  = 0;
 	uint32_t oldWidth  = 0;
 	uint32_t oldHeight = 0;
 	uint32_t oldHeight = 0;
 	uint32_t oldReset  = reset;
 	uint32_t oldReset  = reset;
- 
+
 	float speed      = 0.37f;
 	float speed      = 0.37f;
 	float middleGray = 0.18f;
 	float middleGray = 0.18f;
 	float white      = 1.1f;
 	float white      = 1.1f;
@@ -318,6 +313,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		}
 		}
 		bgfx::setViewFrameBuffer(0, fbh);
 		bgfx::setViewFrameBuffer(0, fbh);
 		bgfx::setViewFrameBuffer(1, fbh);
 		bgfx::setViewFrameBuffer(1, fbh);
+		bgfx::setViewClear(1, BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL);
 
 
 		bgfx::setViewRect(2, 0, 0, 128, 128);
 		bgfx::setViewRect(2, 0, 0, 128, 128);
 		bgfx::setViewFrameBuffer(2, lum[0]);
 		bgfx::setViewFrameBuffer(2, lum[0]);
@@ -361,7 +357,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		bx::mtxRotateXY(mtx
 		bx::mtxRotateXY(mtx
 			, 0.0f
 			, 0.0f
 			, time
 			, time
-			); 
+			);
 
 
 		float temp[4];
 		float temp[4];
 		bx::vec3MulMtx(temp, eye, mtx);
 		bx::vec3MulMtx(temp, eye, mtx);
@@ -453,7 +449,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		screenSpaceQuad( (float)width, (float)height, s_originBottomLeft);
 		screenSpaceQuad( (float)width, (float)height, s_originBottomLeft);
 		bgfx::submit(9);
 		bgfx::submit(9);
 
 
-		// Advance to next frame. Rendering thread will be kicked to 
+		// Advance to next frame. Rendering thread will be kicked to
 		// process submitted rendering primitives.
 		// process submitted rendering primitives.
 		bgfx::frame();
 		bgfx::frame();
 	}
 	}

+ 2 - 2
include/bgfx.c99.h

@@ -1129,7 +1129,7 @@ BGFX_C_API void bgfx_set_view_scissor(uint8_t _id, uint16_t _x, uint16_t _y, uin
  *  @param _depth Depth clear value.
  *  @param _depth Depth clear value.
  *  @param _stencil Stencil clear value.
  *  @param _stencil Stencil clear value.
  */
  */
-BGFX_C_API void bgfx_set_view_clear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil);
+BGFX_C_API void bgfx_set_view_clear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil);
 
 
 /**
 /**
  *  Set view clear flags with different clear color for each
  *  Set view clear flags with different clear color for each
@@ -1142,7 +1142,7 @@ BGFX_C_API void bgfx_set_view_clear(uint8_t _id, uint8_t _flags, uint32_t _rgba,
  *  @param _depth Depth clear value.
  *  @param _depth Depth clear value.
  *  @param _stencil Stencil clear value.
  *  @param _stencil Stencil clear value.
  */
  */
-BGFX_C_API void bgfx_set_view_clear_mrt(uint8_t _id, uint8_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7);
+BGFX_C_API void bgfx_set_view_clear_mrt(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7);
 
 
 /**
 /**
  *  Set view into sequential mode. Draw calls will be sorted in the same
  *  Set view into sequential mode. Draw calls will be sorted in the same

+ 2 - 2
include/bgfx.h

@@ -1049,7 +1049,7 @@ namespace bgfx
 	/// @param _depth Depth clear value.
 	/// @param _depth Depth clear value.
 	/// @param _stencil Stencil clear value.
 	/// @param _stencil Stencil clear value.
 	///
 	///
-	void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba = 0x000000ff, float _depth = 1.0f, uint8_t _stencil = 0);
+	void setViewClear(uint8_t _id, uint16_t _flags, uint32_t _rgba = 0x000000ff, float _depth = 1.0f, uint8_t _stencil = 0);
 
 
 	/// Set view clear flags with different clear color for each
 	/// Set view clear flags with different clear color for each
 	/// frame buffer texture. Must use setClearColor to setup clear color
 	/// frame buffer texture. Must use setClearColor to setup clear color
@@ -1061,7 +1061,7 @@ namespace bgfx
 	/// @param _depth Depth clear value.
 	/// @param _depth Depth clear value.
 	/// @param _stencil Stencil clear value.
 	/// @param _stencil Stencil clear value.
 	///
 	///
-	void setViewClear(uint8_t _id, uint8_t _flags, float _depth, uint8_t _stencil, uint8_t _0 = UINT8_MAX, uint8_t _1 = UINT8_MAX, uint8_t _2 = UINT8_MAX, uint8_t _3 = UINT8_MAX, uint8_t _4 = UINT8_MAX, uint8_t _5 = UINT8_MAX, uint8_t _6 = UINT8_MAX, uint8_t _7 = UINT8_MAX);
+	void setViewClear(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0 = UINT8_MAX, uint8_t _1 = UINT8_MAX, uint8_t _2 = UINT8_MAX, uint8_t _3 = UINT8_MAX, uint8_t _4 = UINT8_MAX, uint8_t _5 = UINT8_MAX, uint8_t _6 = UINT8_MAX, uint8_t _7 = UINT8_MAX);
 
 
 	/// Set view into sequential mode. Draw calls will be sorted in the same
 	/// Set view into sequential mode. Draw calls will be sorted in the same
 	/// order in which submit calls were called.
 	/// order in which submit calls were called.

+ 30 - 7
include/bgfxdefines.h

@@ -182,13 +182,36 @@
 #define BGFX_STENCIL_FUNC_RMASK(_mask) ( (uint32_t(_mask)<<BGFX_STENCIL_FUNC_RMASK_SHIFT)&BGFX_STENCIL_FUNC_RMASK_MASK)
 #define BGFX_STENCIL_FUNC_RMASK(_mask) ( (uint32_t(_mask)<<BGFX_STENCIL_FUNC_RMASK_SHIFT)&BGFX_STENCIL_FUNC_RMASK_MASK)
 
 
 ///
 ///
-#define BGFX_CLEAR_NONE                  UINT8_C(0x00)
-#define BGFX_CLEAR_COLOR                 UINT8_C(0x01)
-#define BGFX_CLEAR_DEPTH                 UINT8_C(0x02)
-#define BGFX_CLEAR_STENCIL               UINT8_C(0x04)
-#define BGFX_CLEAR_DISCARD_COLOR         UINT8_C(0x08)
-#define BGFX_CLEAR_DISCARD_DEPTH         UINT8_C(0x10)
-#define BGFX_CLEAR_DISCARD_STENCIL       UINT8_C(0x20)
+#define BGFX_CLEAR_NONE                  UINT16_C(0x0000)
+#define BGFX_CLEAR_COLOR                 UINT16_C(0x0001)
+#define BGFX_CLEAR_DEPTH                 UINT16_C(0x0002)
+#define BGFX_CLEAR_STENCIL               UINT16_C(0x0004)
+#define BGFX_CLEAR_DISCARD_COLOR_0       UINT16_C(0x0008)
+#define BGFX_CLEAR_DISCARD_COLOR_1       UINT16_C(0x0010)
+#define BGFX_CLEAR_DISCARD_COLOR_2       UINT16_C(0x0020)
+#define BGFX_CLEAR_DISCARD_COLOR_3       UINT16_C(0x0040)
+#define BGFX_CLEAR_DISCARD_COLOR_4       UINT16_C(0x0080)
+#define BGFX_CLEAR_DISCARD_COLOR_5       UINT16_C(0x0100)
+#define BGFX_CLEAR_DISCARD_COLOR_6       UINT16_C(0x0200)
+#define BGFX_CLEAR_DISCARD_COLOR_7       UINT16_C(0x0400)
+#define BGFX_CLEAR_DISCARD_DEPTH         UINT16_C(0x0800)
+#define BGFX_CLEAR_DISCARD_STENCIL       UINT16_C(0x1000)
+
+#define BGFX_CLEAR_DISCARD_COLOR_MASK (0 \
+			| BGFX_CLEAR_DISCARD_COLOR_0 \
+			| BGFX_CLEAR_DISCARD_COLOR_1 \
+			| BGFX_CLEAR_DISCARD_COLOR_2 \
+			| BGFX_CLEAR_DISCARD_COLOR_3 \
+			| BGFX_CLEAR_DISCARD_COLOR_4 \
+			| BGFX_CLEAR_DISCARD_COLOR_5 \
+			| BGFX_CLEAR_DISCARD_COLOR_6 \
+			| BGFX_CLEAR_DISCARD_COLOR_7 \
+			)
+#define BGFX_CLEAR_DISCARD_MASK (0 \
+			| BGFX_CLEAR_DISCARD_COLOR_MASK \
+			| BGFX_CLEAR_DISCARD_DEPTH \
+			| BGFX_CLEAR_DISCARD_STENCIL \
+			)
 
 
 ///
 ///
 #define BGFX_DEBUG_NONE                  UINT32_C(0x00000000)
 #define BGFX_DEBUG_NONE                  UINT32_C(0x00000000)

+ 4 - 4
src/bgfx.cpp

@@ -2583,14 +2583,14 @@ again:
 		s_ctx->setViewScissor(_id, _x, _y, _width, _height);
 		s_ctx->setViewScissor(_id, _x, _y, _width, _height);
 	}
 	}
 
 
-	void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
+	void setViewClear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
 	{
 	{
 		BGFX_CHECK_MAIN_THREAD();
 		BGFX_CHECK_MAIN_THREAD();
 		BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
 		BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
 		s_ctx->setViewClear(_id, _flags, _rgba, _depth, _stencil);
 		s_ctx->setViewClear(_id, _flags, _rgba, _depth, _stencil);
 	}
 	}
 
 
-	void setViewClear(uint8_t _id, uint8_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
+	void setViewClear(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
 	{
 	{
 		BGFX_CHECK_MAIN_THREAD();
 		BGFX_CHECK_MAIN_THREAD();
 		BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
 		BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
@@ -3270,12 +3270,12 @@ BGFX_C_API void bgfx_set_view_scissor(uint8_t _id, uint16_t _x, uint16_t _y, uin
 	bgfx::setViewScissor(_id, _x, _y, _width, _height);
 	bgfx::setViewScissor(_id, _x, _y, _width, _height);
 }
 }
 
 
-BGFX_C_API void bgfx_set_view_clear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
+BGFX_C_API void bgfx_set_view_clear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
 {
 {
 	bgfx::setViewClear(_id, _flags, _rgba, _depth, _stencil);
 	bgfx::setViewClear(_id, _flags, _rgba, _depth, _stencil);
 }
 }
 
 
-BGFX_C_API void bgfx_set_view_clear_mrt(uint8_t _id, uint8_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
+BGFX_C_API void bgfx_set_view_clear_mrt(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
 {
 {
 	bgfx::setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7);
 	bgfx::setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7);
 }
 }

+ 14 - 8
src/bgfx_p.h

@@ -94,7 +94,13 @@ namespace bgfx
 #define BGFX_CHUNK_MAGIC_TEX BX_MAKEFOURCC('T', 'E', 'X', 0x0)
 #define BGFX_CHUNK_MAGIC_TEX BX_MAKEFOURCC('T', 'E', 'X', 0x0)
 #define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x3)
 #define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x3)
 
 
-#define BGFX_CLEAR_COLOR_USE_PALETTE_BIT UINT8_C(0x80)
+#define BGFX_CLEAR_COLOR_USE_PALETTE UINT16_C(0x8000)
+#define BGFX_CLEAR_MASK (0 \
+			| BGFX_CLEAR_COLOR \
+			| BGFX_CLEAR_DEPTH \
+			| BGFX_CLEAR_STENCIL \
+			| BGFX_CLEAR_COLOR_USE_PALETTE \
+			)
 
 
 #include <list> // mingw wants it to be before tr1/unordered_*...
 #include <list> // mingw wants it to be before tr1/unordered_*...
 
 
@@ -204,10 +210,10 @@ namespace bgfx
 
 
 	struct Clear
 	struct Clear
 	{
 	{
-		uint8_t m_index[8];
-		float   m_depth;
-		uint8_t m_stencil;
-		uint8_t m_flags;
+		uint8_t  m_index[8];
+		float    m_depth;
+		uint8_t  m_stencil;
+		uint16_t m_flags;
 	};
 	};
 
 
 	struct Rect
 	struct Rect
@@ -2852,7 +2858,7 @@ namespace bgfx
 			scissor.m_height = _height;
 			scissor.m_height = _height;
 		}
 		}
 
 
-		BGFX_API_FUNC(void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) )
+		BGFX_API_FUNC(void setViewClear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) )
 		{
 		{
 			Clear& clear = m_clear[_id];
 			Clear& clear = m_clear[_id];
 			clear.m_flags = _flags;
 			clear.m_flags = _flags;
@@ -2864,11 +2870,11 @@ namespace bgfx
 			clear.m_stencil  = _stencil;
 			clear.m_stencil  = _stencil;
 		}
 		}
 
 
-		BGFX_API_FUNC(void setViewClear(uint8_t _id, uint8_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7) )
+		BGFX_API_FUNC(void setViewClear(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7) )
 		{
 		{
 			Clear& clear = m_clear[_id];
 			Clear& clear = m_clear[_id];
 			clear.m_flags = (_flags & ~BGFX_CLEAR_COLOR)
 			clear.m_flags = (_flags & ~BGFX_CLEAR_COLOR)
-				| (0xff != (_0&_1&_2&_3&_4&_5&_6&_7) ? BGFX_CLEAR_COLOR|BGFX_CLEAR_COLOR_USE_PALETTE_BIT : 0)
+				| (0xff != (_0&_1&_2&_3&_4&_5&_6&_7) ? BGFX_CLEAR_COLOR|BGFX_CLEAR_COLOR_USE_PALETTE : 0)
 				;
 				;
 			clear.m_index[0] = _0;
 			clear.m_index[0] = _0;
 			clear.m_index[1] = _1;
 			clear.m_index[1] = _1;

+ 3 - 3
src/glcontext_glx.cpp

@@ -15,9 +15,9 @@ namespace bgfx
 	typedef int (*PFNGLXSWAPINTERVALMESAPROC)(uint32_t _interval);
 	typedef int (*PFNGLXSWAPINTERVALMESAPROC)(uint32_t _interval);
 
 
 	PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
 	PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
-	PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
-	PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA;
-	PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI;
+	PFNGLXSWAPINTERVALEXTPROC         glXSwapIntervalEXT;
+	PFNGLXSWAPINTERVALMESAPROC        glXSwapIntervalMESA;
+	PFNGLXSWAPINTERVALSGIPROC         glXSwapIntervalSGI;
 
 
 #	define GL_IMPORT(_optional, _proto, _func, _import) _proto _func
 #	define GL_IMPORT(_optional, _proto, _func, _import) _proto _func
 #	include "glimports.h"
 #	include "glimports.h"

+ 12 - 3
src/glimports.h

@@ -31,7 +31,7 @@
 #define GL_IMPORT_____x(_optional, _proto, _func) GL_EXTENSION(_optional, _proto, _func, _func ## XXXXX)
 #define GL_IMPORT_____x(_optional, _proto, _func) GL_EXTENSION(_optional, _proto, _func, _func ## XXXXX)
 
 
 #if GL_IMPORT_TYPEDEFS
 #if GL_IMPORT_TYPEDEFS
-typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void           (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
 typedef void           (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
 typedef void           (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
 typedef void           (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
 typedef void           (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
 typedef void           (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
 typedef void           (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
@@ -140,6 +140,7 @@ typedef void           (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader,
 typedef void           (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
 typedef void           (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
 typedef const GLubyte* (GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
 typedef const GLubyte* (GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
 typedef GLint          (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
 typedef GLint          (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void           (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
 typedef void           (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
 typedef void           (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
 typedef void           (GL_APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
 typedef void           (GL_APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
 typedef void           (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
 typedef void           (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
@@ -308,6 +309,7 @@ GL_IMPORT______(false, PFNGLGETSHADERIVPROC,                       glGetShaderiv
 GL_IMPORT______(false, PFNGLGETSHADERINFOLOGPROC,                  glGetShaderInfoLog);
 GL_IMPORT______(false, PFNGLGETSHADERINFOLOGPROC,                  glGetShaderInfoLog);
 GL_IMPORT______(false, PFNGLGETSTRINGPROC,                         glGetString);
 GL_IMPORT______(false, PFNGLGETSTRINGPROC,                         glGetString);
 GL_IMPORT______(false, PFNGLGETUNIFORMLOCATIONPROC,                glGetUniformLocation);
 GL_IMPORT______(false, PFNGLGETUNIFORMLOCATIONPROC,                glGetUniformLocation);
+GL_IMPORT______(true,  PFNGLINVALIDATEFRAMEBUFFERPROC,             glInvalidateFramebuffer);
 GL_IMPORT______(false, PFNGLLINKPROGRAMPROC,                       glLinkProgram);
 GL_IMPORT______(false, PFNGLLINKPROGRAMPROC,                       glLinkProgram);
 GL_IMPORT______(true,  PFNGLMEMORYBARRIERPROC,                     glMemoryBarrier);
 GL_IMPORT______(true,  PFNGLMEMORYBARRIERPROC,                     glMemoryBarrier);
 GL_IMPORT______(true,  PFNGLOBJECTLABELPROC,                       glObjectLabel);
 GL_IMPORT______(true,  PFNGLOBJECTLABELPROC,                       glObjectLabel);
@@ -386,6 +388,8 @@ GL_IMPORT_ARB__(true,  PFNGLDRAWELEMENTSINSTANCEDPROC,             glDrawElement
 
 
 GL_IMPORT_ARB__(true,  PFNGLDRAWBUFFERSPROC,                       glDrawBuffers);
 GL_IMPORT_ARB__(true,  PFNGLDRAWBUFFERSPROC,                       glDrawBuffers);
 
 
+GL_IMPORT_ARB__(true,  PFNGLINVALIDATEFRAMEBUFFERPROC,             glInvalidateFramebuffer);
+
 GL_IMPORT_EXT__(true,  PFNGLBINDFRAMEBUFFERPROC,                   glBindFramebuffer);
 GL_IMPORT_EXT__(true,  PFNGLBINDFRAMEBUFFERPROC,                   glBindFramebuffer);
 GL_IMPORT_EXT__(true,  PFNGLGENFRAMEBUFFERSPROC,                   glGenFramebuffers);
 GL_IMPORT_EXT__(true,  PFNGLGENFRAMEBUFFERSPROC,                   glGenFramebuffers);
 GL_IMPORT_EXT__(true,  PFNGLDELETEFRAMEBUFFERSPROC,                glDeleteFramebuffers);
 GL_IMPORT_EXT__(true,  PFNGLDELETEFRAMEBUFFERSPROC,                glDeleteFramebuffers);
@@ -474,6 +478,9 @@ GL_IMPORT_NV___(true,  PFNGLDELETEQUERIESPROC,                     glDeleteQueri
 GL_IMPORT_NV___(true,  PFNGLBEGINQUERYPROC,                        glBeginQuery);
 GL_IMPORT_NV___(true,  PFNGLBEGINQUERYPROC,                        glBeginQuery);
 GL_IMPORT_NV___(true,  PFNGLENDQUERYPROC,                          glEndQuery);
 GL_IMPORT_NV___(true,  PFNGLENDQUERYPROC,                          glEndQuery);
 GL_IMPORT_NV___(true,  PFNGLGETQUERYOBJECTUI64VPROC,               glGetQueryObjectui64v);
 GL_IMPORT_NV___(true,  PFNGLGETQUERYOBJECTUI64VPROC,               glGetQueryObjectui64v);
+
+GL_IMPORT      (true,  PFNGLINVALIDATEFRAMEBUFFERPROC,             glInvalidateFramebuffer, glDiscardFramebufferEXT);
+
 #else
 #else
 GL_IMPORT______(true,  PFNGLTEXIMAGE3DPROC,                        glTexImage3D);
 GL_IMPORT______(true,  PFNGLTEXIMAGE3DPROC,                        glTexImage3D);
 GL_IMPORT______(true,  PFNGLTEXSUBIMAGE3DPROC,                     glTexSubImage3D);
 GL_IMPORT______(true,  PFNGLTEXSUBIMAGE3DPROC,                     glTexSubImage3D);
@@ -505,7 +512,7 @@ GL_IMPORT______(true,  PFNGLBLENDEQUATIONIPROC,                    glBlendEquati
 GL_IMPORT______(true,  PFNGLBLENDEQUATIONSEPARATEIPROC,            glBlendEquationSeparatei);
 GL_IMPORT______(true,  PFNGLBLENDEQUATIONSEPARATEIPROC,            glBlendEquationSeparatei);
 GL_IMPORT______(true,  PFNGLBLENDFUNCIPROC,                        glBlendFunci);
 GL_IMPORT______(true,  PFNGLBLENDFUNCIPROC,                        glBlendFunci);
 GL_IMPORT______(true,  PFNGLBLENDFUNCSEPARATEIPROC,                glBlendFuncSeparatei);
 GL_IMPORT______(true,  PFNGLBLENDFUNCSEPARATEIPROC,                glBlendFuncSeparatei);
-			  
+
 GL_IMPORT______(true,  PFNGLDRAWBUFFERPROC,                        glDrawBuffer);
 GL_IMPORT______(true,  PFNGLDRAWBUFFERPROC,                        glDrawBuffer);
 GL_IMPORT______(true,  PFNGLREADBUFFERPROC,                        glReadBuffer);
 GL_IMPORT______(true,  PFNGLREADBUFFERPROC,                        glReadBuffer);
 GL_IMPORT______(true,  PFNGLGENSAMPLERSPROC,                       glGenSamplers);
 GL_IMPORT______(true,  PFNGLGENSAMPLERSPROC,                       glGenSamplers);
@@ -513,7 +520,7 @@ GL_IMPORT______(true,  PFNGLDELETESAMPLERSPROC,                    glDeleteSampl
 GL_IMPORT______(true,  PFNGLBINDSAMPLERPROC,                       glBindSampler);
 GL_IMPORT______(true,  PFNGLBINDSAMPLERPROC,                       glBindSampler);
 GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERFPROC,                 glSamplerParameterf);
 GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERFPROC,                 glSamplerParameterf);
 GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERIPROC,                 glSamplerParameteri);
 GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERIPROC,                 glSamplerParameteri);
-			  
+
 GL_IMPORT______(true,  PFNGLBINDBUFFERBASEPROC,                    glBindBufferBase);
 GL_IMPORT______(true,  PFNGLBINDBUFFERBASEPROC,                    glBindBufferBase);
 GL_IMPORT______(true,  PFNGLBINDBUFFERRANGEPROC,                   glBindBufferRange);
 GL_IMPORT______(true,  PFNGLBINDBUFFERRANGEPROC,                   glBindBufferRange);
 GL_IMPORT______(true,  PFNGLBINDIMAGETEXTUREPROC,                  glBindImageTexture);
 GL_IMPORT______(true,  PFNGLBINDIMAGETEXTUREPROC,                  glBindImageTexture);
@@ -534,6 +541,8 @@ GL_IMPORT______(true,  PFNGLBEGINQUERYPROC,                        glBeginQuery)
 GL_IMPORT______(true,  PFNGLENDQUERYPROC,                          glEndQuery);
 GL_IMPORT______(true,  PFNGLENDQUERYPROC,                          glEndQuery);
 GL_IMPORT______(true,  PFNGLGETQUERYOBJECTUI64VPROC,               glGetQueryObjectui64v);
 GL_IMPORT______(true,  PFNGLGETQUERYOBJECTUI64VPROC,               glGetQueryObjectui64v);
 
 
+GL_IMPORT______(true,  PFNGLINVALIDATEFRAMEBUFFERPROC,             glInvalidateFramebuffer);
+
 #	endif // BGFX_CONFIG_RENDERER_OPENGLES < 30
 #	endif // BGFX_CONFIG_RENDERER_OPENGLES < 30
 #endif // !BGFX_CONFIG_RENDERER_OPENGL
 #endif // !BGFX_CONFIG_RENDERER_OPENGL
 
 

+ 73 - 9
src/renderer_gl.cpp

@@ -322,6 +322,7 @@ namespace bgfx
 			ARB_half_float_pixel,
 			ARB_half_float_pixel,
 			ARB_half_float_vertex,
 			ARB_half_float_vertex,
 			ARB_instanced_arrays,
 			ARB_instanced_arrays,
+			ARB_invalidate_subdata,
 			ARB_map_buffer_range,
 			ARB_map_buffer_range,
 			ARB_multisample,
 			ARB_multisample,
 			ARB_occlusion_query,
 			ARB_occlusion_query,
@@ -363,6 +364,7 @@ namespace bgfx
 			EXT_compressed_ETC1_RGB8_sub_texture,
 			EXT_compressed_ETC1_RGB8_sub_texture,
 			EXT_debug_label,
 			EXT_debug_label,
 			EXT_debug_marker,
 			EXT_debug_marker,
+			EXT_discard_framebuffer,
 			EXT_draw_buffers,
 			EXT_draw_buffers,
 			EXT_frag_depth,
 			EXT_frag_depth,
 			EXT_framebuffer_blit,
 			EXT_framebuffer_blit,
@@ -480,6 +482,7 @@ namespace bgfx
 		{ "ARB_half_float_pixel",                  BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "ARB_half_float_pixel",                  BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "ARB_half_float_vertex",                 BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "ARB_half_float_vertex",                 BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "ARB_instanced_arrays",                  BGFX_CONFIG_RENDERER_OPENGL >= 33, true  },
 		{ "ARB_instanced_arrays",                  BGFX_CONFIG_RENDERER_OPENGL >= 33, true  },
+		{ "ARB_invalidate_subdata",                BGFX_CONFIG_RENDERER_OPENGL >= 43, true  },
 		{ "ARB_map_buffer_range",                  BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "ARB_map_buffer_range",                  BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "ARB_multisample",                       false,                             true  },
 		{ "ARB_multisample",                       false,                             true  },
 		{ "ARB_occlusion_query",                   BGFX_CONFIG_RENDERER_OPENGL >= 33, true  },
 		{ "ARB_occlusion_query",                   BGFX_CONFIG_RENDERER_OPENGL >= 33, true  },
@@ -521,6 +524,7 @@ namespace bgfx
 		{ "EXT_compressed_ETC1_RGB8_sub_texture",  false,                             true  }, // GLES2 extension.
 		{ "EXT_compressed_ETC1_RGB8_sub_texture",  false,                             true  }, // GLES2 extension.
 		{ "EXT_debug_label",                       false,                             true  },
 		{ "EXT_debug_label",                       false,                             true  },
 		{ "EXT_debug_marker",                      false,                             true  },
 		{ "EXT_debug_marker",                      false,                             true  },
+		{ "EXT_discard_framebuffer",               false,                             true  }, // GLES2 extension.
 		{ "EXT_draw_buffers",                      false,                             true  }, // GLES2 extension.
 		{ "EXT_draw_buffers",                      false,                             true  }, // GLES2 extension.
 		{ "EXT_frag_depth",                        false,                             true  }, // GLES2 extension.
 		{ "EXT_frag_depth",                        false,                             true  }, // GLES2 extension.
 		{ "EXT_framebuffer_blit",                  BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
 		{ "EXT_framebuffer_blit",                  BGFX_CONFIG_RENDERER_OPENGL >= 30, true  },
@@ -691,6 +695,10 @@ namespace bgfx
 	{
 	{
 	}
 	}
 
 
+	static void GL_APIENTRY stubInvalidateFramebuffer(GLenum /*_target*/, GLsizei /*_numAttachments*/, const GLenum* /*_attachments*/)
+	{
+	}
+
 	typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
 	typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
 
 
 	static const char* getGLString(GLenum _name)
 	static const char* getGLString(GLenum _name)
@@ -843,6 +851,7 @@ namespace bgfx
 		RendererContextGL()
 		RendererContextGL()
 			: m_numWindows(1)
 			: m_numWindows(1)
 			, m_rtMsaa(false)
 			, m_rtMsaa(false)
+			, m_fbDiscard(BGFX_CLEAR_NONE)
 			, m_capture(NULL)
 			, m_capture(NULL)
 			, m_captureSize(0)
 			, m_captureSize(0)
 			, m_maxAnisotropy(0.0f)
 			, m_maxAnisotropy(0.0f)
@@ -1364,6 +1373,11 @@ namespace bgfx
 				glObjectLabel = stubObjectLabel;
 				glObjectLabel = stubObjectLabel;
 			}
 			}
 
 
+			if (NULL == glInvalidateFramebuffer)
+			{
+				glInvalidateFramebuffer = stubInvalidateFramebuffer;
+			}
+
 			if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
 			if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
 			{
 			{
 				m_queries.create();
 				m_queries.create();
@@ -1756,14 +1770,24 @@ namespace bgfx
 				) );
 				) );
 		}
 		}
 
 
-		uint32_t setFrameBuffer(FrameBufferHandle _fbh, uint32_t _height, bool _msaa = true)
+		uint32_t setFrameBuffer(FrameBufferHandle _fbh, uint32_t _height, uint8_t _discard = BGFX_CLEAR_NONE, bool _msaa = true)
 		{
 		{
 			if (isValid(m_fbh)
 			if (isValid(m_fbh)
 			&&  m_fbh.idx != _fbh.idx
 			&&  m_fbh.idx != _fbh.idx
-			&&  m_rtMsaa)
+			&& (BGFX_CLEAR_NONE != m_fbDiscard || m_rtMsaa) )
 			{
 			{
 				FrameBufferGL& frameBuffer = m_frameBuffers[m_fbh.idx];
 				FrameBufferGL& frameBuffer = m_frameBuffers[m_fbh.idx];
-				frameBuffer.resolve();
+				if (m_rtMsaa)
+				{
+					frameBuffer.resolve();
+				}
+
+				if (BGFX_CLEAR_NONE != m_fbDiscard)
+				{
+					frameBuffer.discard(m_fbDiscard);
+				}
+
+				m_fbDiscard = BGFX_CLEAR_NONE;
 			}
 			}
 
 
 			m_glctx.makeCurrent(NULL);
 			m_glctx.makeCurrent(NULL);
@@ -1788,8 +1812,9 @@ namespace bgfx
 				}
 				}
 			}
 			}
 
 
-			m_fbh = _fbh;
-			m_rtMsaa = _msaa;
+			m_fbh       = _fbh;
+			m_fbDiscard = _discard;
+			m_rtMsaa    = _msaa;
 
 
 			return _height;
 			return _height;
 		}
 		}
@@ -2258,7 +2283,7 @@ namespace bgfx
 				GLuint flags = 0;
 				GLuint flags = 0;
 				if (BGFX_CLEAR_COLOR & _clear.m_flags)
 				if (BGFX_CLEAR_COLOR & _clear.m_flags)
 				{
 				{
-					if (BGFX_CLEAR_COLOR_USE_PALETTE_BIT & _clear.m_flags)
+					if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
 					{
 					{
 						uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, _clear.m_index[0]);
 						uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, _clear.m_index[0]);
 						const float* rgba = _palette[index];
 						const float* rgba = _palette[index];
@@ -2380,7 +2405,7 @@ namespace bgfx
 				GL_CHECK(glUseProgram(program.m_id) );
 				GL_CHECK(glUseProgram(program.m_id) );
 				program.bindAttributes(vertexDecl, 0);
 				program.bindAttributes(vertexDecl, 0);
 
 
-				if (BGFX_CLEAR_COLOR_USE_PALETTE_BIT & _clear.m_flags)
+				if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
 				{
 				{
 					float mrtClear[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4];
 					float mrtClear[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4];
 					for (uint32_t ii = 0; ii < numMrt; ++ii)
 					for (uint32_t ii = 0; ii < numMrt; ++ii)
@@ -2433,6 +2458,7 @@ namespace bgfx
 		bool m_rtMsaa;
 		bool m_rtMsaa;
 
 
 		FrameBufferHandle m_fbh;
 		FrameBufferHandle m_fbh;
+		uint32_t m_fbDiscard;
 
 
 		Resolution m_resolution;
 		Resolution m_resolution;
 		void* m_capture;
 		void* m_capture;
@@ -4100,6 +4126,42 @@ namespace bgfx
 		}
 		}
 	}
 	}
 
 
+	void FrameBufferGL::discard(uint8_t _flags)
+	{
+		GLenum buffers[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS+2];
+		uint32_t idx = 0;
+
+		if (BGFX_CLEAR_NONE != (_flags & BGFX_CLEAR_DISCARD_COLOR_MASK) )
+		{
+			for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
+			{
+				if (BGFX_CLEAR_NONE != (_flags & (BGFX_CLEAR_DISCARD_COLOR_0<<ii) ) )
+				{
+					buffers[idx++] = GL_COLOR_ATTACHMENT0 + ii;
+				}
+			}
+		}
+
+		uint32_t dsFlags = _flags & (BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL);
+		if (BGFX_CLEAR_NONE != dsFlags)
+		{
+			if ( (BGFX_CLEAR_DISCARD_DEPTH|BGFX_CLEAR_DISCARD_STENCIL) == dsFlags)
+			{
+				buffers[idx++] = GL_DEPTH_STENCIL_ATTACHMENT;
+			}
+			else if (BGFX_CLEAR_DISCARD_DEPTH == dsFlags)
+			{
+				buffers[idx++] = GL_DEPTH_ATTACHMENT;
+			}
+			else if (BGFX_CLEAR_DISCARD_STENCIL == dsFlags)
+			{
+				buffers[idx++] = GL_STENCIL_ATTACHMENT;
+			}
+		}
+
+		GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, idx, buffers) );
+	}
+
 	void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
 	void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
 	{
 	{
 		if (1 < m_numWindows
 		if (1 < m_numWindows
@@ -4182,6 +4244,7 @@ namespace bgfx
 		bool viewHasScissor = false;
 		bool viewHasScissor = false;
 		Rect viewScissorRect;
 		Rect viewScissorRect;
 		viewScissorRect.clear();
 		viewScissorRect.clear();
+		uint8_t discardFlags = BGFX_CLEAR_NONE;
 
 
 		const bool blendIndependentSupported = s_extension[Extension::ARB_draw_buffers_blend].m_supported;
 		const bool blendIndependentSupported = s_extension[Extension::ARB_draw_buffers_blend].m_supported;
 		const bool computeSupported = (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) && s_extension[Extension::ARB_compute_shader].m_supported)
 		const bool computeSupported = (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) && s_extension[Extension::ARB_compute_shader].m_supported)
@@ -4235,7 +4298,7 @@ namespace bgfx
 							? _render->m_hmd.height
 							? _render->m_hmd.height
 							: _render->m_resolution.m_height
 							: _render->m_resolution.m_height
 							;
 							;
-						height = setFrameBuffer(fbh, height);
+						height = setFrameBuffer(fbh, height, discardFlags);
 					}
 					}
 
 
 					viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
 					viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
@@ -4284,8 +4347,9 @@ namespace bgfx
 						) );
 						) );
 
 
 					Clear& clear = _render->m_clear[view];
 					Clear& clear = _render->m_clear[view];
+					discardFlags = clear.m_flags & BGFX_CLEAR_DISCARD_MASK;
 
 
-					if (BGFX_CLEAR_NONE != clear.m_flags)
+					if (BGFX_CLEAR_NONE != (clear.m_flags & BGFX_CLEAR_MASK) )
 					{
 					{
 						clearQuad(_clearQuad, viewState.m_rect, clear, height, _render->m_clearColor);
 						clearQuad(_clearQuad, viewState.m_rect, clear, height, _render->m_clearColor);
 					}
 					}

+ 3 - 2
src/renderer_gl.h

@@ -519,8 +519,8 @@ typedef uint64_t GLuint64;
 #	define glClearDepth glClearDepthf
 #	define glClearDepth glClearDepthf
 #endif // !BGFX_CONFIG_RENDERER_OPENGL
 #endif // !BGFX_CONFIG_RENDERER_OPENGL
 
 
-namespace bgfx 
-{ 
+namespace bgfx
+{
 	class ConstantBuffer;
 	class ConstantBuffer;
 	void dumpExtensions(const char* _extensions);
 	void dumpExtensions(const char* _extensions);
 
 
@@ -835,6 +835,7 @@ namespace bgfx
 		void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
 		void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
 		uint16_t destroy();
 		uint16_t destroy();
 		void resolve();
 		void resolve();
+		void discard(uint8_t _flags);
 
 
 		SwapChainGL* m_swapChain;
 		SwapChainGL* m_swapChain;
 		GLuint m_fbo[2];
 		GLuint m_fbo[2];