Ver Fonte

Added support for blend separate and blend MRT independent.

Branimir Karadžić há 11 anos atrás
pai
commit
d3753d69bf

+ 0 - 1
README.md

@@ -393,7 +393,6 @@ Converts Wavefront .obj mesh file to format optimal for using with bgfx.
 Todo
 ----
 
- - BlendFuncSeparate and BlendEquationSeparate.
  - Blit between textures.
  - Occlusion queries.
  - Fullscreen mode.

+ 65 - 33
include/bgfx.h

@@ -10,10 +10,9 @@
 #include <stdlib.h> // size_t
 
 ///
-#define BGFX_STATE_DEPTH_WRITE           UINT64_C(0x0000000000000001)
-
-#define BGFX_STATE_ALPHA_WRITE           UINT64_C(0x0000000000000008)
-#define BGFX_STATE_ALPHA_MASK            UINT64_C(0x000000000000000c)
+#define BGFX_STATE_RGB_WRITE             UINT64_C(0x0000000000000001)
+#define BGFX_STATE_ALPHA_WRITE           UINT64_C(0x0000000000000002)
+#define BGFX_STATE_DEPTH_WRITE           UINT64_C(0x0000000000000004)
 
 #define BGFX_STATE_DEPTH_TEST_LESS       UINT64_C(0x0000000000000010)
 #define BGFX_STATE_DEPTH_TEST_LEQUAL     UINT64_C(0x0000000000000020)
@@ -40,36 +39,36 @@
 #define BGFX_STATE_BLEND_FACTOR          UINT64_C(0x000000000000c000)
 #define BGFX_STATE_BLEND_INV_FACTOR      UINT64_C(0x000000000000d000)
 #define BGFX_STATE_BLEND_SHIFT           12
-#define BGFX_STATE_BLEND_MASK            UINT64_C(0x00000000000ff000)
+#define BGFX_STATE_BLEND_MASK            UINT64_C(0x000000000ffff000)
 
-#define BGFX_STATE_BLEND_EQUATION_SUB    UINT64_C(0x0000000000100000)
-#define BGFX_STATE_BLEND_EQUATION_REVSUB UINT64_C(0x0000000000200000)
-#define BGFX_STATE_BLEND_EQUATION_MIN    UINT64_C(0x0000000000300000)
-#define BGFX_STATE_BLEND_EQUATION_MAX    UINT64_C(0x0000000000400000)
-#define BGFX_STATE_BLEND_EQUATION_SHIFT  20
-#define BGFX_STATE_BLEND_EQUATION_MASK   UINT64_C(0x0000000000700000)
+#define BGFX_STATE_BLEND_EQUATION_SUB    UINT64_C(0x0000000010000000)
+#define BGFX_STATE_BLEND_EQUATION_REVSUB UINT64_C(0x0000000020000000)
+#define BGFX_STATE_BLEND_EQUATION_MIN    UINT64_C(0x0000000030000000)
+#define BGFX_STATE_BLEND_EQUATION_MAX    UINT64_C(0x0000000040000000)
+#define BGFX_STATE_BLEND_EQUATION_SHIFT  28
+#define BGFX_STATE_BLEND_EQUATION_MASK   UINT64_C(0x00000003f0000000)
 
-#define BGFX_STATE_CULL_CW               UINT64_C(0x0000000010000000)
-#define BGFX_STATE_CULL_CCW              UINT64_C(0x0000000020000000)
-#define BGFX_STATE_CULL_SHIFT            28
-#define BGFX_STATE_CULL_MASK             UINT64_C(0x0000000030000000)
+#define BGFX_STATE_BLEND_INDEPENDENT     UINT64_C(0x0000000400000000)
 
-#define BGFX_STATE_RGB_WRITE             UINT64_C(0x0000000040000000)
+#define BGFX_STATE_CULL_CW               UINT64_C(0x0000001000000000)
+#define BGFX_STATE_CULL_CCW              UINT64_C(0x0000002000000000)
+#define BGFX_STATE_CULL_SHIFT            36
+#define BGFX_STATE_CULL_MASK             UINT64_C(0x0000003000000000)
 
-#define BGFX_STATE_ALPHA_REF_SHIFT       32
-#define BGFX_STATE_ALPHA_REF_MASK        UINT64_C(0x000000ff00000000)
+#define BGFX_STATE_ALPHA_REF_SHIFT       40
+#define BGFX_STATE_ALPHA_REF_MASK        UINT64_C(0x0000ff0000000000)
 
-#define BGFX_STATE_PT_LINES              UINT64_C(0x0000010000000000)
-#define BGFX_STATE_PT_POINTS             UINT64_C(0x0000020000000000)
-#define BGFX_STATE_PT_SHIFT              40
-#define BGFX_STATE_PT_MASK               UINT64_C(0x0000030000000000)
+#define BGFX_STATE_PT_LINES              UINT64_C(0x0001000000000000)
+#define BGFX_STATE_PT_POINTS             UINT64_C(0x0002000000000000)
+#define BGFX_STATE_PT_SHIFT              48
+#define BGFX_STATE_PT_MASK               UINT64_C(0x0003000000000000)
 
-#define BGFX_STATE_POINT_SIZE_SHIFT      44
-#define BGFX_STATE_POINT_SIZE_MASK       UINT64_C(0x000ff00000000000)
+#define BGFX_STATE_POINT_SIZE_SHIFT      52
+#define BGFX_STATE_POINT_SIZE_MASK       UINT64_C(0x0ff0000000000000)
 
-#define BGFX_STATE_MSAA                  UINT64_C(0x0020000000000000)
+#define BGFX_STATE_MSAA                  UINT64_C(0x1000000000000000)
 
-#define BGFX_STATE_RESERVED_MASK         UINT64_C(0xff00000000000000)
+#define BGFX_STATE_RESERVED_MASK         UINT64_C(0xe000000000000000)
 
 #define BGFX_STATE_NONE                  UINT64_C(0x0000000000000000)
 #define BGFX_STATE_MASK                  UINT64_C(0xffffffffffffffff)
@@ -84,16 +83,46 @@
 
 #define BGFX_STATE_ALPHA_REF(_ref) ( (uint64_t(_ref)<<BGFX_STATE_ALPHA_REF_SHIFT)&BGFX_STATE_ALPHA_REF_MASK)
 #define BGFX_STATE_POINT_SIZE(_size) ( (uint64_t(_size)<<BGFX_STATE_POINT_SIZE_SHIFT)&BGFX_STATE_POINT_SIZE_MASK)
-#define BGFX_STATE_BLEND_FUNC(_src, _dst) ( uint64_t(_src)|( uint64_t(_dst)<<4) )
+
+///
+#define BGFX_STATE_BLEND_FUNC_SEPARATE(_srcRGB, _dstRGB, _srcA, _dstA) (0 \
+					| ( (uint64_t(_srcRGB)|(uint64_t(_dstRGB)<<4) )   ) \
+					| ( (uint64_t(_srcA  )|(uint64_t(_dstA  )<<4) )<<8) \
+					)
+
+#define BGFX_STATE_BLEND_EQUATION_SEPARATE(_rgb, _a) (uint64_t(_rgb)|(uint64_t(_a)<<3) )
+
+///
+#define BGFX_STATE_BLEND_FUNC(_src, _dst)    BGFX_STATE_BLEND_FUNC_SEPARATE(_src, _dst, _src, _dst)
+#define BGFX_STATE_BLEND_EQUATION(_equation) BGFX_STATE_BLEND_EQUATION_SEPARATE(_equation, _equation)
 
 #define BGFX_STATE_BLEND_ADD         (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_ONE          ) )
-#define BGFX_STATE_BLEND_ALPHA       (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_COLOR) )
-#define BGFX_STATE_BLEND_DARKEN      (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_ONE          ) | BGFX_STATE_BLEND_EQUATION_MIN)
-#define BGFX_STATE_BLEND_LIGHTEN     (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_ONE          ) | BGFX_STATE_BLEND_EQUATION_MAX)
+#define BGFX_STATE_BLEND_ALPHA       (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) )
+#define BGFX_STATE_BLEND_DARKEN      (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_ONE          ) | BGFX_STATE_BLEND_EQUATION(BGFX_STATE_BLEND_EQUATION_MIN) )
+#define BGFX_STATE_BLEND_LIGHTEN     (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_ONE          ) | BGFX_STATE_BLEND_EQUATION(BGFX_STATE_BLEND_EQUATION_MAX) )
 #define BGFX_STATE_BLEND_MULTIPLY    (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO         ) )
 #define BGFX_STATE_BLEND_NORMAL      (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_INV_SRC_ALPHA) )
 #define BGFX_STATE_BLEND_SCREEN      (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE,       BGFX_STATE_BLEND_INV_SRC_COLOR) )
-#define BGFX_STATE_BLEND_LINEAR_BURN (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_INV_DST_COLOR) | BGFX_STATE_BLEND_EQUATION_SUB)
+#define BGFX_STATE_BLEND_LINEAR_BURN (BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_INV_DST_COLOR) | BGFX_STATE_BLEND_EQUATION(BGFX_STATE_BLEND_EQUATION_SUB) )
+
+///
+#define BGFX_STATE_BLEND_FUNC_RT_x(_src, _dst) (0 \
+					| ( uint32_t( (_src)>>BGFX_STATE_BLEND_SHIFT) \
+					| ( uint32_t( (_dst)>>BGFX_STATE_BLEND_SHIFT)<<4) ) \
+					)
+
+#define BGFX_STATE_BLEND_FUNC_RT_xE(_src, _dst, _equation) (0 \
+					| BGFX_STATE_BLEND_FUNC_RT_x(_src, _dst) \
+					| ( uint32_t( (_equation)>>BGFX_STATE_BLEND_EQUATION_SHIFT)<<8) \
+					)
+
+#define BGFX_STATE_BLEND_FUNC_RT_1(_src, _dst)  (BGFX_STATE_BLEND_FUNC_RT_x(_src, _dst)<< 0)
+#define BGFX_STATE_BLEND_FUNC_RT_2(_src, _dst)  (BGFX_STATE_BLEND_FUNC_RT_x(_src, _dst)<<11)
+#define BGFX_STATE_BLEND_FUNC_RT_3(_src, _dst)  (BGFX_STATE_BLEND_FUNC_RT_x(_src, _dst)<<22)
+
+#define BGFX_STATE_BLEND_FUNC_RT_1E(_src, _dst, _equation) (BGFX_STATE_BLEND_FUNC_RT_xE(_src, _dst, _equation)<< 0)
+#define BGFX_STATE_BLEND_FUNC_RT_2E(_src, _dst, _equation) (BGFX_STATE_BLEND_FUNC_RT_xE(_src, _dst, _equation)<<11)
+#define BGFX_STATE_BLEND_FUNC_RT_3E(_src, _dst, _equation) (BGFX_STATE_BLEND_FUNC_RT_xE(_src, _dst, _equation)<<22)
 
 ///
 #define BGFX_STENCIL_FUNC_REF_SHIFT      0
@@ -257,6 +286,7 @@
 #define BGFX_CAPS_INSTANCING             UINT64_C(0x0000000010000000)
 #define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000020000000)
 #define BGFX_CAPS_FRAGMENT_DEPTH         UINT64_C(0x0000000040000000)
+#define BGFX_CAPS_BLEND_INDEPENDENT      UINT64_C(0x0000000080000000)
 
 #define BGFX_CAPS_TEXTURE_DEPTH_MASK (0 \
 			| BGFX_CAPS_TEXTURE_FORMAT_D16 \
@@ -368,7 +398,9 @@ namespace bgfx
 
 			Unknown, // compressed formats above
 
-			L8,
+			R8,
+			R16,
+			R16F,
 			BGRA8,
 			RGBA16,
 			RGBA16F,
@@ -1154,7 +1186,7 @@ namespace bgfx
 	///   2. BGFX_STATE_BLEND_EQUATION_ADD is set when no other blend
 	///      equation is specified.
 	///
-	void setState(uint64_t _state, uint32_t _rgba = UINT32_MAX);
+	void setState(uint64_t _state, uint32_t _rgba = 0);
 
 	/// Set stencil test state.
 	///

+ 26 - 13
src/bgfx.cpp

@@ -307,7 +307,7 @@ namespace bgfx
 		uint8_t* rgba = mem->data;
 		charsetFillTexture(vga8x8, rgba, 8, pitch, bpp);
 		charsetFillTexture(vga8x16, &rgba[8*pitch], 16, pitch, bpp);
-		m_texture = createTexture2D(width, height, 1, TextureFormat::L8
+		m_texture = createTexture2D(width, height, 1, TextureFormat::R8
 						, BGFX_TEXTURE_MIN_POINT
 						| BGFX_TEXTURE_MAG_POINT
 						| BGFX_TEXTURE_MIP_POINT
@@ -472,29 +472,39 @@ namespace bgfx
 		m_decl.add(Attrib::Color0, 4, AttribType::Uint8, true);
 		m_decl.end();
 
-		const Memory* mem;
-
+		VertexShaderHandle vsh = createVertexShader(
 #	if BGFX_CONFIG_RENDERER_DIRECT3D11
-		mem = makeRef(vs_clear_dx11, sizeof(vs_clear_dx11) );
+			makeRef(vs_clear_dx11, sizeof(vs_clear_dx11) )
 #	elif BGFX_CONFIG_RENDERER_OPENGL
-		mem = makeRef(vs_clear_glsl, sizeof(vs_clear_glsl) );
+			makeRef(vs_clear_glsl, sizeof(vs_clear_glsl) )
 #	endif // BGFX_CONFIG_RENDERER_*
-		VertexShaderHandle vsh = createVertexShader(mem);
+			);
 
+		const Memory* fragMem[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
 #	if BGFX_CONFIG_RENDERER_DIRECT3D11
-		mem = makeRef(fs_clear_dx11, sizeof(fs_clear_dx11) );
+		fragMem[0] = makeRef(fs_clear0_dx11, sizeof(fs_clear0_dx11) );
+		fragMem[1] = makeRef(fs_clear1_dx11, sizeof(fs_clear1_dx11) );
+		fragMem[2] = makeRef(fs_clear2_dx11, sizeof(fs_clear2_dx11) );
+		fragMem[3] = makeRef(fs_clear3_dx11, sizeof(fs_clear3_dx11) );
 #	elif BGFX_CONFIG_RENDERER_OPENGL
-		mem = makeRef(fs_clear_glsl, sizeof(fs_clear_glsl) );
+		fragMem[0] = makeRef(fs_clear0_glsl, sizeof(fs_clear0_glsl) );
+		fragMem[1] = makeRef(fs_clear1_glsl, sizeof(fs_clear1_glsl) );
+		fragMem[2] = makeRef(fs_clear2_glsl, sizeof(fs_clear2_glsl) );
+		fragMem[3] = makeRef(fs_clear3_glsl, sizeof(fs_clear3_glsl) );
 #	endif // BGFX_CONFIG_RENDERER_*
-		FragmentShaderHandle fsh = createFragmentShader(mem);
 
-		m_program = createProgram(vsh, fsh);
+		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii)
+		{
+			FragmentShaderHandle fsh = createFragmentShader(fragMem[ii]);
+			m_program[ii] = createProgram(vsh, fsh);
+			destroyFragmentShader(fsh);
+		}
+
 		destroyVertexShader(vsh);
-		destroyFragmentShader(fsh);
 
 		m_vb = s_ctx->createTransientVertexBuffer(4*m_decl.m_stride, &m_decl);
 
-		mem = alloc(6*sizeof(uint16_t) );
+		const Memory* mem = alloc(6*sizeof(uint16_t) );
 		uint16_t* indices = (uint16_t*)mem->data;
 		indices[0] = 0;
 		indices[1] = 1;
@@ -511,7 +521,10 @@ namespace bgfx
 		BGFX_CHECK_MAIN_THREAD();
 
 #if BGFX_CONFIG_CLEAR_QUAD
-		destroyProgram(m_program);
+		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii)
+		{
+			destroyProgram(m_program[ii]);
+		}
 		destroyIndexBuffer(m_ib);
 		s_ctx->destroyTransientVertexBuffer(m_vb);
 #endif // BGFX_CONFIG_CLEAR_QUAD

+ 2 - 2
src/bgfx_p.h

@@ -457,7 +457,7 @@ namespace bgfx
 		TransientVertexBuffer* m_vb;
 		IndexBufferHandle m_ib;
 		VertexDecl m_decl;
-		ProgramHandle m_program;
+		ProgramHandle m_program[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
 	};
 
 	struct PredefinedUniform
@@ -926,7 +926,7 @@ namespace bgfx
 			m_constBegin = m_constEnd;
 			m_flags = BGFX_STATE_DEFAULT;
 			m_stencil = packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT);
-			m_rgba = UINT32_MAX;
+			m_rgba = 0;
 			m_matrix = 0;
 			m_startIndex = 0;
 			m_numIndices = UINT32_MAX;

+ 4 - 1
src/charset.h

@@ -527,4 +527,7 @@ static const uint8_t vga8x16[256*16] =
 #include "fs_debugfont.bin.h"
 
 #include "vs_clear.bin.h"
-#include "fs_clear.bin.h"
+#include "fs_clear0.bin.h"
+#include "fs_clear1.bin.h"
+#include "fs_clear2.bin.h"
+#include "fs_clear3.bin.h"

+ 3 - 3
src/fs_clear.bin.h → src/fs_clear0.bin.h

@@ -1,4 +1,4 @@
-static const uint8_t fs_clear_glsl[77] =
+static const uint8_t fs_clear0_glsl[77] =
 {
 	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, // FSH....Ivarying 
 	0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x76, // vec4 v_color0;.v
@@ -6,7 +6,7 @@ static const uint8_t fs_clear_glsl[77] =
 	0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, // gl_FragColor = v
 	0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                   // _color0;.}...
 };
-static const uint8_t fs_clear_dx9[137] =
+static const uint8_t fs_clear0_dx9[137] =
 {
 	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, // FSH....I..|.....
 	0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, // ....CTAB....#...
@@ -18,7 +18,7 @@ static const uint8_t fs_clear_dx9[137] =
 	0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80, // ................
 	0x00, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00, 0x00,                                           // .........
 };
-static const uint8_t fs_clear_dx11[494] =
+static const uint8_t fs_clear0_dx11[494] =
 {
 	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, // FSH....I........
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x01, 0x44, 0x58, 0x42, // .............DXB

+ 0 - 0
src/fs_clear.sc → src/fs_clear0.sc


+ 61 - 0
src/fs_clear1.bin.h

@@ -0,0 +1,61 @@
+static const uint8_t fs_clear1_glsl[108] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, // FSH....Ivarying 
+	0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x76, // vec4 v_color0;.v
+	0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, // oid main ().{.  
+	0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x30, 0x5d, 0x20, 0x3d, // gl_FragData[0] =
+	0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, //  v_color0;.  gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x5f, // FragData[1] = v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                         // color0;.}...
+};
+static const uint8_t fs_clear1_dx9[149] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x88, 0x00, 0x00, 0x03, 0xff, 0xff, // FSH....I........
+	0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, // ....CTAB....#...
+	0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, // ................
+	0x1c, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, // ....ps_3_0.Micro
+	0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, // soft (R) HLSL Sh
+	0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, // ader Compiler 9.
+	0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, // 29.952.3111.....
+	0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80, // ................
+	0x00, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x01, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, // ................
+	0xff, 0xff, 0x00, 0x00, 0x00,                                                                   // .....
+};
+static const uint8_t fs_clear1_dx11[550] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, // FSH....I........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x44, 0x58, 0x42, // .............DXB
+	0x43, 0x07, 0x29, 0x65, 0xce, 0x1c, 0xcc, 0xcb, 0x0a, 0x31, 0xfd, 0xe4, 0xfc, 0xc8, 0x95, 0x4a, // C.)e.....1.....J
+	0x88, 0x01, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, // .............4..
+	0x00, 0x8c, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x8c, 0x01, 0x00, // .........,......
+	0x00, 0x52, 0x44, 0x45, 0x46, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .RDEFP..........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x91, 0x00, // ................
+	0x00, 0x1c, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, // .....Microsoft (
+	0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, // R) HLSL Shader C
+	0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, // ompiler 9.29.952
+	0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, // .3111....ISGNL..
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........8......
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, // ................
+	0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .D..............
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, // .........SV_POSI
+	0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, // TION.COLOR...OSG
+	0x4e, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, // ND...........8..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x0f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....8..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, // .............SV_
+	0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x58, 0x00, 0x00, // TARGET...SHDRX..
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, // [email protected]......
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // .....e.... .....
+	0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, // .e.... ......6..
+	0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, // .. ......F......
+	0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, // .6.... ......F..
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, // .....>...STATt..
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                                             // ......
+};

+ 14 - 0
src/fs_clear1.sc

@@ -0,0 +1,14 @@
+$input v_color0
+
+/*
+ * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_shader.sh"
+
+void main()
+{
+	gl_FragData[0] = v_color0;
+	gl_FragData[1] = v_color0;
+}

+ 67 - 0
src/fs_clear2.bin.h

@@ -0,0 +1,67 @@
+static const uint8_t fs_clear2_glsl[137] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, // FSH....Ivarying 
+	0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x76, // vec4 v_color0;.v
+	0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, // oid main ().{.  
+	0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x30, 0x5d, 0x20, 0x3d, // gl_FragData[0] =
+	0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, //  v_color0;.  gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x5f, // FragData[1] = v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, // color0;.  gl_Fra
+	0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, // gData[2] = v_col
+	0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                           // or0;.}...
+};
+static const uint8_t fs_clear2_dx9[161] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x94, 0x00, 0x00, 0x03, 0xff, 0xff, // FSH....I........
+	0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, // ....CTAB....#...
+	0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, // ................
+	0x1c, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, // ....ps_3_0.Micro
+	0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, // soft (R) HLSL Sh
+	0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, // ader Compiler 9.
+	0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, // 29.952.3111.....
+	0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80, // ................
+	0x00, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x01, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, // ................
+	0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00, // ................
+	0x00,                                                                                           // .
+};
+static const uint8_t fs_clear2_dx11[606] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, // FSH....I........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x44, 0x58, 0x42, // [email protected]
+	0x43, 0xdf, 0xef, 0x73, 0x33, 0x5f, 0x1a, 0xe9, 0x7a, 0xc5, 0xf8, 0x6b, 0x15, 0x61, 0x87, 0xb5, // C..s3_..z..k.a..
+	0x29, 0x01, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, // )[email protected]..
+	0x00, 0x8c, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0xc4, 0x01, 0x00, // .........D......
+	0x00, 0x52, 0x44, 0x45, 0x46, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .RDEFP..........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x91, 0x00, // ................
+	0x00, 0x1c, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, // .....Microsoft (
+	0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, // R) HLSL Shader C
+	0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, // ompiler 9.29.952
+	0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, // .3111....ISGNL..
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........8......
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, // ................
+	0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .D..............
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, // .........SV_POSI
+	0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, // TION.COLOR...OSG
+	0x4e, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, // N............P..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....P..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, // .............P..
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, // ................
+	0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, // .....SV_TARGET..
+	0xab, 0x53, 0x48, 0x44, 0x52, 0x78, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, // .SHDRx...@......
+	0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, // .b...........e..
+	0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, // .. ......e.... .
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, // .....e.... .....
+	0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, // .6.... ......F..
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, // .....6.... .....
+	0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, // .F.......6.... .
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, // .....F.......>..
+	0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .STATt..........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // ..............
+};

+ 15 - 0
src/fs_clear2.sc

@@ -0,0 +1,15 @@
+$input v_color0
+
+/*
+ * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_shader.sh"
+
+void main()
+{
+	gl_FragData[0] = v_color0;
+	gl_FragData[1] = v_color0;
+	gl_FragData[2] = v_color0;
+}

+ 73 - 0
src/fs_clear3.bin.h

@@ -0,0 +1,73 @@
+static const uint8_t fs_clear3_glsl[166] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, // FSH....Ivarying 
+	0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x76, // vec4 v_color0;.v
+	0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, // oid main ().{.  
+	0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x30, 0x5d, 0x20, 0x3d, // gl_FragData[0] =
+	0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, //  v_color0;.  gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x5f, // FragData[1] = v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, // color0;.  gl_Fra
+	0x67, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, // gData[2] = v_col
+	0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // or0;.  gl_FragDa
+	0x74, 0x61, 0x5b, 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, // ta[3] = v_color0
+	0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                             // ;.}...
+};
+static const uint8_t fs_clear3_dx9[173] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x03, 0xff, 0xff, // FSH....I........
+	0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, // ....CTAB....#...
+	0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, // ................
+	0x1c, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, // ....ps_3_0.Micro
+	0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, // soft (R) HLSL Sh
+	0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, // ader Compiler 9.
+	0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, // 29.952.3111.....
+	0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80, // ................
+	0x00, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x01, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, // ................
+	0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, // ................
+	0x03, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00, 0x00,                   // .............
+};
+static const uint8_t fs_clear3_dx11[662] =
+{
+	0x46, 0x53, 0x48, 0x01, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, // FSH....I........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x02, 0x44, 0x58, 0x42, // ...........x.DXB
+	0x43, 0xec, 0x65, 0x4d, 0xe1, 0x28, 0x13, 0xaf, 0x45, 0xea, 0x5d, 0x5d, 0xcc, 0x29, 0xb7, 0xa4, // C.eM.(..E.]].)..
+	0x45, 0x01, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, // E....x.......4..
+	0x00, 0x8c, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0xfc, 0x01, 0x00, // ................
+	0x00, 0x52, 0x44, 0x45, 0x46, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .RDEFP..........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x91, 0x00, // ................
+	0x00, 0x1c, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, // .....Microsoft (
+	0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, // R) HLSL Shader C
+	0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, // ompiler 9.29.952
+	0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, // .3111....ISGNL..
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........8......
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, // ................
+	0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .D..............
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, // .........SV_POSI
+	0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, // TION.COLOR...OSG
+	0x4e, 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, // Nt...........h..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x0f, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....h..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, // .............h..
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, // ................
+	0x00, 0x0f, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....h..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, // .............SV_
+	0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x98, 0x00, 0x00, // TARGET...SHDR...
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, // .@...&...b......
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // .....e.... .....
+	0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, // .e.... ......e..
+	0x03, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, // .. ......e.... .
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // .....6.... .....
+	0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, // .F.......6.... .
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, // .....F.......6..
+	0x05, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, // .. ......F......
+	0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, // .6.... ......F..
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, // .....>...STATt..
+	0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                                             // ......
+};

+ 16 - 0
src/fs_clear3.sc

@@ -0,0 +1,16 @@
+$input v_color0
+
+/*
+ * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_shader.sh"
+
+void main()
+{
+	gl_FragData[0] = v_color0;
+	gl_FragData[1] = v_color0;
+	gl_FragData[2] = v_color0;
+	gl_FragData[3] = v_color0;
+}

+ 11 - 0
src/glimports.h

@@ -86,6 +86,7 @@ typedef void           (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
 typedef void           (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
 typedef void           (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
 typedef void           (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void           (GL_APIENTRYP PFNGLDISABLEIPROC) (GLenum cap, GLuint index);
 typedef void           (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
 typedef void           (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
 typedef void           (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
@@ -93,6 +94,7 @@ typedef void           (GL_APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum mode);
 typedef void           (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
 typedef void           (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
 typedef void           (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void           (GL_APIENTRYP PFNGLENABLEIPROC) (GLenum cap, GLuint index);
 typedef void           (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
 typedef void           (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
 typedef void           (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
@@ -238,6 +240,7 @@ GL_IMPORT______(false, PFNGLDEPTHFUNCPROC,                         glDepthFunc);
 GL_IMPORT______(false, PFNGLDEPTHMASKPROC,                         glDepthMask);
 GL_IMPORT______(false, PFNGLDETACHSHADERPROC,                      glDetachShader);
 GL_IMPORT______(false, PFNGLDISABLEPROC,                           glDisable);
+GL_IMPORT______(true,  PFNGLDISABLEIPROC,                          glDisablei);
 GL_IMPORT______(false, PFNGLDISABLEVERTEXATTRIBARRAYPROC,          glDisableVertexAttribArray);
 GL_IMPORT______(false, PFNGLDRAWARRAYSPROC,                        glDrawArrays);
 GL_IMPORT______(true,  PFNGLDRAWARRAYSINSTANCEDPROC,               glDrawArraysInstanced);
@@ -245,6 +248,7 @@ GL_IMPORT______(true,  PFNGLDRAWBUFFERPROC,                        glDrawBuffer)
 GL_IMPORT______(false, PFNGLDRAWELEMENTSPROC,                      glDrawElements);
 GL_IMPORT______(true,  PFNGLDRAWELEMENTSINSTANCEDPROC,             glDrawElementsInstanced);
 GL_IMPORT______(false, PFNGLENABLEPROC,                            glEnable);
+GL_IMPORT______(true,  PFNGLENABLEIPROC,                           glEnablei);
 GL_IMPORT______(false, PFNGLENABLEVERTEXATTRIBARRAYPROC,           glEnableVertexAttribArray);
 GL_IMPORT______(true,  PFNGLENDQUERYPROC,                          glEndQuery);
 GL_IMPORT______(true,  PFNGLFRAMEBUFFERRENDERBUFFERPROC,           glFramebufferRenderbuffer);
@@ -407,6 +411,13 @@ GL_IMPORT_OES__(true,  PFNGLBINDVERTEXARRAYPROC,                   glBindVertexA
 GL_IMPORT_OES__(true,  PFNGLDELETEVERTEXARRAYSPROC,                glDeleteVertexArrays);
 GL_IMPORT_OES__(true,  PFNGLGENVERTEXARRAYSPROC,                   glGenVertexArrays);
 
+GL_IMPORT_____x(true,  PFNGLENABLEIPROC,                           glEnablei);
+GL_IMPORT_____x(true,  PFNGLDISABLEIPROC,                          glDisablei);
+GL_IMPORT_____x(true,  PFNGLBLENDEQUATIONIPROC,                    glBlendEquationi);
+GL_IMPORT_____x(true,  PFNGLBLENDEQUATIONSEPARATEIPROC,            glBlendEquationSeparatei);
+GL_IMPORT_____x(true,  PFNGLBLENDFUNCIPROC,                        glBlendFunci);
+GL_IMPORT_____x(true,  PFNGLBLENDFUNCSEPARATEIPROC,                glBlendFuncSeparatei);
+
 GL_IMPORT_____x(true,  PFNGLDRAWBUFFERPROC,                        glDrawBuffer);
 GL_IMPORT_____x(true,  PFNGLREADBUFFERPROC,                        glReadBuffer);
 GL_IMPORT_____x(true,  PFNGLGENSAMPLERSPROC,                       glGenSamplers);

+ 9 - 5
src/image.cpp

@@ -28,7 +28,9 @@ namespace bgfx
 		{  2, 8, 4,  8 }, // PTC22
 		{  4, 4, 4,  8 }, // PTC24
 		{  0, 0, 0,  0 }, // Unknown
-		{  8, 1, 1,  1 }, // L8
+		{  8, 1, 1,  1 }, // R8
+		{ 16, 1, 1,  2 }, // R16
+		{ 16, 1, 1,  2 }, // R16F
 		{ 32, 1, 1,  4 }, // BGRA8
 		{ 64, 1, 1,  8 }, // RGBA16
 		{ 64, 1, 1,  8 }, // RGBA16F
@@ -65,7 +67,9 @@ namespace bgfx
 		"PTC22",     // PTC22
 		"PTC24",     // PTC24
 		"<unknown>", // Unknown
-		"L8",        // L8
+		"R8",        // R8
+		"R16",       // R16
+		"R16F"       // R16F
 		"BGRA8",     // BGRA8
 		"RGBA16",    // RGBA16
 		"RGBA16F",   // RGBA16F
@@ -981,9 +985,9 @@ namespace bgfx
 		{ D3DFMT_A16B16G16R16,       TextureFormat::RGBA16  },
 		{ D3DFMT_A16B16G16R16F,      TextureFormat::RGBA16F },
 		{ DDPF_RGB|DDPF_ALPHAPIXELS, TextureFormat::BGRA8   },
-		{ DDPF_INDEXED,              TextureFormat::L8      },
-		{ DDPF_LUMINANCE,            TextureFormat::L8      },
-		{ DDPF_ALPHA,                TextureFormat::L8      },
+		{ DDPF_INDEXED,              TextureFormat::R8      },
+		{ DDPF_LUMINANCE,            TextureFormat::R8      },
+		{ DDPF_ALPHA,                TextureFormat::R8      },
 	};
 
 	bool imageParseDds(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)

+ 161 - 51
src/renderer_d3d11.cpp

@@ -40,19 +40,19 @@ namespace bgfx
 	static const D3D11_BLEND s_blendFactor[][2] =
 	{
 		{ (D3D11_BLEND)0,               (D3D11_BLEND)0               }, // ignored
-		{ D3D11_BLEND_ZERO,             D3D11_BLEND_ZERO             },
-		{ D3D11_BLEND_ONE,              D3D11_BLEND_ONE              },
-		{ D3D11_BLEND_SRC_COLOR,        D3D11_BLEND_SRC_ALPHA        },
-		{ D3D11_BLEND_INV_SRC_COLOR,    D3D11_BLEND_INV_SRC_ALPHA    },
-		{ D3D11_BLEND_SRC_ALPHA,        D3D11_BLEND_SRC_ALPHA        },
-		{ D3D11_BLEND_INV_SRC_ALPHA,    D3D11_BLEND_INV_SRC_ALPHA    },
-		{ D3D11_BLEND_DEST_ALPHA,       D3D11_BLEND_DEST_ALPHA       },
-		{ D3D11_BLEND_INV_DEST_ALPHA,   D3D11_BLEND_INV_DEST_ALPHA   },
-		{ D3D11_BLEND_DEST_COLOR,       D3D11_BLEND_DEST_ALPHA       },
-		{ D3D11_BLEND_INV_DEST_COLOR,   D3D11_BLEND_INV_DEST_ALPHA   },
-		{ D3D11_BLEND_SRC_ALPHA_SAT,    D3D11_BLEND_ONE              },
-		{ D3D11_BLEND_BLEND_FACTOR,     D3D11_BLEND_BLEND_FACTOR     },
-		{ D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR },
+		{ D3D11_BLEND_ZERO,             D3D11_BLEND_ZERO             }, // ZERO
+		{ D3D11_BLEND_ONE,              D3D11_BLEND_ONE              },	// ONE
+		{ D3D11_BLEND_SRC_COLOR,        D3D11_BLEND_SRC_ALPHA        },	// SRC_COLOR
+		{ D3D11_BLEND_INV_SRC_COLOR,    D3D11_BLEND_INV_SRC_ALPHA    },	// INV_SRC_COLOR
+		{ D3D11_BLEND_SRC_ALPHA,        D3D11_BLEND_SRC_ALPHA        },	// SRC_ALPHA
+		{ D3D11_BLEND_INV_SRC_ALPHA,    D3D11_BLEND_INV_SRC_ALPHA    },	// INV_SRC_ALPHA
+		{ D3D11_BLEND_DEST_ALPHA,       D3D11_BLEND_DEST_ALPHA       },	// DST_ALPHA
+		{ D3D11_BLEND_INV_DEST_ALPHA,   D3D11_BLEND_INV_DEST_ALPHA   },	// INV_DST_ALPHA
+		{ D3D11_BLEND_DEST_COLOR,       D3D11_BLEND_DEST_ALPHA       },	// DST_COLOR
+		{ D3D11_BLEND_INV_DEST_COLOR,   D3D11_BLEND_INV_DEST_ALPHA   },	// INV_DST_COLOR
+		{ D3D11_BLEND_SRC_ALPHA_SAT,    D3D11_BLEND_ONE              },	// SRC_ALPHA_SAT
+		{ D3D11_BLEND_BLEND_FACTOR,     D3D11_BLEND_BLEND_FACTOR     },	// FACTOR
+		{ D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR },	// INV_FACTOR
 	};
 
 	static const D3D11_BLEND_OP s_blendEquation[] =
@@ -206,7 +206,9 @@ namespace bgfx
 		{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN           }, // PTC22
 		{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN           }, // PTC24
 		{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN           }, // Unknown
-		{ DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8_UNORM,              DXGI_FORMAT_UNKNOWN           }, // L8
+		{ DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8_UNORM,              DXGI_FORMAT_UNKNOWN           }, // R8
+		{ DXGI_FORMAT_R16_UNORM,          DXGI_FORMAT_R16_UNORM,             DXGI_FORMAT_UNKNOWN           }, // R16
+		{ DXGI_FORMAT_R16_FLOAT,          DXGI_FORMAT_R16_FLOAT,             DXGI_FORMAT_UNKNOWN           }, // R16F
 		{ DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,        DXGI_FORMAT_UNKNOWN           }, // BGRA8
 		{ DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM,    DXGI_FORMAT_UNKNOWN           }, // RGBA16
 		{ DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_UNKNOWN           }, // RGBA16F
@@ -512,6 +514,7 @@ namespace bgfx
 								| BGFX_CAPS_INSTANCING
 								| BGFX_CAPS_VERTEX_ATTRIB_HALF
 								| BGFX_CAPS_FRAGMENT_DEPTH
+								| BGFX_CAPS_BLEND_INDEPENDENT
 								);
 			g_caps.maxTextureSize   = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
 			g_caps.maxFBAttachments = bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS);
@@ -772,21 +775,29 @@ namespace bgfx
 
 		void clear(const Clear& _clear)
 		{
-			if (NULL != m_currentColor
-			&&  BGFX_CLEAR_COLOR_BIT & _clear.m_flags)
+			if (isValid(m_fbh) )
 			{
-				uint32_t rgba = _clear.m_rgba;
-				float frgba[4] = { (rgba>>24)/255.0f, ( (rgba>>16)&0xff)/255.0f, ( (rgba>>8)&0xff)/255.0f, (rgba&0xff)/255.0f };
-				m_deviceCtx->ClearRenderTargetView(m_currentColor, frgba);
+				FrameBuffer& frameBuffer = m_frameBuffers[m_fbh.idx];
+				frameBuffer.clear(_clear);
 			}
-
-			if (NULL != m_currentDepthStencil
-			&& (BGFX_CLEAR_DEPTH_BIT|BGFX_CLEAR_STENCIL_BIT) & _clear.m_flags)
+			else
 			{
-				DWORD flags = 0;
-				flags |= (_clear.m_flags & BGFX_CLEAR_DEPTH_BIT) ? D3D11_CLEAR_DEPTH : 0;
-				flags |= (_clear.m_flags & BGFX_CLEAR_STENCIL_BIT) ? D3D11_CLEAR_STENCIL : 0;
-				m_deviceCtx->ClearDepthStencilView(m_currentDepthStencil, flags, _clear.m_depth, _clear.m_stencil);
+				if (NULL != m_currentColor
+				&&  BGFX_CLEAR_COLOR_BIT & _clear.m_flags)
+				{
+					uint32_t rgba = _clear.m_rgba;
+					float frgba[4] = { (rgba>>24)/255.0f, ( (rgba>>16)&0xff)/255.0f, ( (rgba>>8)&0xff)/255.0f, (rgba&0xff)/255.0f };
+					m_deviceCtx->ClearRenderTargetView(m_currentColor, frgba);
+				}
+
+				if (NULL != m_currentDepthStencil
+				&& (BGFX_CLEAR_DEPTH_BIT|BGFX_CLEAR_STENCIL_BIT) & _clear.m_flags)
+				{
+					DWORD flags = 0;
+					flags |= (_clear.m_flags & BGFX_CLEAR_DEPTH_BIT) ? D3D11_CLEAR_DEPTH : 0;
+					flags |= (_clear.m_flags & BGFX_CLEAR_STENCIL_BIT) ? D3D11_CLEAR_STENCIL : 0;
+					m_deviceCtx->ClearDepthStencilView(m_currentDepthStencil, flags, _clear.m_depth, _clear.m_stencil);
+				}
 			}
 		}
 
@@ -856,46 +867,110 @@ namespace bgfx
 			m_deviceCtx->IASetInputLayout(layout);
 		}
 
-		void setBlendState(uint64_t _state, uint32_t _rgba = UINT32_MAX)
+		void setBlendState(uint64_t _state, uint32_t _rgba = 0)
 		{
-			_state &= BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE;
+			_state &= 0
+				| BGFX_STATE_BLEND_MASK
+				| BGFX_STATE_BLEND_EQUATION_MASK
+				| BGFX_STATE_BLEND_INDEPENDENT
+				| BGFX_STATE_ALPHA_WRITE
+				| BGFX_STATE_RGB_WRITE
+				;
 
-			ID3D11BlendState* bs = m_blendStateCache.find(_state);
+			bx::HashMurmur2A murmur;
+			murmur.begin();
+			murmur.add(_state);
+
+			const uint64_t f0 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_FACTOR);
+			const uint64_t f1 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_FACTOR, BGFX_STATE_BLEND_INV_FACTOR);
+			bool hasFactor = f0 == (_state & f0) 
+						  || f1 == (_state & f1)
+						  ;
+
+			float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+			if (hasFactor)
+			{
+				blendFactor[0] = ( (_rgba>>24)     )/255.0f;
+				blendFactor[1] = ( (_rgba>>16)&0xff)/255.0f;
+				blendFactor[2] = ( (_rgba>> 8)&0xff)/255.0f;
+				blendFactor[3] = ( (_rgba    )&0xff)/255.0f;
+			}
+			else
+			{
+				murmur.add(_rgba);
+			}
+
+			uint32_t hash = murmur.end();
+
+			ID3D11BlendState* bs = m_blendStateCache.find(hash);
 			if (NULL == bs)
 			{
 				D3D11_BLEND_DESC desc;
 				memset(&desc, 0, sizeof(desc) );
-				D3D11_RENDER_TARGET_BLEND_DESC& drt = desc.RenderTarget[0];
-				drt.BlendEnable = !!(BGFX_STATE_BLEND_MASK & _state);
+				desc.IndependentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT & _state);
+
+				D3D11_RENDER_TARGET_BLEND_DESC* drt = &desc.RenderTarget[0];
+				drt->BlendEnable = !!(BGFX_STATE_BLEND_MASK & _state);
+
+				const uint32_t blend    = uint32_t( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT);
+				const uint32_t equation = uint32_t( (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);
+
+				const uint32_t srcRGB = (blend    )&0xf;
+				const uint32_t dstRGB = (blend>> 4)&0xf;
+				const uint32_t srcA   = (blend>> 8)&0xf;
+				const uint32_t dstA   = (blend>>12)&0xf;
+
+				const uint32_t equRGB = (equation   )&0x7;
+				const uint32_t equA   = (equation>>3)&0x7;
+
+				drt->SrcBlend       = s_blendFactor[srcRGB][0];
+				drt->DestBlend      = s_blendFactor[dstRGB][0];
+				drt->BlendOp        = s_blendEquation[equRGB];
+
+				drt->SrcBlendAlpha  = s_blendFactor[srcA][1];
+				drt->DestBlendAlpha = s_blendFactor[dstA][1];
+				drt->BlendOpAlpha   = s_blendEquation[equA];
 
-				uint32_t blend = (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
-				uint32_t equation = (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT;
-				uint32_t src = blend&0xf;
-				uint32_t dst = (blend>>4)&0xf;
 				uint32_t writeMask = (_state&BGFX_STATE_ALPHA_WRITE) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0;
 				writeMask |= (_state&BGFX_STATE_RGB_WRITE) ? D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE : 0;
 
-				drt.SrcBlend = s_blendFactor[src][0];
-				drt.DestBlend = s_blendFactor[dst][0];
-				drt.BlendOp = s_blendEquation[equation];
+				drt->RenderTargetWriteMask = writeMask;
 
-				drt.SrcBlendAlpha = s_blendFactor[src][1];
-				drt.DestBlendAlpha = s_blendFactor[dst][1];
-				drt.BlendOpAlpha = s_blendEquation[equation];
+				if (desc.IndependentBlendEnable)
+				{
+					for (uint32_t ii = 1, rgba = _rgba; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii, rgba >>= 11)
+					{
+						drt = &desc.RenderTarget[ii];
+						drt->BlendEnable = 0 != (rgba&0x7ff);
+
+						const uint32_t src      = (rgba   )&0xf;
+						const uint32_t dst      = (rgba>>4)&0xf;
+						const uint32_t equation = (rgba>>8)&0x7;
 
-				drt.RenderTargetWriteMask = writeMask;
+						drt->SrcBlend       = s_blendFactor[src][0];
+						drt->DestBlend      = s_blendFactor[dst][0];
+						drt->BlendOp        = s_blendEquation[equation];
 
+						drt->SrcBlendAlpha  = s_blendFactor[src][1];
+						drt->DestBlendAlpha = s_blendFactor[dst][1];
+						drt->BlendOpAlpha   = s_blendEquation[equation];
+
+						drt->RenderTargetWriteMask = writeMask;
+					}
+				}
+				else
+				{
+					for (uint32_t ii = 1; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii)
+					{
+						memcpy(&desc.RenderTarget[ii], drt, sizeof(D3D11_RENDER_TARGET_BLEND_DESC) );
+					}
+				}
+				
 				DX_CHECK(m_device->CreateBlendState(&desc, &bs) );
 
-				m_blendStateCache.add(_state, bs);
+				m_blendStateCache.add(hash, bs);
 			}
 
-			float blendFactor[4];
-			blendFactor[0] = (_rgba>>24)/255.0f;
-			blendFactor[1] = ( (_rgba>>16)&0xff)/255.0f;
-			blendFactor[2] = ( (_rgba>>8)&0xff)/255.0f;
-			blendFactor[3] = (_rgba&0xff)/255.0f;
-
 			m_deviceCtx->OMSetBlendState(bs, blendFactor, 0xffffffff);
 		}
 
@@ -1505,7 +1580,15 @@ namespace bgfx
 			s_renderCtx->setDepthStencilState(state, stencil);
 			s_renderCtx->setRasterizerState(state);
 
-			Program& program = s_renderCtx->m_program[m_program.idx];
+			uint32_t numMrt = 0;
+			FrameBufferHandle fbh = s_renderCtx->m_fbh;
+			if (isValid(fbh) )
+			{
+				const FrameBuffer& fb = s_renderCtx->m_frameBuffers[fbh.idx];
+				numMrt = bx::uint32_max(1, fb.m_num)-1;
+			}
+
+			Program& program = s_renderCtx->m_program[m_program[numMrt].idx];
 			s_renderCtx->m_currentProgram = &program;
 			deviceCtx->VSSetShader( (ID3D11VertexShader*)program.m_vsh->m_ptr, NULL, 0);
 			deviceCtx->VSSetConstantBuffers(0, 0, NULL);
@@ -2000,6 +2083,33 @@ namespace bgfx
 	{
 	}
 
+	void FrameBuffer::clear(const Clear& _clear)
+	{
+		ID3D11DeviceContext* deviceCtx = s_renderCtx->m_deviceCtx;
+
+		if (BGFX_CLEAR_COLOR_BIT & _clear.m_flags)
+		{
+			uint32_t rgba = _clear.m_rgba;
+			float frgba[4] = { (rgba>>24)/255.0f, ( (rgba>>16)&0xff)/255.0f, ( (rgba>>8)&0xff)/255.0f, (rgba&0xff)/255.0f };
+			for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
+			{
+				if (NULL != m_rtv[ii])
+				{
+					deviceCtx->ClearRenderTargetView(m_rtv[ii], frgba);
+				}
+			}
+		}
+
+		if (NULL != m_dsv
+		&& (BGFX_CLEAR_DEPTH_BIT|BGFX_CLEAR_STENCIL_BIT) & _clear.m_flags)
+		{
+			DWORD flags = 0;
+			flags |= (_clear.m_flags & BGFX_CLEAR_DEPTH_BIT) ? D3D11_CLEAR_DEPTH : 0;
+			flags |= (_clear.m_flags & BGFX_CLEAR_STENCIL_BIT) ? D3D11_CLEAR_STENCIL : 0;
+			deviceCtx->ClearDepthStencilView(m_dsv, flags, _clear.m_depth, _clear.m_stencil);
+		}
+	}
+
 	void UniformBuffer::create(UniformType::Enum _type, uint16_t _num, bool _alloc)
 	{
 		uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type]*_num);
@@ -2380,8 +2490,8 @@ namespace bgfx
 
 				if ( (0
 					 | BGFX_STATE_CULL_MASK
-					 | BGFX_STATE_ALPHA_MASK
 					 | BGFX_STATE_RGB_WRITE
+					 | BGFX_STATE_ALPHA_WRITE
 					 | BGFX_STATE_BLEND_MASK
 					 | BGFX_STATE_BLEND_EQUATION_MASK
 					 | BGFX_STATE_ALPHA_REF_MASK

+ 1 - 0
src/renderer_d3d11.h

@@ -288,6 +288,7 @@ namespace bgfx
 		void create(uint8_t _num, const TextureHandle* _handles);
 		void destroy();
 		void resolve();
+		void clear(const Clear& _clear);
 
 		ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
 		ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];

+ 56 - 34
src/renderer_d3d9.cpp

@@ -47,19 +47,19 @@ namespace bgfx
 	static const Blend s_blendFactor[] =
 	{
 		{ (D3DBLEND)0,             (D3DBLEND)0,             false }, // ignored
-		{ D3DBLEND_ZERO,           D3DBLEND_ZERO,           false },
-		{ D3DBLEND_ONE,            D3DBLEND_ONE,            false },
-		{ D3DBLEND_SRCCOLOR,       D3DBLEND_SRCCOLOR,       false },
-		{ D3DBLEND_INVSRCCOLOR,    D3DBLEND_INVSRCCOLOR,    false },
-		{ D3DBLEND_SRCALPHA,       D3DBLEND_SRCALPHA,       false },
-		{ D3DBLEND_INVSRCALPHA,    D3DBLEND_INVSRCALPHA,    false },
-		{ D3DBLEND_DESTALPHA,      D3DBLEND_DESTALPHA,      false },
-		{ D3DBLEND_INVDESTALPHA,   D3DBLEND_INVDESTALPHA,   false },
-		{ D3DBLEND_DESTCOLOR,      D3DBLEND_DESTCOLOR,      false },
-		{ D3DBLEND_INVDESTCOLOR,   D3DBLEND_INVDESTCOLOR,   false },
-		{ D3DBLEND_SRCALPHASAT,    D3DBLEND_ONE,            false },
-		{ D3DBLEND_BLENDFACTOR,    D3DBLEND_BLENDFACTOR,    true  },
-		{ D3DBLEND_INVBLENDFACTOR, D3DBLEND_INVBLENDFACTOR, true  },
+		{ D3DBLEND_ZERO,           D3DBLEND_ZERO,           false }, // ZERO
+		{ D3DBLEND_ONE,            D3DBLEND_ONE,            false }, // ONE
+		{ D3DBLEND_SRCCOLOR,       D3DBLEND_SRCCOLOR,       false }, // SRC_COLOR
+		{ D3DBLEND_INVSRCCOLOR,    D3DBLEND_INVSRCCOLOR,    false }, // INV_SRC_COLOR
+		{ D3DBLEND_SRCALPHA,       D3DBLEND_SRCALPHA,       false }, // SRC_ALPHA
+		{ D3DBLEND_INVSRCALPHA,    D3DBLEND_INVSRCALPHA,    false }, // INV_SRC_ALPHA
+		{ D3DBLEND_DESTALPHA,      D3DBLEND_DESTALPHA,      false }, // DST_ALPHA
+		{ D3DBLEND_INVDESTALPHA,   D3DBLEND_INVDESTALPHA,   false }, // INV_DST_ALPHA
+		{ D3DBLEND_DESTCOLOR,      D3DBLEND_DESTCOLOR,      false }, // DST_COLOR
+		{ D3DBLEND_INVDESTCOLOR,   D3DBLEND_INVDESTCOLOR,   false }, // INV_DST_COLOR
+		{ D3DBLEND_SRCALPHASAT,    D3DBLEND_ONE,            false }, // SRC_ALPHA_SAT
+		{ D3DBLEND_BLENDFACTOR,    D3DBLEND_BLENDFACTOR,    true  }, // FACTOR
+		{ D3DBLEND_INVBLENDFACTOR, D3DBLEND_INVBLENDFACTOR, true  }, // INV_FACTOR
 	};
 
 	static const D3DBLENDOP s_blendEquation[] =
@@ -184,7 +184,9 @@ namespace bgfx
 		{ D3DFMT_UNKNOWN       }, // PTC22
 		{ D3DFMT_UNKNOWN       }, // PTC24
 		{ D3DFMT_UNKNOWN       }, // Unknown
-		{ D3DFMT_L8            }, // L8
+		{ D3DFMT_L8            }, // R8
+		{ D3DFMT_G16R16        }, // R16
+		{ D3DFMT_R16F          }, // R16F
 		{ D3DFMT_A8R8G8B8      }, // BGRA8
 		{ D3DFMT_A16B16G16R16  }, // RGBA16
 		{ D3DFMT_A16B16G16R16F }, // RGBA16F
@@ -2593,8 +2595,8 @@ namespace bgfx
 					 | BGFX_STATE_CULL_MASK
 					 | BGFX_STATE_DEPTH_WRITE
 					 | BGFX_STATE_DEPTH_TEST_MASK
-					 | BGFX_STATE_ALPHA_MASK
 					 | BGFX_STATE_RGB_WRITE
+					 | BGFX_STATE_ALPHA_WRITE
 					 | BGFX_STATE_BLEND_MASK
 					 | BGFX_STATE_BLEND_EQUATION_MASK
 					 | BGFX_STATE_ALPHA_REF_MASK
@@ -2648,33 +2650,53 @@ namespace bgfx
 						DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, writeEnable) );
 					}
 
-					if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK) & changedFlags)
+					if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK) & changedFlags
+					||  blendFactor != state.m_rgba)
 					{
-						bool alphaBlendEnabled = !!(BGFX_STATE_BLEND_MASK & newFlags);
-						DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlendEnabled) );
-//						DX_CHECK(device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, alphaBlendEnabled) );
+						bool enabled = !!(BGFX_STATE_BLEND_MASK & newFlags);
+						DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, enabled) );
 
-						if (alphaBlendEnabled)
+						if (enabled)
 						{
-							uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
-							uint32_t equation = (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT;
-							uint32_t src = blend&0xf;
-							uint32_t dst = (blend>>4)&0xf;
-
- 							DX_CHECK(device->SetRenderState(D3DRS_SRCBLEND, s_blendFactor[src].m_src) );
-							DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dst].m_dst) );
-							DX_CHECK(device->SetRenderState(D3DRS_BLENDOP, s_blendEquation[equation]) );
-//							DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA) );
-//							DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA) );
-
-							if ( (s_blendFactor[src].m_factor || s_blendFactor[dst].m_factor)
+							const uint32_t blend    = uint32_t( (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT);
+							const uint32_t equation = uint32_t( (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);
+
+							const uint32_t srcRGB  = (blend    )&0xf;
+							const uint32_t dstRGB  = (blend>> 4)&0xf;
+							const uint32_t srcA    = (blend>> 8)&0xf;
+							const uint32_t dstA    = (blend>>12)&0xf;
+
+							const uint32_t equRGB = (equation   )&0x7;
+							const uint32_t equA   = (equation>>3)&0x7;
+
+ 							DX_CHECK(device->SetRenderState(D3DRS_SRCBLEND,  s_blendFactor[srcRGB].m_src) );
+							DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dstRGB].m_dst) );
+							DX_CHECK(device->SetRenderState(D3DRS_BLENDOP,   s_blendEquation[equRGB]) );
+
+							const bool separate = srcRGB != srcA || dstRGB != dstA || equRGB != equA;
+
+							DX_CHECK(device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, separate) );
+							if (separate)
+							{
+								DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA,  s_blendFactor[srcA].m_src) );
+								DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, s_blendFactor[dstA].m_dst) );
+								DX_CHECK(device->SetRenderState(D3DRS_BLENDOPALPHA,   s_blendEquation[equA]) );
+							}
+
+							if ( (s_blendFactor[srcRGB].m_factor || s_blendFactor[dstRGB].m_factor)
 							&&  blendFactor != state.m_rgba)
 							{
-								blendFactor = state.m_rgba;
-								D3DCOLOR color = D3DCOLOR_RGBA(blendFactor>>24, (blendFactor>>16)&0xff, (blendFactor>>8)&0xff, blendFactor&0xff);
+								const uint32_t rgba = state.m_rgba;
+								D3DCOLOR color = D3DCOLOR_RGBA(rgba>>24
+															, (rgba>>16)&0xff
+															, (rgba>> 8)&0xff
+															, (rgba    )&0xff
+															);
 								DX_CHECK(device->SetRenderState(D3DRS_BLENDFACTOR, color) );
 							}
 						}
+
+						blendFactor = state.m_rgba;
 					}
 
 					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);

+ 136 - 42
src/renderer_gl.cpp

@@ -67,19 +67,19 @@ namespace bgfx
 	static const Blend s_blendFactor[] =
 	{
 		{ 0,                           0,                           false }, // ignored
-		{ GL_ZERO,                     GL_ZERO,                     false },
-		{ GL_ONE,                      GL_ONE,                      false },
-		{ GL_SRC_COLOR,                GL_SRC_COLOR,                false },
-		{ GL_ONE_MINUS_SRC_COLOR,      GL_ONE_MINUS_SRC_COLOR,      false },
-		{ GL_SRC_ALPHA,                GL_SRC_ALPHA,                false },
-		{ GL_ONE_MINUS_SRC_ALPHA,      GL_ONE_MINUS_SRC_ALPHA,      false },
-		{ GL_DST_ALPHA,                GL_DST_ALPHA,                false },
-		{ GL_ONE_MINUS_DST_ALPHA,      GL_ONE_MINUS_DST_ALPHA,      false },
-		{ GL_DST_COLOR,                GL_DST_COLOR,                false },
-		{ GL_ONE_MINUS_DST_COLOR,      GL_ONE_MINUS_DST_COLOR,      false },
-		{ GL_SRC_ALPHA_SATURATE,       GL_ONE,                      false },
-		{ GL_CONSTANT_COLOR,           GL_CONSTANT_COLOR,           true  },
-		{ GL_ONE_MINUS_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, true  },
+		{ GL_ZERO,                     GL_ZERO,                     false }, // ZERO
+		{ GL_ONE,                      GL_ONE,                      false }, // ONE
+		{ GL_SRC_COLOR,                GL_SRC_COLOR,                false }, // SRC_COLOR
+		{ GL_ONE_MINUS_SRC_COLOR,      GL_ONE_MINUS_SRC_COLOR,      false }, // INV_SRC_COLOR
+		{ GL_SRC_ALPHA,                GL_SRC_ALPHA,                false }, // SRC_ALPHA
+		{ GL_ONE_MINUS_SRC_ALPHA,      GL_ONE_MINUS_SRC_ALPHA,      false }, // INV_SRC_ALPHA
+		{ GL_DST_ALPHA,                GL_DST_ALPHA,                false }, // DST_ALPHA
+		{ GL_ONE_MINUS_DST_ALPHA,      GL_ONE_MINUS_DST_ALPHA,      false }, // INV_DST_ALPHA
+		{ GL_DST_COLOR,                GL_DST_COLOR,                false }, // DST_COLOR
+		{ GL_ONE_MINUS_DST_COLOR,      GL_ONE_MINUS_DST_COLOR,      false }, // INV_DST_COLOR
+		{ GL_SRC_ALPHA_SATURATE,       GL_ONE,                      false }, // SRC_ALPHA_SAT
+		{ GL_CONSTANT_COLOR,           GL_CONSTANT_COLOR,           true  }, // FACTOR
+		{ GL_ONE_MINUS_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, true  }, // INV_FACTOR
 	};
 
 	static const GLenum s_blendEquation[] =
@@ -170,7 +170,9 @@ namespace bgfx
 		{ GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,         GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,         GL_ZERO,                        false }, // PTC22
 		{ GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG,         GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG,         GL_ZERO,                        false }, // PTC24
 		{ GL_ZERO,                                     GL_ZERO,                                     GL_ZERO,                        true  }, // Unknown
-		{ GL_LUMINANCE,                                GL_LUMINANCE,                                GL_UNSIGNED_BYTE,               true  }, // L8
+		{ GL_LUMINANCE,                                GL_LUMINANCE,                                GL_UNSIGNED_BYTE,               true  }, // R8
+		{ GL_R16,                                      GL_RED,                                      GL_UNSIGNED_SHORT,              true  }, // R16
+		{ GL_R16F,                                     GL_RED,                                      GL_HALF_FLOAT,                  true  }, // R16F
 		{ GL_RGBA,                                     GL_RGBA,                                     GL_UNSIGNED_BYTE,               true  }, // BGRA8
 		{ GL_RGBA16,                                   GL_RGBA,                                     GL_UNSIGNED_BYTE,               true  }, // RGBA16
 		{ GL_RGBA16F,                                  GL_RGBA,                                     GL_HALF_FLOAT,                  true  }, // RGBA16F
@@ -725,6 +727,17 @@ namespace bgfx
 			return _height;
 		}
 
+		uint32_t getNumRt() const
+		{
+			if (isValid(m_fbh) )
+			{
+				const FrameBuffer& frameBuffer = m_frameBuffers[m_fbh.idx];
+				return frameBuffer.m_num;
+			}
+
+			return 1;
+		}
+
 		void createMsaaFbo(uint32_t _width, uint32_t _height, uint32_t _msaa)
 		{
 			if (1 < _msaa)
@@ -1213,6 +1226,10 @@ namespace bgfx
 				? BGFX_CAPS_FRAGMENT_DEPTH
 				: 0
 				;
+			g_caps.supported |= s_extension[Extension::ARB_draw_buffers_blend].m_supported
+				? BGFX_CAPS_BLEND_INDEPENDENT
+				: 0
+				;
 			g_caps.maxTextureSize = glGet(GL_MAX_TEXTURE_SIZE);
 
 			if (BX_ENABLED(!BGFX_CONFIG_RENDERER_OPENGLES2) )
@@ -1359,8 +1376,8 @@ namespace bgfx
 #if BGFX_CONFIG_RENDERER_OPENGL
 			if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL >= 31) )
 			{
-				s_textureFormat[TextureFormat::L8].m_internalFmt = GL_R8;
-				s_textureFormat[TextureFormat::L8].m_fmt         = GL_RED;
+				s_textureFormat[TextureFormat::R8].m_internalFmt = GL_R8;
+				s_textureFormat[TextureFormat::R8].m_fmt         = GL_RED;
 			}
 
 			if (s_extension[Extension::ARB_debug_output].m_supported
@@ -1962,7 +1979,8 @@ namespace bgfx
 			}
 
 #if BGFX_CONFIG_RENDERER_OPENGL
-			if (GL_RGBA == m_fmt
+			if (TextureFormat::BGRA8 == m_textureFormat
+			&&  GL_RGBA == m_fmt
 			&&  s_renderCtx->m_textureSwizzleSupport)
 			{
 				GLint swizzleMask[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
@@ -2712,6 +2730,8 @@ namespace bgfx
 			}
 		}
 
+		m_num = colorIdx;
+
 		if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
 		{
 			if (0 == colorIdx)
@@ -2745,11 +2765,7 @@ namespace bgfx
 					if (0 != texture.m_id)
 					{
 						GLenum attachment = GL_COLOR_ATTACHMENT0 + colorIdx;
-						if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) )
-						{
-							attachment = GL_DEPTH_ATTACHMENT;
-						}
-						else
+						if (!isDepth( (TextureFormat::Enum)texture.m_textureFormat) )
 						{
 							++colorIdx;
 							GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
@@ -2776,6 +2792,7 @@ namespace bgfx
 	{
 		GL_CHECK(glDeleteFramebuffers(0 == m_fbo[1] ? 1 : 2, m_fbo) );
 		memset(m_fbo, 0, sizeof(m_fbo) );
+		m_num = 0;
 	}
 
 	void FrameBuffer::resolve()
@@ -3027,7 +3044,15 @@ namespace bgfx
 			IndexBuffer& ib = s_renderCtx->m_indexBuffers[m_ib.idx];
 			GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
 
-			Program& program = s_renderCtx->m_program[m_program.idx];
+			uint32_t numMrt = 0;
+			FrameBufferHandle fbh = s_renderCtx->m_fbh;
+			if (isValid(fbh) )
+			{
+				const FrameBuffer& fb = s_renderCtx->m_frameBuffers[fbh.idx];
+				numMrt = bx::uint32_max(1, fb.m_num)-1;
+			}
+
+			Program& program = s_renderCtx->m_program[m_program[numMrt].idx];
 			GL_CHECK(glUseProgram(program.m_id) );
 			program.bindAttributes(vertexDecl, 0);
 
@@ -3463,8 +3488,8 @@ namespace bgfx
 					 | BGFX_STATE_CULL_MASK
 					 | BGFX_STATE_DEPTH_WRITE
 					 | BGFX_STATE_DEPTH_TEST_MASK
-					 | BGFX_STATE_ALPHA_MASK
 					 | BGFX_STATE_RGB_WRITE
+					 | BGFX_STATE_ALPHA_WRITE
 					 | BGFX_STATE_BLEND_MASK
 					 | BGFX_STATE_BLEND_EQUATION_MASK
 					 | BGFX_STATE_ALPHA_REF_MASK
@@ -3544,35 +3569,104 @@ namespace bgfx
 						GL_CHECK(glColorMask(rgb, rgb, rgb, alpha) );
 					}
 
-					if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK) & changedFlags)
+					if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_BLEND_INDEPENDENT) & changedFlags
+					||  blendFactor != state.m_rgba)
 					{
-						if (BGFX_STATE_BLEND_MASK & newFlags)
+						if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_BLEND_INDEPENDENT) & newFlags
+						||  blendFactor != state.m_rgba)
 						{
-							uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
-							uint32_t equation = (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT;
-							uint32_t src = blend&0xf;
-							uint32_t dst = (blend>>4)&0xf;
-							GL_CHECK(glEnable(GL_BLEND) );
-							GL_CHECK(glBlendFunc(s_blendFactor[src].m_src, s_blendFactor[dst].m_dst) );
-							GL_CHECK(glBlendEquation(s_blendEquation[equation]) );
-
-							if ( (s_blendFactor[src].m_factor || s_blendFactor[dst].m_factor)
-							&&  blendFactor != state.m_rgba)
+							const bool enabled = !!(BGFX_STATE_BLEND_MASK & newFlags);
+							const bool independent = !!(BGFX_STATE_BLEND_INDEPENDENT & newFlags);
+
+							const uint32_t blend    = uint32_t( (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT);
+							const uint32_t equation = uint32_t( (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);
+
+							const uint32_t srcRGB  = (blend    )&0xf;
+							const uint32_t dstRGB  = (blend>> 4)&0xf;
+							const uint32_t srcA    = (blend>> 8)&0xf;
+							const uint32_t dstA    = (blend>>12)&0xf;
+
+							const uint32_t equRGB = (equation   )&0x7;
+							const uint32_t equA   = (equation>>3)&0x7;
+
+							const uint32_t numRt = s_renderCtx->getNumRt();
+
+							if (!BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
+							||  1 >= numRt
+							||  !independent)
 							{
-								blendFactor = state.m_rgba;
+								if (enabled)
+								{
+									GL_CHECK(glEnable(GL_BLEND) );
+									GL_CHECK(glBlendFuncSeparate(s_blendFactor[srcRGB].m_src
+										, s_blendFactor[dstRGB].m_dst
+										, s_blendFactor[srcA].m_src
+										, s_blendFactor[dstA].m_dst)
+										);
+									GL_CHECK(glBlendEquationSeparate(s_blendEquation[equRGB], s_blendEquation[equA]) );
+
+									if ( (s_blendFactor[srcRGB].m_factor || s_blendFactor[dstRGB].m_factor)
+									&&  blendFactor != state.m_rgba)
+									{
+										const uint32_t rgba = state.m_rgba;
+										GLclampf rr = ( (rgba>>24)     )/255.0f;
+										GLclampf gg = ( (rgba>>16)&0xff)/255.0f;
+										GLclampf bb = ( (rgba>> 8)&0xff)/255.0f;
+										GLclampf aa = ( (rgba    )&0xff)/255.0f;
 
-								GLclampf rr = (blendFactor>>24)/255.0f;
-								GLclampf gg = ( (blendFactor>>16)&0xff)/255.0f;
-								GLclampf bb = ( (blendFactor>>8)&0xff)/255.0f;
-								GLclampf aa = (blendFactor&0xff)/255.0f;
+										GL_CHECK(glBlendColor(rr, gg, bb, aa) );
+									}
+								}
+								else
+								{
+									GL_CHECK(glDisable(GL_BLEND) );
+								}
+							}
+							else
+							{
+								if (enabled)
+								{
+									GL_CHECK(glEnablei(GL_BLEND, 0) );
+									GL_CHECK(glBlendFuncSeparatei(0
+										, s_blendFactor[srcRGB].m_src
+										, s_blendFactor[dstRGB].m_dst
+										, s_blendFactor[srcA].m_src
+										, s_blendFactor[dstA].m_dst)
+										);
+									GL_CHECK(glBlendEquationSeparatei(0
+										, s_blendEquation[equRGB]
+										, s_blendEquation[equA])
+										);
+								}
+								else
+								{
+									GL_CHECK(glDisablei(GL_BLEND, 0) );
+								}
 
-								GL_CHECK(glBlendColor(rr, gg, bb, aa) );
+								for (uint32_t ii = 1, rgba = state.m_rgba; ii < numRt; ++ii, rgba >>= 11)
+								{
+									if (0 != (rgba&0x7ff) )
+									{
+										const uint32_t src      = (rgba   )&0xf;
+										const uint32_t dst      = (rgba>>4)&0xf;
+										const uint32_t equation = (rgba>>8)&0x7;
+										GL_CHECK(glEnablei(GL_BLEND, ii) );
+										GL_CHECK(glBlendFunci(ii, s_blendFactor[src].m_src, s_blendFactor[dst].m_dst) );
+										GL_CHECK(glBlendEquationi(ii, s_blendEquation[equation]) );
+									}
+									else
+									{
+										GL_CHECK(glDisablei(GL_BLEND, ii) );
+									}
+								}
 							}
 						}
 						else
 						{
 							GL_CHECK(glDisable(GL_BLEND) );
 						}
+
+						blendFactor = state.m_rgba;
 					}
 
 					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);

+ 9 - 0
src/renderer_gl.h

@@ -64,6 +64,7 @@ typedef uint64_t GLuint64;
 #		define GL_RGB10_A2 GL_RGB10_A2_EXT
 #		define GL_R16F GL_R16F_EXT
 #		define GL_R32F GL_R32F_EXT
+#		define GL_RED GL_RED_EXT
 #		define GL_UNSIGNED_INT_2_10_10_10_REV GL_UNSIGNED_INT_2_10_10_10_REV_EXT
 #		define GL_TEXTURE_3D GL_TEXTURE_3D_OES
 #		define GL_SAMPLER_3D GL_SAMPLER_3D_OES
@@ -98,6 +99,10 @@ typedef uint64_t GLuint64;
 #	define GL_BGRA_EXT 0x80E1
 #endif // GL_BGRA_EXT
 
+#ifndef GL_R16
+#	define GL_R16 0x822A
+#endif // GL_R16
+
 #ifndef GL_R16F_EXT
 #	define GL_R16F_EXT 0x822D
 #endif // GL_R16F_EXT
@@ -106,6 +111,10 @@ typedef uint64_t GLuint64;
 #	define GL_R32F_EXT 0x822E
 #endif // GL_R32F_EXT
 
+#ifndef GL_RED_EXT
+#	define GL_RED_EXT 0x1903
+#endif // GL_RED_EXT
+
 #ifndef GL_RGB10_A2_EXT
 #	define GL_RGB10_A2_EXT 0x8059
 #endif // GL_RGB10_A2_EXT