bkaradzic 13 лет назад
Родитель
Сommit
45a85d438c
11 измененных файлов с 6140 добавлено и 5915 удалено
  1. 3095 3095
      src/bgfx_p.h
  2. 31 30
      src/fs_clear_dx11.bin.h
  3. 55 52
      src/fs_debugfont_dx11.bin.h
  4. 225 90
      src/renderer_d3d11.cpp
  5. 6 10
      src/renderer_d3d11.h
  6. 2431 2417
      src/renderer_d3d9.cpp
  7. 2 2
      src/renderer_d3d9.h
  8. 14 1
      src/renderer_gl.cpp
  9. 37 36
      src/vs_clear_dx11.bin.h
  10. 173 171
      src/vs_debugfont_dx11.bin.h
  11. 71 11
      tools/shaderc.cpp

+ 3095 - 3095
src/bgfx_p.h

@@ -1,3103 +1,3103 @@
-/*
- * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
- * License: http://www.opensource.org/licenses/BSD-2-Clause
- */
-
-#ifndef __BGFX_P_H__
-#define __BGFX_P_H__
-
-#include "bgfx.h"
-#include <inttypes.h>
-#include <stdarg.h> // va_list
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <alloca.h>
-
-extern void dbgPrintf(const char* _format, ...);
-extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...);
-
-#ifndef BGFX_CONFIG_DEBUG
-#	define BGFX_CONFIG_DEBUG 0
-#endif // BGFX_CONFIG_DEBUG
-
-#if BGFX_CONFIG_DEBUG
-#	define BX_TRACE(_format, ...) \
-				do { \
-					dbgPrintf(BX_FILE_LINE_LITERAL "BGFX " _format "\n", ##__VA_ARGS__); \
-				} while(0)
-
-#	define BX_CHECK(_condition, _format, ...) \
-				do { \
-					if (!(_condition) ) \
-					{ \
-						BX_TRACE(BX_FILE_LINE_LITERAL "CHECK " _format, ##__VA_ARGS__); \
-						bx::debugBreak(); \
-					} \
-				} while(0)
-#endif // 0
-
-#define BGFX_FATAL(_condition, _err, _format, ...) \
-			do { \
-				if (!(_condition) ) \
-				{ \
-					fatal(_err, _format, ##__VA_ARGS__); \
-				} \
-			} while(0)
-
-#define BX_NAMESPACE 1
-#include <bx/bx.h>
-#include <bx/debug.h>
-#include <bx/blockalloc.h>
-#include <bx/countof.h>
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#ifndef __BGFX_P_H__
+#define __BGFX_P_H__
+
+#include "bgfx.h"
+#include <inttypes.h>
+#include <stdarg.h> // va_list
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <alloca.h>
+
+extern void dbgPrintf(const char* _format, ...);
+extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...);
+
+#ifndef BGFX_CONFIG_DEBUG
+#	define BGFX_CONFIG_DEBUG 0
+#endif // BGFX_CONFIG_DEBUG
+
+#if BGFX_CONFIG_DEBUG
+#	define BX_TRACE(_format, ...) \
+				do { \
+					dbgPrintf(BX_FILE_LINE_LITERAL "BGFX " _format "\n", ##__VA_ARGS__); \
+				} while(0)
+
+#	define BX_CHECK(_condition, _format, ...) \
+				do { \
+					if (!(_condition) ) \
+					{ \
+						BX_TRACE(BX_FILE_LINE_LITERAL "CHECK " _format, ##__VA_ARGS__); \
+						bx::debugBreak(); \
+					} \
+				} while(0)
+#endif // 0
+
+#define BGFX_FATAL(_condition, _err, _format, ...) \
+			do { \
+				if (!(_condition) ) \
+				{ \
+					fatal(_err, _format, ##__VA_ARGS__); \
+				} \
+			} while(0)
+
+#define BX_NAMESPACE 1
+#include <bx/bx.h>
+#include <bx/debug.h>
+#include <bx/blockalloc.h>
+#include <bx/countof.h>
 #include <bx/endian.h>
-#include <bx/handlealloc.h>
-#include <bx/hash.h>
-#include <bx/radixsort.h>
-#include <bx/ringbuffer.h>
-#include <bx/uint32_t.h>
-
-#if BX_PLATFORM_WINDOWS
-#	include <windows.h>
-extern HWND g_bgfxHwnd;
-#elif BX_PLATFORM_XBOX360
-#	include <malloc.h>
-#	include <xtl.h>
-#elif BX_PLATFORM_POSIX
-#	include <pthread.h>
-#endif // BX_PLATFORM_*
-
-#ifndef MAKEFOURCC
-#	define MAKEFOURCC(_a, _b, _c, _d) (0 \
-				| ( (uint32_t)(_a) \
-				| ( (uint32_t)(_b) << 8) \
-				| ( (uint32_t)(_c) << 16) \
-				| ( (uint32_t)(_d) << 24) \
-				) )
-#endif // MAKEFOURCC
-
-#include "dds.h"
-
-#define BGFX_MAGIC MAKEFOURCC('B','G','F','X')
-
-#if BGFX_CONFIG_USE_TINYSTL
-
-namespace tinystl
-{
-	struct bgfx_allocator
-	{
-		static void* static_allocate(size_t _bytes);
-		static void static_deallocate(void* _ptr, size_t /*_bytes*/);
-	};
-} // namespace tinystl
-#	define TINYSTL_ALLOCATOR tinystl::bgfx_allocator
-
-#	include <TINYSTL/string.h>
-#	include <TINYSTL/unordered_map.h>
-namespace stl = tinystl;
-#else
-namespace std { namespace tr1 {} using namespace tr1; } // namespace std
-#	include <string>
-#	include <unordered_map>
-namespace stl = std;
-#endif // BGFX_CONFIG_USE_TINYSTL
-#include <list>
-
-#include "config.h"
-
-#if BGFX_CONFIG_MULTITHREADED
-#	include <bx/sem.h>
-#endif // BGFX_CONFIG_MULTITHREADED
-
-#include <bx/cpu.h>
-#include <bx/timer.h>
-
-#define BGFX_DRAW_WHOLE_INDEX_BUFFER 0xffffffff
-
-#define BGFX_DEFAULT_WIDTH  1280
-#define BGFX_DEFAULT_HEIGHT 720
-
-#define BGFX_STATE_TEX0      UINT64_C(0x0100000000000000)
-#define BGFX_STATE_TEX1      UINT64_C(0x0200000000000000)
-#define BGFX_STATE_TEX2      UINT64_C(0x0400000000000000)
-#define BGFX_STATE_TEX3      UINT64_C(0x0800000000000000)
-#define BGFX_STATE_TEX4      UINT64_C(0x1000000000000000)
-#define BGFX_STATE_TEX5      UINT64_C(0x2000000000000000)
-#define BGFX_STATE_TEX6      UINT64_C(0x4000000000000000)
-#define BGFX_STATE_TEX7      UINT64_C(0x8000000000000000)
-#define BGFX_STATE_TEX_MASK  UINT64_C(0xff00000000000000)
-#define BGFX_STATE_TEX_COUNT 8
-
-#define BGFX_SAMPLER_TEXTURE            UINT16_C(0x0000)
-#define BGFX_SAMPLER_RENDERTARGET_COLOR UINT16_C(0x0001)
-#define BGFX_SAMPLER_RENDERTARGET_DEPTH UINT16_C(0x0002)
-#define BGFX_SAMPLER_TYPE_MASK          UINT16_C(0x0003)
-
-#if BGFX_CONFIG_RENDERER_DIRECT3D9
-#	define BGFX_RENDERER_NAME "Direct3D 9"
-#elif BGFX_CONFIG_RENDERER_DIRECT3D11
-#	define BGFX_RENDERER_NAME "Direct3D 11"
-#elif BGFX_CONFIG_RENDERER_OPENGL
-#	define BGFX_RENDERER_NAME "OpenGL"
-#elif BGFX_CONFIG_RENDERER_OPENGLES2
-#	define BGFX_RENDERER_NAME "OpenGL ES 2"
-#endif // BGFX_CONFIG_RENDERER_
-
-namespace bgfx
-{
-	struct Clear
-	{
-		uint32_t m_rgba;
-		float m_depth;
-		uint8_t m_stencil;
-		uint8_t m_flags;
-	};
-
-	struct Rect
-	{
-		uint16_t m_x;
-		uint16_t m_y;
-		uint16_t m_width;
-		uint16_t m_height;
-	};
-
-	extern const uint32_t g_constantTypeSize[ConstantType::Count];
-	extern FatalFn g_fatal;
-	extern ReallocFn g_realloc;
-	extern FreeFn g_free;
-	extern CacheFn g_cache;
-
-	void fatal(Fatal::Enum _code, const char* _format, ...);
-	void release(const Memory* _mem);
-	void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale = false, bool _yflip = false);
-	const char* getAttribName(Attrib::Enum _attr);
-	bool renderFrame();
-
-	inline uint32_t uint16_min(uint16_t _a, uint16_t _b)
-	{
-		return _a > _b ? _b : _a;
-	}
-
-	inline uint32_t uint16_max(uint16_t _a, uint16_t _b)
-	{
-		return _a < _b ? _b : _a;
-	}
-
-	inline uint32_t hash(const void* _data, uint32_t _size)
-	{
-		HashMurmur2A murmur;
-		murmur.begin();
-		murmur.add(_data, (int)_size);
-		return murmur.end();
-	}
-
-	inline uint32_t gcd(uint32_t _a, uint32_t _b)
-	{
-		do
-		{
-			uint32_t tmp = _a % _b;
-			_a = _b;
-			_b = tmp;
-		}
-		while (_b);
-
-		return _a;
-	}
-
-	inline uint32_t lcm(uint32_t _a, uint32_t _b)
-	{
-		return _a * (_b / gcd(_a, _b) );
-	}
-
-	inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride)
-	{
-		const uint32_t mod    = uint32_mod(_offset, _stride);
-		const uint32_t add    = uint32_sub(_stride, mod);
-		const uint32_t mask   = uint32_cmpeq(mod, 0);
-		const uint32_t tmp    = uint32_selb(mask, 0, add);
-		const uint32_t result = uint32_add(_offset, tmp);
-
-		return result;
-	}
-
-	inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride)
-	{
-		uint32_t align = lcm(16, _stride);
-		return _offset+align-(_offset%align);
-	}
-
-	inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride)
-	{
-		uint32_t align = lcm(256, _stride);
-		return _offset+align-(_offset%align);
-	}
-
-	BX_FORCE_INLINE uint32_t castfu(float _value)
-	{
-		union {	float fl; uint32_t ui; } un;
-		un.fl = _value;
-		return un.ui;
-	}
-
-	void dump(const VertexDecl& _decl);
-
-	struct TextVideoMem
-	{
-		TextVideoMem()
-			: m_mem(NULL)
-			, m_size(0)
-			, m_width(0)
-			, m_height(0)
-			, m_small(false)
-		{
-			resize();
-			clear();
-		}
-
-		~TextVideoMem()
-		{
-			g_free(m_mem);
-		}
-
-		void resize(bool _small = false, uint16_t _width = BGFX_DEFAULT_WIDTH, uint16_t _height = BGFX_DEFAULT_HEIGHT)
-		{
-			uint32_t width = uint32_max(1, _width/8);
-			uint32_t height = uint32_max(1, _height/(_small ? 8 : 16) );
-
-			if (NULL == m_mem
-			||  m_width != width
-			||  m_height != height
-			||  m_small != _small)
-			{
-				m_small = _small;
-				m_width = (uint16_t)width;
-				m_height = (uint16_t)height;
-				m_size = m_width * m_height * 2;
-
-				m_mem = (uint8_t*)g_realloc(m_mem, m_size);
-			}
-		}
-
-		void clear(uint8_t _attr = 0)
-		{
-			uint8_t* mem = m_mem;
-			for (uint32_t ii = 0, num = m_size/2; ii < num; ++ii)
-			{
-				mem[0] = 0;
-				mem[1] = _attr;
-				mem += 2;
-			}
-		}
-
-		void printfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
-		{
-			if (_x < m_width && _y < m_height)
-			{
-				char* temp = (char*)alloca(m_width);
-
-				uint32_t num = vsnprintf(temp, m_width, _format, _argList);
-
-				uint8_t* mem = &m_mem[(_y*m_width+_x)*2];
-				for (uint32_t ii = 0, xx = _x; ii < num && xx < m_width; ++ii, ++xx)
-				{
-					mem[0] = temp[ii];
-					mem[1] = _attr;
-					mem += 2;
-				}
-			}
-		}
-
-		void printf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...)
-		{
-			va_list argList;
-			va_start(argList, _format);
-			printfVargs(_x, _y, _attr, _format, argList);
-			va_end(argList);
-		}
-
-		uint8_t* m_mem;
-		uint32_t m_size;
-		uint16_t m_width;
-		uint16_t m_height;
-		bool m_small;
-	};
-
-	struct TextVideoMemBlitter
-	{
-		void init();
-
-		void blit(const TextVideoMem* _mem)
-		{
-			blit(*_mem);
-		}
-
-		void blit(const TextVideoMem& _mem);
-		void setup();
-		void render(uint32_t _numIndices);
-
-		TextureHandle m_texture;
-		TransientVertexBuffer* m_vb;
-		TransientIndexBuffer* m_ib;
-		VertexDecl m_decl;
-		MaterialHandle m_material;
-	};
-
+#include <bx/handlealloc.h>
+#include <bx/hash.h>
+#include <bx/radixsort.h>
+#include <bx/ringbuffer.h>
+#include <bx/uint32_t.h>
+
+#if BX_PLATFORM_WINDOWS
+#	include <windows.h>
+extern HWND g_bgfxHwnd;
+#elif BX_PLATFORM_XBOX360
+#	include <malloc.h>
+#	include <xtl.h>
+#elif BX_PLATFORM_POSIX
+#	include <pthread.h>
+#endif // BX_PLATFORM_*
+
+#ifndef MAKEFOURCC
+#	define MAKEFOURCC(_a, _b, _c, _d) (0 \
+				| ( (uint32_t)(_a) \
+				| ( (uint32_t)(_b) << 8) \
+				| ( (uint32_t)(_c) << 16) \
+				| ( (uint32_t)(_d) << 24) \
+				) )
+#endif // MAKEFOURCC
+
+#include "dds.h"
+
+#define BGFX_MAGIC MAKEFOURCC('B','G','F','X')
+
+#if BGFX_CONFIG_USE_TINYSTL
+
+namespace tinystl
+{
+	struct bgfx_allocator
+	{
+		static void* static_allocate(size_t _bytes);
+		static void static_deallocate(void* _ptr, size_t /*_bytes*/);
+	};
+} // namespace tinystl
+#	define TINYSTL_ALLOCATOR tinystl::bgfx_allocator
+
+#	include <TINYSTL/string.h>
+#	include <TINYSTL/unordered_map.h>
+namespace stl = tinystl;
+#else
+namespace std { namespace tr1 {} using namespace tr1; } // namespace std
+#	include <string>
+#	include <unordered_map>
+namespace stl = std;
+#endif // BGFX_CONFIG_USE_TINYSTL
+#include <list>
+
+#include "config.h"
+
+#if BGFX_CONFIG_MULTITHREADED
+#	include <bx/sem.h>
+#endif // BGFX_CONFIG_MULTITHREADED
+
+#include <bx/cpu.h>
+#include <bx/timer.h>
+
+#define BGFX_DRAW_WHOLE_INDEX_BUFFER 0xffffffff
+
+#define BGFX_DEFAULT_WIDTH  1280
+#define BGFX_DEFAULT_HEIGHT 720
+
+#define BGFX_STATE_TEX0      UINT64_C(0x0100000000000000)
+#define BGFX_STATE_TEX1      UINT64_C(0x0200000000000000)
+#define BGFX_STATE_TEX2      UINT64_C(0x0400000000000000)
+#define BGFX_STATE_TEX3      UINT64_C(0x0800000000000000)
+#define BGFX_STATE_TEX4      UINT64_C(0x1000000000000000)
+#define BGFX_STATE_TEX5      UINT64_C(0x2000000000000000)
+#define BGFX_STATE_TEX6      UINT64_C(0x4000000000000000)
+#define BGFX_STATE_TEX7      UINT64_C(0x8000000000000000)
+#define BGFX_STATE_TEX_MASK  UINT64_C(0xff00000000000000)
+#define BGFX_STATE_TEX_COUNT 8
+
+#define BGFX_SAMPLER_TEXTURE            UINT16_C(0x0000)
+#define BGFX_SAMPLER_RENDERTARGET_COLOR UINT16_C(0x0001)
+#define BGFX_SAMPLER_RENDERTARGET_DEPTH UINT16_C(0x0002)
+#define BGFX_SAMPLER_TYPE_MASK          UINT16_C(0x0003)
+
+#if BGFX_CONFIG_RENDERER_DIRECT3D9
+#	define BGFX_RENDERER_NAME "Direct3D 9"
+#elif BGFX_CONFIG_RENDERER_DIRECT3D11
+#	define BGFX_RENDERER_NAME "Direct3D 11"
+#elif BGFX_CONFIG_RENDERER_OPENGL
+#	define BGFX_RENDERER_NAME "OpenGL"
+#elif BGFX_CONFIG_RENDERER_OPENGLES2
+#	define BGFX_RENDERER_NAME "OpenGL ES 2"
+#endif // BGFX_CONFIG_RENDERER_
+
+namespace bgfx
+{
+	struct Clear
+	{
+		uint32_t m_rgba;
+		float m_depth;
+		uint8_t m_stencil;
+		uint8_t m_flags;
+	};
+
+	struct Rect
+	{
+		uint16_t m_x;
+		uint16_t m_y;
+		uint16_t m_width;
+		uint16_t m_height;
+	};
+
+	extern const uint32_t g_constantTypeSize[ConstantType::Count];
+	extern FatalFn g_fatal;
+	extern ReallocFn g_realloc;
+	extern FreeFn g_free;
+	extern CacheFn g_cache;
+
+	void fatal(Fatal::Enum _code, const char* _format, ...);
+	void release(const Memory* _mem);
+	void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale = false, bool _yflip = false);
+	const char* getAttribName(Attrib::Enum _attr);
+	bool renderFrame();
+
+	inline uint32_t uint16_min(uint16_t _a, uint16_t _b)
+	{
+		return _a > _b ? _b : _a;
+	}
+
+	inline uint32_t uint16_max(uint16_t _a, uint16_t _b)
+	{
+		return _a < _b ? _b : _a;
+	}
+
+	inline uint32_t hash(const void* _data, uint32_t _size)
+	{
+		HashMurmur2A murmur;
+		murmur.begin();
+		murmur.add(_data, (int)_size);
+		return murmur.end();
+	}
+
+	inline uint32_t gcd(uint32_t _a, uint32_t _b)
+	{
+		do
+		{
+			uint32_t tmp = _a % _b;
+			_a = _b;
+			_b = tmp;
+		}
+		while (_b);
+
+		return _a;
+	}
+
+	inline uint32_t lcm(uint32_t _a, uint32_t _b)
+	{
+		return _a * (_b / gcd(_a, _b) );
+	}
+
+	inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride)
+	{
+		const uint32_t mod    = uint32_mod(_offset, _stride);
+		const uint32_t add    = uint32_sub(_stride, mod);
+		const uint32_t mask   = uint32_cmpeq(mod, 0);
+		const uint32_t tmp    = uint32_selb(mask, 0, add);
+		const uint32_t result = uint32_add(_offset, tmp);
+
+		return result;
+	}
+
+	inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride)
+	{
+		uint32_t align = lcm(16, _stride);
+		return _offset+align-(_offset%align);
+	}
+
+	inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride)
+	{
+		uint32_t align = lcm(256, _stride);
+		return _offset+align-(_offset%align);
+	}
+
+	BX_FORCE_INLINE uint32_t castfu(float _value)
+	{
+		union {	float fl; uint32_t ui; } un;
+		un.fl = _value;
+		return un.ui;
+	}
+
+	void dump(const VertexDecl& _decl);
+
+	struct TextVideoMem
+	{
+		TextVideoMem()
+			: m_mem(NULL)
+			, m_size(0)
+			, m_width(0)
+			, m_height(0)
+			, m_small(false)
+		{
+			resize();
+			clear();
+		}
+
+		~TextVideoMem()
+		{
+			g_free(m_mem);
+		}
+
+		void resize(bool _small = false, uint16_t _width = BGFX_DEFAULT_WIDTH, uint16_t _height = BGFX_DEFAULT_HEIGHT)
+		{
+			uint32_t width = uint32_max(1, _width/8);
+			uint32_t height = uint32_max(1, _height/(_small ? 8 : 16) );
+
+			if (NULL == m_mem
+			||  m_width != width
+			||  m_height != height
+			||  m_small != _small)
+			{
+				m_small = _small;
+				m_width = (uint16_t)width;
+				m_height = (uint16_t)height;
+				m_size = m_width * m_height * 2;
+
+				m_mem = (uint8_t*)g_realloc(m_mem, m_size);
+			}
+		}
+
+		void clear(uint8_t _attr = 0)
+		{
+			uint8_t* mem = m_mem;
+			for (uint32_t ii = 0, num = m_size/2; ii < num; ++ii)
+			{
+				mem[0] = 0;
+				mem[1] = _attr;
+				mem += 2;
+			}
+		}
+
+		void printfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
+		{
+			if (_x < m_width && _y < m_height)
+			{
+				char* temp = (char*)alloca(m_width);
+
+				uint32_t num = vsnprintf(temp, m_width, _format, _argList);
+
+				uint8_t* mem = &m_mem[(_y*m_width+_x)*2];
+				for (uint32_t ii = 0, xx = _x; ii < num && xx < m_width; ++ii, ++xx)
+				{
+					mem[0] = temp[ii];
+					mem[1] = _attr;
+					mem += 2;
+				}
+			}
+		}
+
+		void printf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...)
+		{
+			va_list argList;
+			va_start(argList, _format);
+			printfVargs(_x, _y, _attr, _format, argList);
+			va_end(argList);
+		}
+
+		uint8_t* m_mem;
+		uint32_t m_size;
+		uint16_t m_width;
+		uint16_t m_height;
+		bool m_small;
+	};
+
+	struct TextVideoMemBlitter
+	{
+		void init();
+
+		void blit(const TextVideoMem* _mem)
+		{
+			blit(*_mem);
+		}
+
+		void blit(const TextVideoMem& _mem);
+		void setup();
+		void render(uint32_t _numIndices);
+
+		TextureHandle m_texture;
+		TransientVertexBuffer* m_vb;
+		TransientIndexBuffer* m_ib;
+		VertexDecl m_decl;
+		MaterialHandle m_material;
+	};
+
 	struct ClearQuad
 	{
 		void init();
 		void clear(const Rect& _rect, const Clear& _clear);
 
-		TransientVertexBuffer* m_vb;
-		IndexBufferHandle m_ib;
-		VertexDecl m_decl;
+		TransientVertexBuffer* m_vb;
+		IndexBufferHandle m_ib;
+		VertexDecl m_decl;
 		MaterialHandle m_material;
 	};
-
-	struct PredefinedUniform
-	{
-		enum Enum
-		{
-			ViewRect,
-			ViewTexel,
-			View,
-			ViewProj,
-			ViewProjX,
-			Model,
-			ModelViewProj,
-			ModelViewProjX,
-			AlphaRef,
-			Count
-		};
-
-		uint8_t m_type;
-		uint16_t m_loc;
-		uint16_t m_count;
-	};
-
-	const char* getPredefinedUniformName(PredefinedUniform::Enum _enum);
-	PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name);
-
-	class StreamRead
-	{
-	public:
-		StreamRead(const void* _data, uint32_t _size)
-			: m_data( (uint8_t*)_data)
-			, m_size(_size)
-			, m_pos(0)
-		{
-		}
-
-		~StreamRead()
-		{
-		}
-
-		void skip(uint32_t _size)
-		{
-			BX_CHECK(m_size-m_pos >= _size, "Available %d, requested %d.", m_size-m_pos, _size);
-			m_pos += _size;
-		}
-
-		void read(void* _data, uint32_t _size)
-		{
-			BX_CHECK(m_size-m_pos >= _size, "Available %d, requested %d.", m_size-m_pos, _size);
-			memcpy(_data, &m_data[m_pos], _size);
-			m_pos += _size;
-		}
-
-		template<typename Ty>
-		void read(Ty& _value)
-		{
-			read(&_value, sizeof(Ty) );
-		}
-
-		const uint8_t* getDataPtr() const
-		{
-			return &m_data[m_pos];
-		}
-
-		uint32_t getPos() const
-		{
-			return m_pos;
-		}
-
-		void align(uint16_t _align)
-		{
-			m_pos = strideAlign(m_pos, _align);
-		}
-
-		uint32_t remaining() const
-		{
-			return m_size-m_pos;
-		}
-
-	private:
-		const uint8_t* m_data;
-		uint32_t m_size;
-		uint32_t m_pos;
-	};
-
-	class StreamWrite
-	{
-	public:
-		StreamWrite(void* _data, uint32_t _size)
-			: m_data( (uint8_t*)_data)
-			, m_size(_size)
-			, m_pos(0)
-		{
-		}
-
-		~StreamWrite()
-		{
-		}
-
-		void write(void* _data, uint32_t _size)
-		{
-			BX_CHECK(m_size-m_pos >= _size, "Write out of bounds. Available %d, requested %d.", m_size-m_pos, _size);
-			memcpy(&m_data[m_pos], _data, _size);
-			m_pos += _size;
-		}
-
-		template<typename Ty>
-		void write(Ty& _value)
-		{
-			write(&_value, sizeof(Ty) );
-		}
-
-		uint8_t* getDataPtr() const
-		{
-			return &m_data[m_pos];
-		}
-
-		uint32_t getPos() const
-		{
-			return m_pos;
-		}
-
-		void align(uint16_t _align)
-		{
-			m_pos = strideAlign(m_pos, _align);
-		}
-
-	private:
-		uint8_t* m_data;
-		uint32_t m_size;
-		uint32_t m_pos;
-	};
-
-	struct CommandBuffer
-	{
-		CommandBuffer()
-			: m_pos(0)
-			, m_size(BGFX_CONFIG_MAX_COMMAND_BUFFER_SIZE)
-		{
-			finish();
-		}
-
-		enum Enum
-		{
-			RendererInit,
-			CreateVertexDecl,
-			CreateIndexBuffer,
-			CreateVertexBuffer,
-			CreateDynamicIndexBuffer,
-			UpdateDynamicIndexBuffer,
-			CreateDynamicVertexBuffer,
-			UpdateDynamicVertexBuffer,
-			CreateVertexShader,
-			CreateFragmentShader,
-			CreateMaterial,
-			CreateTexture,
-			CreateRenderTarget,
-			CreateUniform,
-			End,
-			RendererShutdown,
-			DestroyVertexDecl,
-			DestroyIndexBuffer,
-			DestroyVertexBuffer,
-			DestroyDynamicIndexBuffer,
-			DestroyDynamicVertexBuffer,
-			DestroyVertexShader,
-			DestroyFragmentShader,
-			DestroyMaterial,
-			DestroyTexture,
-			DestroyRenderTarget,
-			DestroyUniform,
-			SaveScreenShot,
-		};
-
-		void write(const void* _data, uint32_t _size)
-		{
-			BX_CHECK(m_pos < m_size, "");
-			memcpy(&m_buffer[m_pos], _data, _size);
-			m_pos += _size;
-		}
-
-		template<typename Type>
-		void write(const Type& _in)
-		{
-			write(reinterpret_cast<const uint8_t*>(&_in), sizeof(Type) );
-		}
-
-		void read(void* _data, uint32_t _size)
-		{
-			BX_CHECK(m_pos < m_size, "");
-			memcpy(_data, &m_buffer[m_pos], _size);
-			m_pos += _size;
-		}
-
-		template<typename Type>
-		void read(Type& _in)
-		{
-			read(reinterpret_cast<uint8_t*>(&_in), sizeof(Type) );
-		}
-
-		void reset()
-		{
-			m_pos = 0;
-		}
-
-		void finish()
-		{
-			uint8_t cmd = End;
-			write(cmd);
-			m_pos = 0;
-		}
-
-		uint32_t m_pos;
-		uint32_t m_size;
-		uint8_t m_buffer[BGFX_CONFIG_MAX_COMMAND_BUFFER_SIZE];
-
-	private:
-		CommandBuffer(const CommandBuffer&);
-		void operator=(const CommandBuffer&);
-	};
-
-	struct SortKey
-	{
-		uint64_t encode()
-		{
-			// |               3               2               1               0|
-			// |fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210|
-			// |             vvvvvsssssssssssttmmmmmmmmmdddddddddddddddddddddddd|
-			// |                 ^          ^ ^        ^                       ^|
-			// |                 |          | |        |                       ||
-
-			uint64_t tmp0 = m_depth;
-			uint64_t tmp1 = uint64_t(m_material)<<0x18;
-			uint64_t tmp2 = uint64_t(m_trans)<<0x21;
-			uint64_t tmp3 = uint64_t(m_seq)<<0x23;
-			uint64_t tmp4 = uint64_t(m_view)<<0x2e;
-			uint64_t key = tmp0|tmp1|tmp2|tmp3|tmp4;
-			return key;
-		}
-
-		void decode(uint64_t _key)
-		{
-			m_depth = _key&0xffffffff;
-			m_material = (_key>>0x18)&(BGFX_CONFIG_MAX_MATERIALS-1);
-			m_trans = (_key>>0x21)&0x3;
-			m_seq = (_key>>0x23)&0x7ff;
-			m_view = (_key>>0x2e)&(BGFX_CONFIG_MAX_VIEWS-1);
-		}
-
-		void reset()
-		{
-			m_depth = 0;
-			m_material = 0;
-			m_seq = 0;
-			m_view = 0;
-			m_trans = 0;
-		}
-
-		int32_t m_depth;
-		uint16_t m_material;
-		uint16_t m_seq;
-		uint8_t m_view;
-		uint8_t m_trans;
-	};
-
-	BX_ALIGN_STRUCT_16(struct) Matrix4
-	{
-		float val[16];
-
-		void setIdentity()
-		{
-			memset(val, 0, sizeof(val) );
-			val[0] = val[5] = val[10] = val[15] = 1.0f;
-		}
-	};
-
-	void matrix_mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
-	void matrix_ortho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far);
-
-	struct MatrixCache
-	{
-		MatrixCache()
-			: m_num(1)
-		{
-			m_cache[0].setIdentity();
-		}
-
-		void reset()
-		{
-			m_num = 1;
-		}
-
-		uint32_t add(const void* _mtx, uint16_t _num)
-		{
-			if (NULL != _mtx)
-			{
-				BX_CHECK(m_num+_num < BGFX_CONFIG_MAX_MATRIX_CACHE, "Matrix cache overflow. %d (max: %d)", m_num+_num, BGFX_CONFIG_MAX_MATRIX_CACHE);
-
-				uint32_t num = uint32_min(BGFX_CONFIG_MAX_MATRIX_CACHE-m_num, _num);
-				uint32_t first = m_num;
-				memcpy(&m_cache[m_num], _mtx, sizeof(Matrix4)*num);
-				m_num += num;
-				return first;
-			}
-
-			return 0;
-		}
-
-		Matrix4 m_cache[BGFX_CONFIG_MAX_MATRIX_CACHE];
-		uint32_t m_num;
-	};
-
-	struct Sampler
-	{
-		uint16_t m_idx;
-		uint16_t m_flags;
-	};
-	
-	struct Constant
-	{
-		ConstantType::Enum m_type;
-		uint16_t m_num;
-	};
-
-#define CONSTANT_OPCODE_MASK(_bits) ( (1<<_bits)-1)
-
-#define CONSTANT_OPCODE_TYPE_BITS 8
-#define CONSTANT_OPCODE_TYPE_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_TYPE_BITS)
-#define CONSTANT_OPCODE_LOC_BITS 10
-#define CONSTANT_OPCODE_LOC_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_LOC_BITS)
-#define CONSTANT_OPCODE_NUM_BITS 10
-#define CONSTANT_OPCODE_NUM_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_NUM_BITS)
-#define CONSTANT_OPCODE_COPY_BITS 1
-#define CONSTANT_OPCODE_COPY_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_COPY_BITS)
-
-#define BGFX_UNIFORM_FUNCTIONBIT UINT8_C(0x40)
-#define BGFX_UNIFORM_FRAGMENTBIT UINT8_C(0x80)
-#define BGFX_UNIFORM_TYPEMASK    UINT8_C(0x3f)
-
-	class ConstantBuffer
-	{
-	public:
-		static ConstantBuffer* create(uint32_t _size)
-		{
-			uint32_t size = BX_ALIGN_16(uint32_max(_size, sizeof(ConstantBuffer) ) );
-			void* data = g_realloc(NULL, size);
-			return ::new(data) ConstantBuffer(_size);
-		}
-
-		static void destroy(ConstantBuffer* _constantBuffer)
-		{
-			_constantBuffer->~ConstantBuffer();
-			g_free(_constantBuffer);
-		}
-
-		static uint32_t encodeOpcode(ConstantType::Enum _type, uint16_t _loc, uint16_t _num, uint16_t _copy)
-		{
-			uint32_t opcode = 0;
-
-			opcode <<= CONSTANT_OPCODE_TYPE_BITS;
-			opcode |= _type&CONSTANT_OPCODE_TYPE_MASK;
-
-			opcode <<= CONSTANT_OPCODE_LOC_BITS;
-			opcode |= _loc&CONSTANT_OPCODE_LOC_MASK;
-
-			opcode <<= CONSTANT_OPCODE_NUM_BITS;
-			opcode |= _num&CONSTANT_OPCODE_NUM_MASK;
-
-			opcode <<= CONSTANT_OPCODE_COPY_BITS;
-			opcode |= _copy&CONSTANT_OPCODE_COPY_MASK;
-
-			return opcode;
-		}
-
-		static void decodeOpcode(uint32_t _opcode, ConstantType::Enum& _type, uint16_t& _loc, uint16_t& _num, uint16_t& _copy)
-		{
-			uint32_t copy;
-			uint32_t num;
-			uint32_t loc;
-
-			copy = _opcode&CONSTANT_OPCODE_COPY_MASK;
-			_opcode >>= CONSTANT_OPCODE_COPY_BITS;
-
-			num = _opcode&CONSTANT_OPCODE_NUM_MASK;
-			_opcode >>= CONSTANT_OPCODE_NUM_BITS;
-
-			loc = _opcode&CONSTANT_OPCODE_LOC_MASK;
-			_opcode >>= CONSTANT_OPCODE_LOC_BITS;
-
-			_type = (ConstantType::Enum)(_opcode&CONSTANT_OPCODE_TYPE_MASK);
-			_opcode >>= CONSTANT_OPCODE_TYPE_BITS;
-
-			_copy = (uint16_t)copy;
-			_num = (uint16_t)num;
-			_loc = (uint16_t)loc;
-		}
-
-		void write(const void* _data, uint32_t _size)
-		{
-			BX_CHECK(m_pos + _size < m_size, "Write would go out of bounds. pos %d + size %d > max size: %d).", m_pos, _size, m_size);
-
-			if (m_pos + _size < m_size)
-			{
-				memcpy(&m_buffer[m_pos], _data, _size);
-				m_pos += _size;
-			}
-		}
-
-		void write(uint32_t _value)
-		{
-			write(&_value, sizeof(uint32_t) );
-		}
-
-		const char* read(uint32_t _size)
-		{
-			BX_CHECK(m_pos < m_size, "Out of bounds %d (size: %d).", m_pos, m_size);
-			const char* result = &m_buffer[m_pos];
-			m_pos += _size;
-			return result;
-		}
-
-		uint32_t read()
-		{
-			const char* result = read(sizeof(uint32_t) );
-			return *( (uint32_t*)result);
-		}
-
-		bool isEmpty() const
-		{
-			return 0 == m_pos;
-		}
-
-		uint32_t getPos() const
-		{
-			return m_pos;
-		}
-
-		void reset(uint32_t _pos = 0)
-		{
-			m_pos = _pos;
-		}
-
-		void finish()
-		{
-			write(ConstantType::End);
-			m_pos = 0;
-		}
-
-		void writeUniform(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
-		void writeUniformRef(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
-		void commit();
-
-	private:
-		ConstantBuffer(uint32_t _size)
-			: m_size(_size-sizeof(m_buffer) )
-			, m_pos(0)
-		{
-			BX_TRACE("ConstantBuffer %d, %d", _size, m_size);
-			finish();
-		}
-
-		~ConstantBuffer()
-		{
-		}
-
-		uint32_t m_size;
-		uint32_t m_pos;
-		char m_buffer[8];
-	};
-
-	typedef const void* (*UniformFn)(const void* _data);
-
-	struct UniformInfo
-	{
-		const void* m_data;
-		UniformFn m_func;
-	};
-
- 	class UniformRegistry
- 	{
-	public:
-		UniformRegistry()
-		{
-		}
-
-		~UniformRegistry()
-		{
-		}
- 
- 		const UniformInfo* find(const char* _name) const
- 		{
-			UniformHashMap::const_iterator it = m_uniforms.find(_name);
-			if (it != m_uniforms.end() )
-			{
-				return &it->second;
-			}
-
- 			return NULL;
- 		}
-
-		const UniformInfo& reg(const char* _name, const void* _data, UniformFn _func = NULL)
-		{
-			UniformHashMap::const_iterator it = m_uniforms.find(_name);
-			if (it == m_uniforms.end() )
-			{
-				UniformInfo info;
-				info.m_data = _data;
-				info.m_func = _func;
-
-				stl::pair<UniformHashMap::iterator, bool> result = m_uniforms.insert(UniformHashMap::value_type(_name, info) );
-				return result.first->second;	
-			}
-
-			return it->second;
-		}
-
- 	private:
- 		typedef stl::unordered_map<stl::string, UniformInfo> UniformHashMap;
- 		UniformHashMap m_uniforms;
- 	};
-
-	struct RenderState
-	{
-		void reset()
-		{
-			m_constEnd = 0;
-			clear();
-		}
-
-		void clear()
-		{
-			m_constBegin = m_constEnd;
-			m_flags = BGFX_STATE_DEFAULT;
-			m_matrix = 0;
-			m_startIndex = BGFX_DRAW_WHOLE_INDEX_BUFFER;
-			m_numIndices = 0;
-			m_startVertex = 0;
-			m_numVertices = UINT32_C(0xffffffff);
-			m_instanceDataOffset = 0;
-			m_instanceDataStride = 0;
-			m_numInstances = 1;
-			m_num = 1;
-			m_vertexBuffer.idx = invalidHandle;
-			m_vertexDecl.idx = invalidHandle;
-			m_indexBuffer.idx = invalidHandle;
-			m_instanceDataBuffer.idx = invalidHandle;
-			
-			for (uint32_t ii = 0; ii < BGFX_STATE_TEX_COUNT; ++ii)
-			{
-				m_sampler[ii].m_idx = invalidHandle;
-				m_sampler[ii].m_flags = BGFX_SAMPLER_TEXTURE;
-			}
-		}
-
-		uint64_t m_flags;
-		uint32_t m_constBegin;
-		uint32_t m_constEnd;
-		uint32_t m_matrix;
-		uint32_t m_startIndex;
-		uint32_t m_numIndices;
-		uint32_t m_startVertex;
-		uint32_t m_numVertices;
-		uint32_t m_instanceDataOffset;
-		uint16_t m_instanceDataStride;
-		uint16_t m_numInstances;
-		uint16_t m_num;
-
-		VertexBufferHandle m_vertexBuffer;
-		VertexDeclHandle m_vertexDecl;
-		IndexBufferHandle m_indexBuffer;
-		VertexBufferHandle m_instanceDataBuffer;
-		Sampler m_sampler[BGFX_STATE_TEX_COUNT];
-	};
-
-	struct Resolution
-	{
-		Resolution()
-			: m_width(BGFX_DEFAULT_WIDTH)
-			, m_height(BGFX_DEFAULT_HEIGHT)
-			, m_flags(BGFX_RESET_NONE)
-		{
-		}
-
-		uint32_t m_width;
-		uint32_t m_height;
-		uint32_t m_flags;
-	};
-
-	struct DynamicIndexBuffer
-	{
-		IndexBufferHandle m_handle;
-		uint32_t m_offset;
-		uint32_t m_size;
-	};
-
-	struct DynamicVertexBuffer
-	{
-		VertexBufferHandle m_handle;
-		uint32_t m_offset;
-		uint32_t m_size;
-		uint32_t m_startVertex;
-		uint32_t m_numVertices;
-		uint32_t m_stride;
-		VertexDeclHandle m_decl;
-	};
-
-	struct Frame
-	{
-		BX_CACHE_LINE_ALIGN_MARKER();
-
-		Frame()
-		{
-		}
-
-		~Frame()
-		{
-		}
-
-		void create()
-		{
-			m_constantBuffer = ConstantBuffer::create(BGFX_CONFIG_MAX_CONSTANT_BUFFER_SIZE);
-			reset();
-			m_textVideoMem = new TextVideoMem;
-		}
-
-		void destroy()
-		{
-			ConstantBuffer::destroy(m_constantBuffer);
-			delete m_textVideoMem;
-		}
-
-		void reset()
-		{
-			m_state.reset();
-			m_matrixCache.reset();
-			m_key.reset();
-			m_num = 0;
-			m_numRenderStates = 0;
-			m_numDropped = 0;
-			m_iboffset = 0;
-			m_vboffset = 0;
-			m_cmdPre.reset();
-			m_cmdPost.reset();
-			m_constantBuffer->reset();
-			m_discard = false;
-			resetFreeHandles();
-		}
-
-		void finish()
-		{
-			m_cmdPre.finish();
-			m_cmdPost.finish();
-			m_constantBuffer->finish();
-
-			if (0 < m_numDropped)
-			{
-				BX_TRACE("Too many draw calls: %d, dropped %d (max: %d)", m_num+m_numDropped, m_numDropped, BGFX_CONFIG_MAX_DRAW_CALLS);
-			}
-		}
-
-		void setViewTransform(uint8_t _id, const void* _view, const void* _proj, uint8_t _other)
-		{
-			if (BGFX_CONFIG_MAX_VIEWS > _other)
-			{
-				m_other[_id] = _other;
-			}
-			else
-			{
-				m_other[_id] = _id;
-			}
-
-			if (NULL != _view)
-			{
-				memcpy(m_view[_id].val, _view, sizeof(Matrix4) );
-			}
-			else
-			{
-				m_view[_id].setIdentity();
-			}
-
-			if (NULL != _proj)
-			{
-				memcpy(m_proj[_id].val, _proj, sizeof(Matrix4) );
-			}
-			else
-			{
-				m_view[_id].setIdentity();
-			}
-		}
-
-		void setViewTransformMask(uint32_t _viewMask, const void* _view, const void* _proj, uint8_t _other)
-		{
-			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
-			{
-				viewMask >>= ntz;
-				id += ntz;
-
-				setViewTransform(id, _view, _proj, _other);
-			}
-		}
-
-		void setState(uint64_t _state)
-		{
-			uint8_t blend = ( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT)&0xff;
-			m_key.m_trans = "\x0\x1\x1\x2\x2\x1\x2\x1\x2\x1\x1\x1\x1\x1\x1\x1\x1"[( (blend)&0xf) + (!!blend)];
-			m_state.m_flags = _state;
-		}
-
-		uint32_t setTransform(const void* _mtx, uint16_t _num)
-		{
-			m_state.m_matrix = m_matrixCache.add(_mtx, _num);
-			m_state.m_num = _num;
-
-			return m_state.m_matrix;
-		}
-
-		void setTransform(uint32_t _cache, uint16_t _num)
-		{
-			m_state.m_matrix = _cache;
-			m_state.m_num = _num;
-		}
-
-		void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
-		{
-			m_state.m_startIndex = _firstIndex;
-			m_state.m_numIndices = _numIndices;
-			m_state.m_indexBuffer = _handle;
-		}
-
-		void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices)
-		{
-			m_state.m_indexBuffer = _ib->handle;
-			m_state.m_startIndex = _ib->startIndex;
-			m_state.m_numIndices = _numIndices;
-			m_discard = 0 == _numIndices;
-			g_free(const_cast<TransientIndexBuffer*>(_ib) );
-		}
-
-		void setVertexBuffer(VertexBufferHandle _handle)
-		{
-			BX_CHECK(_handle.idx < BGFX_CONFIG_MAX_VERTEX_BUFFERS, "Invalid vertex buffer handle. %d (< %d)", _handle.idx, BGFX_CONFIG_MAX_VERTEX_BUFFERS);
-			m_state.m_startVertex = 0;
-			m_state.m_numVertices = UINT32_C(0xffffffff);
-			m_state.m_vertexBuffer = _handle;
-		}
-
-		void setVertexBuffer(const DynamicVertexBuffer& dvb)
-		{
-			m_state.m_startVertex = dvb.m_startVertex;
-			m_state.m_numVertices = dvb.m_numVertices;
-			m_state.m_vertexBuffer = dvb.m_handle;
-			m_state.m_vertexDecl = dvb.m_decl;
-		}
-
-		void setVertexBuffer(const TransientVertexBuffer* _vb)
-		{
-			m_state.m_startVertex = _vb->startVertex;
-			m_state.m_numVertices = _vb->size/_vb->stride;
-			m_state.m_vertexBuffer = _vb->handle;
-			m_state.m_vertexDecl = _vb->decl;
-			g_free(const_cast<TransientVertexBuffer*>(_vb) );
-		}
-
-		void setInstanceDataBuffer(const InstanceDataBuffer* _idb)
-		{
-#if BGFX_CONFIG_RENDERER_OPENGLES2
-#else
- 			m_state.m_instanceDataOffset = _idb->offset;
-			m_state.m_instanceDataStride = _idb->stride;
-			m_state.m_numInstances = _idb->num;
-			m_state.m_instanceDataBuffer = _idb->handle;
-			g_free(const_cast<InstanceDataBuffer*>(_idb) );
-#endif // BGFX_CONFIG_RENDERER_OPENGLES
-		}
-
-		void setMaterial(MaterialHandle _handle)
-		{
-			BX_CHECK(invalidHandle != _handle.idx, "Can't set material with invalid handle.");
-			m_key.m_material = _handle.idx;
-		}
-
-		void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle)
-		{
-			m_flags |= BGFX_STATE_TEX0<<_stage;
-			Sampler& sampler = m_state.m_sampler[_stage];
-			sampler.m_idx = _handle.idx;
-			sampler.m_flags = BGFX_SAMPLER_TEXTURE;
-
-			if (invalidHandle != _sampler.idx)
-			{
-				uint32_t stage = _stage;
-				setUniform(_sampler, &stage);
-			}
-		}
-
-		void setTexture(uint8_t _stage, UniformHandle _sampler, RenderTargetHandle _handle, bool _depth)
-		{
-			m_flags |= BGFX_STATE_TEX0<<_stage;
-			Sampler& sampler = m_state.m_sampler[_stage];
-			sampler.m_idx = _handle.idx;
-			sampler.m_flags = _depth ? BGFX_SAMPLER_RENDERTARGET_DEPTH : BGFX_SAMPLER_RENDERTARGET_COLOR;
-
-			if (invalidHandle != _sampler.idx)
-			{
-				uint32_t stage = _stage;
-				setUniform(_sampler, &stage);
-			}
-		}
-
-		void submit(uint8_t _id);
-		void submitMask(uint32_t _viewMask);
-		void sort();
-
-		bool checkAvailTransientIndexBuffer(uint16_t _num)
-		{
-			uint32_t offset = m_iboffset;
-			uint32_t iboffset = offset + _num*sizeof(uint16_t);
-			iboffset = uint32_min(iboffset, BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
-			uint32_t num = (iboffset-offset)/sizeof(uint16_t);
-			return num == _num;
-		}
-
-		uint32_t allocTransientIndexBuffer(uint16_t& _num)
-		{
-			uint32_t offset = m_iboffset;
-			m_iboffset = offset + _num*sizeof(uint16_t);
-			m_iboffset = uint32_min(m_iboffset, BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
-			_num = uint16_t( (m_iboffset-offset)/sizeof(uint16_t) );
-			return offset;
-		}
-
-		bool checkAvailTransientVertexBuffer(uint16_t _num, uint16_t _stride)
-		{
-			uint32_t offset = strideAlign(m_vboffset, _stride);
-			uint32_t vboffset = offset + _num * _stride;
-			vboffset = uint32_min(vboffset, BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
-			uint32_t num = (vboffset-offset)/_stride;
-			return num == _num;
-		}
-
-		uint32_t allocTransientVertexBuffer(uint16_t& _num, uint16_t _stride)
-		{
-			uint32_t offset = strideAlign(m_vboffset, _stride);
-			m_vboffset = offset + _num * _stride;
-			m_vboffset = uint32_min(m_vboffset, BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
-			_num = uint16_t( (m_vboffset-offset)/_stride);
-			return offset;
-		}
-
-		void writeConstant(ConstantType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num)
-		{
-			m_constantBuffer->writeUniform(_type, _handle.idx, _value, _num);
-		}
-
-		void free(IndexBufferHandle _handle)
-		{
-			m_freeIndexBufferHandle[m_numFreeIndexBufferHandles] = _handle;
-			++m_numFreeIndexBufferHandles;
-		}
-
-		void free(VertexDeclHandle _handle)
-		{
-			m_freeVertexDeclHandle[m_numFreeVertexDeclHandles] = _handle;
-			++m_numFreeVertexDeclHandles;
-		}
-
-		void free(VertexBufferHandle _handle)
-		{
-			m_freeVertexBufferHandle[m_numFreeVertexBufferHandles] = _handle;
-			++m_numFreeVertexBufferHandles;
-		}
-
-		void free(VertexShaderHandle _handle)
-		{
-			m_freeVertexShaderHandle[m_numFreeVertexShaderHandles] = _handle;
-			++m_numFreeVertexShaderHandles;
-		}
-
-		void free(FragmentShaderHandle _handle)
-		{
-			m_freeFragmentShaderHandle[m_numFreeFragmentShaderHandles] = _handle;
-			++m_numFreeFragmentShaderHandles;
-		}
-
-		void free(MaterialHandle _handle)
-		{
-			m_freeMaterialHandle[m_numFreeMaterialHandles] = _handle;
-			++m_numFreeMaterialHandles;
-		}
-
-		void free(TextureHandle _handle)
-		{
-			m_freeTextureHandle[m_numFreeTextureHandles] = _handle;
-			++m_numFreeTextureHandles;
-		}
-
-		void free(RenderTargetHandle _handle)
-		{
-			m_freeRenderTargetHandle[m_numFreeRenderTargetHandles] = _handle;
-			++m_numFreeRenderTargetHandles;
-		}
-
-		void free(UniformHandle _handle)
-		{
-			m_freeUniformHandle[m_numFreeUniformHandles] = _handle;
-			++m_numFreeUniformHandles;
-		}
-
-		void resetFreeHandles()
-		{
-			m_numFreeIndexBufferHandles = 0;
-			m_numFreeVertexDeclHandles = 0;
-			m_numFreeVertexBufferHandles = 0;
-			m_numFreeVertexShaderHandles = 0;
-			m_numFreeFragmentShaderHandles = 0;
-			m_numFreeFragmentShaderHandles = 0;
-			m_numFreeMaterialHandles = 0;
-			m_numFreeTextureHandles = 0;
-			m_numFreeRenderTargetHandles = 0;
-			m_numFreeUniformHandles = 0;
-		}
-
-		SortKey m_key;
-
-		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
-		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
-		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
-		Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
-		Matrix4 m_proj[BGFX_CONFIG_MAX_VIEWS];
-		uint8_t m_other[BGFX_CONFIG_MAX_VIEWS];
-
-		uint64_t m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS];
-		uint16_t m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS];
-		RenderState m_renderState[BGFX_CONFIG_MAX_DRAW_CALLS];
-		RenderState m_state;
-		uint64_t m_flags;
-
-		ConstantBuffer* m_constantBuffer;
-
-		uint16_t m_num;
-		uint16_t m_numRenderStates;
-		uint16_t m_numDropped;
-
-		MatrixCache m_matrixCache;
-
-		uint32_t m_iboffset;
-		uint32_t m_vboffset;
-		TransientIndexBuffer* m_transientIb;
-		TransientVertexBuffer* m_transientVb;
-
-		Resolution m_resolution;
-		uint32_t m_debug;
-
-		CommandBuffer m_cmdPre;
-		CommandBuffer m_cmdPost;
-
-		uint16_t m_numFreeIndexBufferHandles;
-		uint16_t m_numFreeVertexDeclHandles;
-		uint16_t m_numFreeVertexBufferHandles;
-		uint16_t m_numFreeVertexShaderHandles;
-		uint16_t m_numFreeFragmentShaderHandles;
-		uint16_t m_numFreeMaterialHandles;
-		uint16_t m_numFreeTextureHandles;
-		uint16_t m_numFreeRenderTargetHandles;
-		uint16_t m_numFreeUniformHandles;
-
-		IndexBufferHandle m_freeIndexBufferHandle[BGFX_CONFIG_MAX_INDEX_BUFFERS];
-		VertexDeclHandle m_freeVertexDeclHandle[BGFX_CONFIG_MAX_VERTEX_DECLS];
-		VertexBufferHandle m_freeVertexBufferHandle[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
-		VertexShaderHandle m_freeVertexShaderHandle[BGFX_CONFIG_MAX_VERTEX_SHADERS];
-		FragmentShaderHandle m_freeFragmentShaderHandle[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
-		MaterialHandle m_freeMaterialHandle[BGFX_CONFIG_MAX_MATERIALS];
-		TextureHandle m_freeTextureHandle[BGFX_CONFIG_MAX_TEXTURES];
-		RenderTargetHandle m_freeRenderTargetHandle[BGFX_CONFIG_MAX_RENDER_TARGETS];
-		UniformHandle m_freeUniformHandle[BGFX_CONFIG_MAX_UNIFORMS];
-		TextVideoMem* m_textVideoMem;
-
-		int64_t m_waitSubmit;
-		int64_t m_waitRender;
-
-		bool m_discard;
-	};
-
-	struct MaterialRef
-	{
-		MaterialRef()
-		{
-		}
-
-		MaterialHandle find(uint32_t _hash)
-		{
-			MaterialMap::const_iterator it = m_materialMap.find(_hash);
-			if (it != m_materialMap.end() )
-			{
-				return it->second;
-			}
-
-			MaterialHandle result = BGFX_INVALID_HANDLE;
-			return result;
-		}
-
-		void add(MaterialHandle _handle, uint32_t _hash)
-		{
-			m_materialMap.insert(stl::make_pair(_hash, _handle) );
-		}
-
-		typedef stl::unordered_map<uint32_t, MaterialHandle> MaterialMap;
-		MaterialMap m_materialMap;
-	};
-
-	struct VertexDeclRef
-	{
-		VertexDeclRef()
-		{
-			memset(m_vertexDeclRef, 0, sizeof(m_vertexDeclRef) );
-			memset(m_vertexBufferRef, 0xff, sizeof(m_vertexBufferRef) );
-		}
-
-		VertexDeclHandle find(uint32_t _hash)
-		{
-			VertexDeclMap::const_iterator it = m_vertexDeclMap.find(_hash);
-			if (it != m_vertexDeclMap.end() )
-			{
-				return it->second;
-			}
-
-			VertexDeclHandle result = BGFX_INVALID_HANDLE;
-			return result;
-		}
-
-		void add(VertexBufferHandle _handle, VertexDeclHandle _declHandle, uint32_t _hash)
-		{
-			m_vertexBufferRef[_handle.idx] = _declHandle;
-			m_vertexDeclRef[_declHandle.idx]++;
-			m_vertexDeclMap.insert(stl::make_pair(_hash, _declHandle) );
-		}
-
-		VertexDeclHandle release(VertexBufferHandle _handle)
-		{
-			VertexDeclHandle declHandle = m_vertexBufferRef[_handle.idx];
-			m_vertexDeclRef[declHandle.idx]--;
-
-			if (0 != m_vertexDeclRef[declHandle.idx])
-			{
-				VertexDeclHandle invalid = BGFX_INVALID_HANDLE;
-				return invalid;
-			}
-
-			return declHandle;
-		}
-
-		typedef stl::unordered_map<uint32_t, VertexDeclHandle> VertexDeclMap;
-		VertexDeclMap m_vertexDeclMap;
-		uint16_t m_vertexDeclRef[BGFX_CONFIG_MAX_VERTEX_DECLS];
-		VertexDeclHandle m_vertexBufferRef[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
-	};
-
-	// First-fit non-local allocator.
-	class NonLocalAllocator
-	{
-	public:
-		static const uint64_t invalidBlock = UINT64_MAX;
-
-		NonLocalAllocator()
-		{
-		}
-
-		~NonLocalAllocator()
-		{
-		}
-
-		void reset()
-		{
-			m_free.clear();
-			m_used.clear();
-		}
-
-		void add(uint64_t _ptr, uint32_t _size)
-		{
-			m_free.push_back(Free(_ptr, _size) );
-		}
-
-		uint64_t alloc(uint32_t _size)
-		{
-			for (FreeList::iterator it = m_free.begin(), itEnd = m_free.end(); it != itEnd; ++it)
-			{
-				if (it->m_size >= _size)
-				{
-					uint64_t ptr = it->m_ptr;
-
-					m_used.insert(stl::make_pair(ptr, _size) );
-
-					if (it->m_size != _size)
-					{
-						it->m_size -= _size;
-						it->m_ptr += _size;
-					}
-					else
-					{
-						m_free.erase(it);
-					}
-
-					return ptr;
-				}
-			}
-
-			// there is no block large enough.
-			return invalidBlock;
-		}
-
-		void free(uint64_t _block)
-		{
-			UsedList::iterator it = m_used.find(_block);
-			if (it != m_used.end() )
-			{
-				m_free.push_front(Free(it->first, it->second) );
-				m_used.erase(it);
-			}
-		}
-
-		void compact()
-		{
-			m_free.sort();
-
-			for (FreeList::iterator it = m_free.begin(), next = it, itEnd = m_free.end(); next != itEnd;)
-			{
-				if ( (it->m_ptr + it->m_size) == next->m_ptr)
-				{
-					it->m_size += next->m_size;
-					next = m_free.erase(next);
-				}
-				else
-				{
-					it = next;
-					++next;
-				}
-			}
-		}
-
-	private:
-		struct Free
-		{
-			Free(uint64_t _ptr, uint32_t _size)
-				: m_ptr(_ptr)
-				, m_size(_size)
-			{
-			}
-
-			bool operator<(const Free& rhs) const
-			{
-				return m_ptr < rhs.m_ptr;
-			}
-
-			uint64_t m_ptr;
-			uint32_t m_size;
-		};
-
-		typedef std::list<Free> FreeList;
-		FreeList m_free;
-
-		typedef stl::unordered_map<uint64_t, uint32_t> UsedList;
-		UsedList m_used;
-	};
-
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
-	DWORD WINAPI renderThread(LPVOID _arg);
-#elif BX_PLATFORM_LINUX
-	void* renderThread(void*);
-#endif // BX_PLATFORM_
-
-	struct Context
-	{
-		Context()
-			: m_render(&m_frame[0])
-			, m_submit(&m_frame[1])
-			, m_dynamicIndexBufferHandle(BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS)
-			, m_dynamicVertexBufferHandle(BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS)
-			, m_indexBufferHandle(BGFX_CONFIG_MAX_INDEX_BUFFERS)
-			, m_vertexDeclHandle(BGFX_CONFIG_MAX_VERTEX_DECLS)
-			, m_vertexBufferHandle(BGFX_CONFIG_MAX_VERTEX_BUFFERS)
-			, m_vertexShaderHandle(BGFX_CONFIG_MAX_VERTEX_SHADERS)
-			, m_fragmentShaderHandle(BGFX_CONFIG_MAX_FRAGMENT_SHADERS)
-			, m_materialHandle(BGFX_CONFIG_MAX_MATERIALS)
-			, m_textureHandle(BGFX_CONFIG_MAX_TEXTURES)
-			, m_renderTargetHandle(BGFX_CONFIG_MAX_RENDER_TARGETS)
-			, m_uniformHandle(BGFX_CONFIG_MAX_UNIFORMS)
-			, m_frames(0)
-			, m_debug(BGFX_DEBUG_NONE)
-			, m_rendererInitialized(false)
-			, m_exit(false)
-		{
-		}
-
-		~Context()
-		{
-		}
-
-		// game thread
-		void init(bool _createRenderThread);
-		void shutdown();
-
-		void frame()
-		{
-#if BX_PLATFORM_WINDOWS
-			m_window.update();
-#endif // BX_PLATFORM_WINDOWS
-
-			// wait for render thread to finish
-			renderSemWait();
-
-			swap();
-
-			// release render thread
-			gameSemPost();
-
-#if !BGFX_CONFIG_MULTITHREADED
-			renderFrame();
-#endif // BGFX_CONFIG_MULTITHREADED
-		}
-
-		CommandBuffer& getCommandBuffer(CommandBuffer::Enum _cmd)
-		{
-			CommandBuffer& cmdbuf = _cmd < CommandBuffer::End ? m_submit->m_cmdPre : m_submit->m_cmdPost;
-			uint8_t cmd = (uint8_t)_cmd;
-			cmdbuf.write(cmd);
-			return cmdbuf;
-		}
-
-		void reset(uint32_t _width, uint32_t _height, uint32_t _flags)
-		{
-			m_resolution.m_width = _width;
-			m_resolution.m_height = _height;
-			m_resolution.m_flags = _flags&(~BGFX_RESET_FULLSCREEN_FAKE);
-
-			memset(m_rt, 0xff, sizeof(m_rt) );
-
-#if BX_PLATFORM_WINDOWS
-			uint32_t fullscreen = (_flags&BGFX_RESET_FULLSCREEN_MASK)>>BGFX_RESET_FULLSCREEN_SHIFT;
-			m_window.adjust(_width, _height, BGFX_RESET_FULLSCREEN_FAKE != fullscreen);
-#endif // BX_PLATFORM_WINDOWS
-		}
-
-		void dbgTextClear(uint8_t _attr, bool _small)
-		{
-			m_submit->m_textVideoMem->resize(_small, m_resolution.m_width, m_resolution.m_height);
-			m_submit->m_textVideoMem->clear(_attr);
-		}
-
-		void dbgTextPrintfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
-		{
-			m_submit->m_textVideoMem->printfVargs(_x, _y, _attr, _format, _argList);
-		}
-
-		IndexBufferHandle createIndexBuffer(const Memory* _mem)
-		{
-			IndexBufferHandle handle = { m_indexBufferHandle.alloc() };
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateIndexBuffer);
-			cmdbuf.write(handle);
-			cmdbuf.write(_mem);
-			return handle;
-		}
-
-		void destroyIndexBuffer(IndexBufferHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyIndexBuffer);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		VertexDeclHandle findVertexDecl(const VertexDecl& _decl)
-		{
-			VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash);
-
-			if (invalidHandle == declHandle.idx)
-			{
-				VertexDeclHandle temp = { m_vertexDeclHandle.alloc() };
-				declHandle = temp;
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexDecl);
-				cmdbuf.write(declHandle);
-				cmdbuf.write(_decl);
-			}
-
-			return declHandle;
-		}
-
-		VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
-		{
-			VertexBufferHandle handle = { m_vertexBufferHandle.alloc() };
-
-			VertexDeclHandle declHandle = findVertexDecl(_decl);
-			m_declRef.add(handle, declHandle, _decl.m_hash);
-
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexBuffer);
-			cmdbuf.write(handle);
-			cmdbuf.write(_mem);
-			cmdbuf.write(declHandle);
-			return handle;
-		}
-
-		void destroyVertexBuffer(VertexBufferHandle _handle)
-		{
-			VertexDeclHandle declHandle = m_declRef.release(_handle);
-			if (invalidHandle != declHandle.idx)
-			{
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexDecl);
-				cmdbuf.write(declHandle);
-			}
-
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexBuffer);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		DynamicIndexBufferHandle createDynamicIndexBuffer(uint16_t _num)
-		{
-			DynamicIndexBufferHandle handle = BGFX_INVALID_HANDLE;
-			uint32_t size = BX_ALIGN_16(uint32_t(_num*2) );
-			uint64_t ptr = m_dynamicIndexBufferAllocator.alloc(size);
-			if (ptr == NonLocalAllocator::invalidBlock)
-			{
-				IndexBufferHandle indexBufferHandle = { m_indexBufferHandle.alloc() };
-				if (indexBufferHandle.idx == invalidHandle)
-				{
-					return handle;
-				}
-
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
-				cmdbuf.write(indexBufferHandle);
-				cmdbuf.write(BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
-
-				m_dynamicIndexBufferAllocator.add(uint64_t(indexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
-				ptr = m_dynamicIndexBufferAllocator.alloc(size);
-			}
-
-			handle.idx = m_dynamicIndexBufferHandle.alloc();
-			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[handle.idx];
-			dib.m_handle.idx = uint16_t(ptr>>32);
-			dib.m_offset = uint32_t(ptr);
-			dib.m_size = size;
-
-			return handle;
-		}
-
-		DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem)
-		{
-			DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/2);
-			updateDynamicIndexBuffer(handle, _mem);
-			return handle;
-		}
-
-		void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem)
-		{
-			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicIndexBuffer);
-			cmdbuf.write(dib.m_handle);
-			cmdbuf.write(dib.m_offset);
-			cmdbuf.write(dib.m_size);
-			cmdbuf.write(_mem);
-		}
-
-		void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle)
-		{
-			m_freeDynamicIndexBufferHandle[m_numFreeDynamicIndexBufferHandles++] = _handle;
-		}
-
-		void destroyDynamicIndexBufferInternal(DynamicIndexBufferHandle _handle)
-		{
-			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
-			m_dynamicIndexBufferAllocator.free(uint64_t(dib.m_handle.idx)<<32 | dib.m_offset);
-			m_dynamicIndexBufferHandle.free(_handle.idx);
-		}
-
-		DynamicVertexBufferHandle createDynamicVertexBuffer(uint16_t _num, const VertexDecl& _decl)
-		{
-			DynamicVertexBufferHandle handle = BGFX_INVALID_HANDLE;
-			uint32_t size = strideAlign16(_num*_decl.m_stride, _decl.m_stride);
-			uint64_t ptr = m_dynamicVertexBufferAllocator.alloc(size);
-			if (ptr == NonLocalAllocator::invalidBlock)
-			{
-				VertexBufferHandle vertexBufferHandle = { m_vertexBufferHandle.alloc() };
-
-				if (vertexBufferHandle.idx == invalidHandle)
-				{
-					return handle;
-				}
-
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer);
-				cmdbuf.write(vertexBufferHandle);
-				cmdbuf.write(BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
-
-				m_dynamicVertexBufferAllocator.add(uint64_t(vertexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
-				ptr = m_dynamicVertexBufferAllocator.alloc(size);
-			}
-
-			VertexDeclHandle declHandle = findVertexDecl(_decl);
-
-			handle.idx = m_dynamicVertexBufferHandle.alloc();
-			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[handle.idx];
-			dvb.m_handle.idx = uint16_t(ptr>>32);
-			dvb.m_offset = uint32_t(ptr);
-			dvb.m_size = size;
-			dvb.m_startVertex = dvb.m_offset/_decl.m_stride;
-			dvb.m_numVertices = dvb.m_size/_decl.m_stride;
-			dvb.m_decl = declHandle;
-			m_declRef.add(dvb.m_handle, declHandle, _decl.m_hash);
-
-			return handle;
-		}
-
-		DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
-		{
-			DynamicVertexBufferHandle handle = createDynamicVertexBuffer(_mem->size/_decl.m_stride, _decl);
-			updateDynamicVertexBuffer(handle, _mem);
-			return handle;
-		}
-
-		void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, const Memory* _mem)
-		{
-			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx];
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicVertexBuffer);
-			cmdbuf.write(dvb.m_handle);
-			cmdbuf.write(dvb.m_offset);
-			cmdbuf.write(dvb.m_size);
-			cmdbuf.write(_mem);
-		}
-
-		void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle)
-		{
-			m_freeDynamicVertexBufferHandle[m_numFreeDynamicVertexBufferHandles++] = _handle;
-		}
-
-		void destroyDynamicVertexBufferInternal(DynamicVertexBufferHandle _handle)
-		{
-			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx];
-
-			VertexDeclHandle declHandle = m_declRef.release(dvb.m_handle);
-			if (invalidHandle != declHandle.idx)
-			{
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexDecl);
-				cmdbuf.write(declHandle);
-			}
-
-			m_dynamicVertexBufferAllocator.free(uint64_t(dvb.m_handle.idx)<<32 | dvb.m_offset);
-			m_dynamicVertexBufferHandle.free(_handle.idx);
-		}
-
-		TransientIndexBuffer* createTransientIndexBuffer(uint32_t _size)
-		{
-			IndexBufferHandle handle = { m_indexBufferHandle.alloc() };
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
-			cmdbuf.write(handle);
-			cmdbuf.write(_size);
-
-			TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer)+_size);
-			ib->data = (uint8_t*)&ib[1];
-			ib->size = _size;
-			ib->handle = handle;
-
-			return ib;
-		}
-
-		void destroyTransientIndexBuffer(TransientIndexBuffer* _ib)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyDynamicIndexBuffer);
-			cmdbuf.write(_ib->handle);
-
-			m_submit->free(_ib->handle);
-			g_free(const_cast<TransientIndexBuffer*>(_ib) );
-		}
-
-		const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num)
-		{
-			uint32_t offset = m_submit->allocTransientIndexBuffer(_num);
-
-			TransientIndexBuffer& dib = *m_submit->m_transientIb;
-
-			TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer) );
-			ib->data = &dib.data[offset];
-			ib->size = _num * sizeof(uint16_t);
-			ib->handle = dib.handle;
-			ib->startIndex = offset/sizeof(uint16_t);
-
-			return ib;
-		}
-
-		TransientVertexBuffer* createTransientVertexBuffer(uint32_t _size, const VertexDecl* _decl = NULL)
-		{
-			VertexBufferHandle handle = { m_vertexBufferHandle.alloc() };
-
-			uint16_t stride = 0;
-			VertexDeclHandle declHandle = BGFX_INVALID_HANDLE;
-
-			if (NULL != _decl)
-			{
-				declHandle = findVertexDecl(*_decl);
-				m_declRef.add(handle, declHandle, _decl->m_hash);
-
-				stride = _decl->m_stride;
-			}
-
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer);
-			cmdbuf.write(handle);
-			cmdbuf.write(_size);
-
-			TransientVertexBuffer* vb = (TransientVertexBuffer*)g_realloc(NULL, sizeof(TransientVertexBuffer)+_size);
-			vb->data = (uint8_t*)&vb[1];
-			vb->size = _size;
-			vb->startVertex = 0;
-			vb->stride = stride;
-			vb->handle = handle;
-			vb->decl = declHandle;
-
-			return vb;
-		}
-
-		void destroyTransientVertexBuffer(TransientVertexBuffer* _vb)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyDynamicVertexBuffer);
-			cmdbuf.write(_vb->handle);
-
-			m_submit->free(_vb->handle);
-			g_free(const_cast<TransientVertexBuffer*>(_vb) );
-		}
-
-		const TransientVertexBuffer* allocTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl)
-		{
-			VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash);
-
-			TransientVertexBuffer& dvb = *m_submit->m_transientVb;
-
-			if (invalidHandle == declHandle.idx)
-			{
-				VertexDeclHandle temp = { m_vertexDeclHandle.alloc() };
-				declHandle = temp;
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexDecl);
-				cmdbuf.write(declHandle);
-				cmdbuf.write(_decl);
-				m_declRef.add(dvb.handle, declHandle, _decl.m_hash);
-			}
-
-			uint32_t offset = m_submit->allocTransientVertexBuffer(_num, _decl.m_stride);
-
-			TransientVertexBuffer* vb = (TransientVertexBuffer*)g_realloc(NULL, sizeof(TransientVertexBuffer) );
-			vb->data = &dvb.data[offset];
-			vb->size = _num * _decl.m_stride;
-			vb->startVertex = offset/_decl.m_stride;
-			vb->stride = _decl.m_stride;
-			vb->handle = dvb.handle;
-			vb->decl = declHandle;
-
-			return vb;
-		}
-
-		const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride)
-		{
-#if BGFX_CONFIG_RENDERER_OPENGLES2
-			return NULL;
-#else
-			uint16_t stride = BX_ALIGN_16(_stride);
-			uint32_t offset = m_submit->allocTransientVertexBuffer(_num, stride);
-
-			TransientVertexBuffer& dvb = *m_submit->m_transientVb;
-			InstanceDataBuffer* idb = (InstanceDataBuffer*)g_realloc(NULL, sizeof(InstanceDataBuffer) );
-			idb->data = &dvb.data[offset];
-			idb->size = _num * stride;
-			idb->offset = offset;
-			idb->stride = stride;
-			idb->num = _num;
-			idb->handle = dvb.handle;
-
-			return idb;
-#endif // BGFX_CONFIG_RENDERER_OPENGLES
-		}
-
-		VertexShaderHandle createVertexShader(const Memory* _mem)
-		{
-			VertexShaderHandle handle = { m_vertexShaderHandle.alloc() };
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexShader);
-			cmdbuf.write(handle);
-			cmdbuf.write(_mem);
-			return handle;
-		}
-
-		void destroyVertexShader(VertexShaderHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexShader);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		FragmentShaderHandle createFragmentShader(const Memory* _mem)
-		{
-			FragmentShaderHandle handle = { m_fragmentShaderHandle.alloc() };
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFragmentShader);
-			cmdbuf.write(handle);
-			cmdbuf.write(_mem);
-			return handle;
-		}
-
-		void destroyFragmentShader(FragmentShaderHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFragmentShader);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		MaterialHandle createMaterial(VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
-		{
-			MaterialHandle handle;
-// 			uint32_t hash = _vsh.idx<<16 | _fsh.idx;
-// 
-// 			MaterialHandle handle = m_materialRef.find(hash);
-// 
-// 			if (invalidHandle != handle.idx)
-// 			{
-// 				return handle;
-// 			}
-// 
- 			handle.idx = m_materialHandle.alloc();
-// 			m_materialRef.add(handle, hash);
-
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateMaterial);
-			cmdbuf.write(handle);
-			cmdbuf.write(_vsh);
-			cmdbuf.write(_fsh);
-			return handle;
-		}
-
-		void destroyMaterial(MaterialHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyMaterial);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height)
-		{
-			if (NULL != _width
-			||  NULL != _height)
-			{
-				int width = 0;
-				int height = 0;
-
-				Dds dds;
-				if (parseDds(dds, _mem) )
-				{
-					width = dds.m_width;
-					height = dds.m_height;
-				}
-
-				if (NULL != _width)
-				{
-					*_width = (uint16_t)width;
-				}
-
-				if (NULL != _height)
-				{
-					*_height = (uint16_t)height;
-				}
-			}
-
-			TextureHandle handle = { m_textureHandle.alloc() };
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTexture);
-			cmdbuf.write(handle);
-			cmdbuf.write(_mem);
-			cmdbuf.write(_flags);
-			return handle;
-		}
-
-		void destroyTexture(TextureHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyTexture);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		RenderTargetHandle createRenderTarget(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
-		{
-			RenderTargetHandle handle = { m_renderTargetHandle.alloc() };
-
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateRenderTarget);
-			cmdbuf.write(handle);
-			cmdbuf.write(_width);
-			cmdbuf.write(_height);
-			cmdbuf.write(_flags);
-			cmdbuf.write(_textureFlags);
-			return handle;
-		}
-
-		void destroyRenderTarget(RenderTargetHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyRenderTarget);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		UniformHandle createUniform(const char* _name, ConstantType::Enum _type, uint16_t _num)
-		{
-			BX_CHECK(PredefinedUniform::Count == nameToPredefinedUniformEnum(_name), "%s is predefined uniform name.", _name);
-
-			UniformHandle handle = { m_uniformHandle.alloc() };
-
-			Constant& constant = m_constant[handle.idx];
-			constant.m_type = _type;
-			constant.m_num = _num;
-
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateUniform);
-			cmdbuf.write(handle);
-			cmdbuf.write(_type);
-			cmdbuf.write(_num);
-			uint8_t len = (uint8_t)strlen(_name);
-			cmdbuf.write(len);
-			cmdbuf.write(_name, len);
-			return handle;
-		}
-
-		void destroyUniform(UniformHandle _handle)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyUniform);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
-		}
-
-		void saveScreenShot(const Memory* _mem)
-		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::SaveScreenShot);
-			cmdbuf.write(_mem);
-		}
-
-		void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
-		{
-			Constant& constant = m_constant[_handle.idx];
-			BX_CHECK(constant.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, constant.m_num);
-			m_submit->writeConstant(constant.m_type, _handle, _value, uint16_min(constant.m_num, _num) );
-		}
-
-		void setUniform(MaterialHandle /*_material*/, UniformHandle /*_handle*/, const void* /*_value*/)
-		{
-			BX_CHECK(false, "NOT IMPLEMENTED!");
-		}
-
-		void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
-		{
-			Rect& rect = m_rect[_id];
-			rect.m_x = _x;
-			rect.m_y = _y;
-			rect.m_width = uint16_max(_width, 1);
-			rect.m_height = uint16_max(_height, 1);
-		}
-
-		void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
-		{
-			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
-			{
-				viewMask >>= ntz;
-				id += ntz;
-
-				setViewRect(id, _x, _y, _width, _height);
-			}
-		}
-
-		void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
-		{
-			Clear& clear = m_clear[_id];
-			clear.m_flags = _flags;
-			clear.m_rgba = _rgba;
-			clear.m_depth = _depth;
-			clear.m_stencil = _stencil;
-		}
-
-		void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
-		{
-			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
-			{
-				viewMask >>= ntz;
-				id += ntz;
-
-				setViewClear(id, _flags, _rgba, _depth, _stencil);
-			}
-		}
-
-		void setViewSeq(uint8_t _id, bool _enabled)
-		{
-			m_seqMask[_id] = _enabled ? 0xffff : 0x0;
-		}
-
-		void setViewSeqMask(uint32_t _viewMask, bool _enabled)
-		{
-			uint16_t mask = _enabled ? 0xffff : 0x0;
-			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
-			{
-				viewMask >>= ntz;
-				id += ntz;
-
-				m_seqMask[id] = mask;
-			}
-		}
-
-		void setViewRenderTarget(uint8_t _id, RenderTargetHandle _handle)
-		{
-			m_rt[_id] = _handle;
-		}
-
-		void setViewRenderTargetMask(uint32_t _viewMask, RenderTargetHandle _handle)
-		{
-			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
-			{
-				viewMask >>= ntz;
-				id += ntz;
-
-				m_rt[id] = _handle;
-			}
-		}
-
-		void dumpViewStats()
-		{
-#if 0 // BGFX_CONFIG_DEBUG
-			for (uint8_t view = 0; view < BGFX_CONFIG_MAX_VIEWS; ++view)
-			{
-				if (0 < m_seq[view])
-				{
-					BX_TRACE("%d: %d", view, m_seq[view]);
-				}
-			}
-#endif // BGFX_CONFIG_DEBUG
-		}
-
-		void freeDynamicBuffers()
-		{
-			for (uint16_t ii = 0, num = m_numFreeDynamicIndexBufferHandles; ii < num; ++ii)
-			{
-				destroyDynamicIndexBufferInternal(m_freeDynamicIndexBufferHandle[ii]);
-			}
-			m_numFreeDynamicIndexBufferHandles = 0;
-
-			for (uint16_t ii = 0, num = m_numFreeDynamicVertexBufferHandles; ii < num; ++ii)
-			{
-				destroyDynamicVertexBufferInternal(m_freeDynamicVertexBufferHandle[ii]);
-			}
-			m_numFreeDynamicVertexBufferHandles = 0;
-		}
-
-		void freeAllHandles(Frame* _frame)
-		{
-			for (uint16_t ii = 0, num = _frame->m_numFreeIndexBufferHandles; ii < num; ++ii)
-			{
-				m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
-			{
-				m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
-			{
-				m_vertexBufferHandle.free(_frame->m_freeVertexBufferHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeVertexShaderHandles; ii < num; ++ii)
-			{
-				m_vertexShaderHandle.free(_frame->m_freeVertexShaderHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeFragmentShaderHandles; ii < num; ++ii)
-			{
-				m_fragmentShaderHandle.free(_frame->m_freeFragmentShaderHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeMaterialHandles; ii < num; ++ii)
-			{
-				m_materialHandle.free(_frame->m_freeMaterialHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeTextureHandles; ii < num; ++ii)
-			{
-				m_textureHandle.free(_frame->m_freeTextureHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeRenderTargetHandles; ii < num; ++ii)
-			{
-				m_renderTargetHandle.free(_frame->m_freeRenderTargetHandle[ii].idx);
-			}
-
-			for (uint16_t ii = 0, num = _frame->m_numFreeUniformHandles; ii < num; ++ii)
-			{
-				m_uniformHandle.free(_frame->m_freeUniformHandle[ii].idx);
-			}
-		}
-
-		void swap()
-		{
-			freeDynamicBuffers();
-			m_submit->m_resolution = m_resolution;
-			m_submit->m_debug = m_debug;
-			memcpy(m_submit->m_rt, m_rt, sizeof(m_rt) );
-			memcpy(m_submit->m_clear, m_clear, sizeof(m_clear) );
-			memcpy(m_submit->m_rect, m_rect, sizeof(m_rect) );
-			m_submit->finish();
-
-			dumpViewStats();
-
-			freeAllHandles(m_render);
-
-			memset(m_seq, 0, sizeof(m_seq) );
-			Frame* temp = m_render;
-			m_render = m_submit;
-			m_submit = temp;
-			m_frames++;
-			m_submit->reset();
-
-			m_submit->m_textVideoMem->resize(m_render->m_textVideoMem->m_small, m_resolution.m_width, m_resolution.m_height);
-		}
-
-		void flip();
-
-		// render thread
-		bool renderFrame()
-		{
-			flip();
-
-			gameSemWait();
-			
-			rendererExecCommands(m_render->m_cmdPre);
-			if (m_rendererInitialized)
-			{
-				rendererSubmit();
-			}
-			rendererExecCommands(m_render->m_cmdPost);
-
-			renderSemPost();
-
-			return m_exit;
-		}
-
-		void rendererInit();
-		void rendererShutdown();
-		void rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem);
-		void rendererDestroyIndexBuffer(IndexBufferHandle _handle);
-		void rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle);
-		void rendererDestroyVertexBuffer(VertexBufferHandle _handle);
-		void rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size);
-		void rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem);
-		void rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle);
-		void rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size);
-		void rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem);
-		void rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle);
-		void rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl);
-		void rendererDestroyVertexDecl(VertexDeclHandle _handle);
-		void rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem);
-		void rendererDestroyVertexShader(VertexShaderHandle _handle);
-		void rendererCreateFragmentShader(FragmentShaderHandle _handle, Memory* _mem);
-		void rendererDestroyFragmentShader(FragmentShaderHandle _handle);
-		void rendererCreateMaterial(MaterialHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
-		void rendererDestroyMaterial(FragmentShaderHandle _handle);
-		void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags);
-		void rendererDestroyTexture(TextureHandle _handle);
-		void rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
-		void rendererDestroyRenderTarget(RenderTargetHandle _handle);
-		void rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name);
-		void rendererDestroyUniform(UniformHandle _handle);
-		void rendererSaveScreenShot(Memory* _mem);
-		void rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size);
-
-		void rendererUpdateUniforms(ConstantBuffer* _constantBuffer, uint32_t _begin, uint32_t _end)
-		{
-			_constantBuffer->reset(_begin);
-			while (_constantBuffer->getPos() < _end)
-			{
-				uint32_t opcode = _constantBuffer->read();
-
-				if (ConstantType::End == opcode)
-				{
-					break;
-				}
-
-				ConstantType::Enum type;
-				uint16_t loc;
-				uint16_t num;
-				uint16_t copy;
-				ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy);
-
-				const char* data;
-				uint32_t size = g_constantTypeSize[type]*num;
-				data = _constantBuffer->read(size);
-				rendererUpdateUniform(loc, data, size);
-			}
-		}
-		
-		void rendererExecCommands(CommandBuffer& _cmdbuf)
-		{
-			_cmdbuf.reset();
-
-			bool end = false;
-
-			do
-			{
-				uint8_t command;
-				_cmdbuf.read(command);
-
-				switch (command)
-				{
-				case CommandBuffer::RendererInit:
-					{
-						rendererInit();
-						m_rendererInitialized = true;
-					}
-					break;
-
-				case CommandBuffer::RendererShutdown:
-					{
-						rendererShutdown();
-						m_rendererInitialized = false;
-						m_exit = true;
-					}
-					break;
-
-				case CommandBuffer::CreateIndexBuffer:
-					{
-						IndexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						rendererCreateIndexBuffer(handle, mem);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyIndexBuffer:
-					{
-						IndexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyIndexBuffer(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateVertexDecl:
-					{
-						VertexDeclHandle handle;
-						_cmdbuf.read(handle);
-
-						VertexDecl decl;
-						_cmdbuf.read(decl);
-
-						rendererCreateVertexDecl(handle, decl);
-					}
-					break;
-
-				case CommandBuffer::DestroyVertexDecl:
-					{
-						VertexDeclHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyVertexDecl(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateVertexBuffer:
-					{
-						VertexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						VertexDeclHandle declHandle;
-						_cmdbuf.read(declHandle);
-
-						rendererCreateVertexBuffer(handle, mem, declHandle);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyVertexBuffer:
-					{
-						VertexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyVertexBuffer(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateDynamicIndexBuffer:
-					{
-						IndexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						uint32_t size;
-						_cmdbuf.read(size);
-
-						rendererCreateDynamicIndexBuffer(handle, size);
-					}
-					break;
-
-				case CommandBuffer::UpdateDynamicIndexBuffer:
-					{
-						IndexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						uint32_t offset;
-						_cmdbuf.read(offset);
-
-						uint32_t size;
-						_cmdbuf.read(size);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						rendererUpdateDynamicIndexBuffer(handle, offset, size, mem);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyDynamicIndexBuffer:
-					{
-						IndexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyDynamicIndexBuffer(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateDynamicVertexBuffer:
-					{
-						VertexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						uint32_t size;
-						_cmdbuf.read(size);
-
-						rendererCreateDynamicVertexBuffer(handle, size);
-					}
-					break;
-
-				case CommandBuffer::UpdateDynamicVertexBuffer:
-					{
-						VertexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						uint32_t offset;
-						_cmdbuf.read(offset);
-
-						uint32_t size;
-						_cmdbuf.read(size);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						rendererUpdateDynamicVertexBuffer(handle, offset, size, mem);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyDynamicVertexBuffer:
-					{
-						VertexBufferHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyDynamicVertexBuffer(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateVertexShader:
-					{
-						VertexShaderHandle handle;
-						_cmdbuf.read(handle);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						rendererCreateVertexShader(handle, mem);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyVertexShader:
-					{
-						VertexShaderHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyVertexShader(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateFragmentShader:
-					{
-						FragmentShaderHandle handle;
-						_cmdbuf.read(handle);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						rendererCreateFragmentShader(handle, mem);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyFragmentShader:
-					{
-						FragmentShaderHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyFragmentShader(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateMaterial:
-					{
-						MaterialHandle handle;
-						_cmdbuf.read(handle);
-
-						VertexShaderHandle vsh;
-						_cmdbuf.read(vsh);
-
-						FragmentShaderHandle fsh;
-						_cmdbuf.read(fsh);
-
-						rendererCreateMaterial(handle, vsh, fsh);
-					}
-					break;
-
-				case CommandBuffer::DestroyMaterial:
-					{
-						FragmentShaderHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyMaterial(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateTexture:
-					{
-						TextureHandle handle;
-						_cmdbuf.read(handle);
-
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						uint32_t flags;
-						_cmdbuf.read(flags);
-
-						rendererCreateTexture(handle, mem, flags);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::DestroyTexture:
-					{
-						TextureHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyTexture(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateRenderTarget:
-					{
-						RenderTargetHandle handle;
-						_cmdbuf.read(handle);
-
-						uint16_t width;
-						_cmdbuf.read(width);
-
-						uint16_t height;
-						_cmdbuf.read(height);
-
-						uint32_t flags;
-						_cmdbuf.read(flags);
-
-						uint32_t textureFlags;
-						_cmdbuf.read(textureFlags);
-
-						rendererCreateRenderTarget(handle, width, height, flags, textureFlags);
-					}
-					break;
-
-				case CommandBuffer::DestroyRenderTarget:
-					{
-						RenderTargetHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyRenderTarget(handle);
-					}
-					break;
-
-				case CommandBuffer::CreateUniform:
-					{
-						UniformHandle handle;
-						_cmdbuf.read(handle);
-
-						ConstantType::Enum type;
-						_cmdbuf.read(type);
-
-						uint16_t num;
-						_cmdbuf.read(num);
-
-						uint8_t len;
-						_cmdbuf.read(len);
-
-						char name[256];
-						_cmdbuf.read(name, len);
-						name[len] = '\0';
-
-						rendererCreateUniform(handle, type, num, name);
-					}
-					break;
-
-				case CommandBuffer::DestroyUniform:
-					{
-						UniformHandle handle;
-						_cmdbuf.read(handle);
-
-						rendererDestroyUniform(handle);
-					}
-					break;
-
-				case CommandBuffer::SaveScreenShot:
-					{
-						Memory* mem;
-						_cmdbuf.read(mem);
-
-						rendererSaveScreenShot(mem);
-
-						release(mem);
-					}
-					break;
-
-				case CommandBuffer::End:
-					end = true;
-					break;
-
-				default:
-					BX_CHECK(false, "WTF!");
-					break;
-				}
-			} while (!end);
-		}
-
-		void rendererSubmit();
-
-#if BGFX_CONFIG_MULTITHREADED
-		void gameSemPost()
-		{
-// 			BX_TRACE("game post");
-			m_gameSem.post();
-		}
-
-		void gameSemWait()
-		{
-// 			BX_TRACE("game wait");
-			int64_t start = bx::getHPCounter();
-			m_gameSem.wait();
-			m_render->m_waitSubmit = bx::getHPCounter()-start;
-		}
-
-		void renderSemPost()
-		{
-// 			BX_TRACE("render post");
-			m_renderSem.post();
-		}
-
-		void renderSemWait()
-		{
-// 			BX_TRACE("render wait");
-			int64_t start = bx::getHPCounter();
-			m_renderSem.wait();
-			m_submit->m_waitRender = bx::getHPCounter() - start;
-		}
-
-		Semaphore m_renderSem;
-		Semaphore m_gameSem;
-
-#	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
-		HANDLE m_renderThread;
-#	else
-		pthread_t m_renderThread;
-#	endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
-
-#else
-		void gameSemPost()
-		{
-		}
-
-		void gameSemWait()
-		{
-		}
-
-		void renderSemPost()
-		{
-		}
-
-		void renderSemWait()
-		{
-		}
-#endif // BGFX_CONFIG_MULTITHREADED
-
-		Frame m_frame[2];
-		Frame* m_render;
-		Frame* m_submit;
-
-		uint64_t m_tempKeys[BGFX_CONFIG_MAX_DRAW_CALLS];
-		uint16_t m_tempValues[BGFX_CONFIG_MAX_DRAW_CALLS];
-
-		DynamicIndexBuffer m_dynamicIndexBuffers[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS];
-		DynamicVertexBuffer m_dynamicVertexBuffers[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
-
-		uint16_t m_numFreeDynamicIndexBufferHandles;
-		uint16_t m_numFreeDynamicVertexBufferHandles;
-		DynamicIndexBufferHandle m_freeDynamicIndexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS];
-		DynamicVertexBufferHandle m_freeDynamicVertexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
-
-		NonLocalAllocator m_dynamicIndexBufferAllocator;
-		HandleAlloc m_dynamicIndexBufferHandle;
-		NonLocalAllocator m_dynamicVertexBufferAllocator;
-		HandleAlloc m_dynamicVertexBufferHandle;
-
-		HandleAlloc m_indexBufferHandle;
-		HandleAlloc m_vertexDeclHandle;
-		HandleAlloc m_vertexBufferHandle;
-		HandleAlloc m_vertexShaderHandle;
-		HandleAlloc m_fragmentShaderHandle;
-		HandleAlloc m_materialHandle;
-		HandleAlloc m_textureHandle;
-		HandleAlloc m_renderTargetHandle;
-		HandleAlloc m_uniformHandle;
-
-		MaterialRef m_materialRef;
-		VertexDeclRef m_declRef;
-
-		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
-		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
-		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
-		Constant m_constant[BGFX_CONFIG_MAX_UNIFORMS];
-		uint16_t m_seq[BGFX_CONFIG_MAX_VIEWS];
-		uint16_t m_seqMask[BGFX_CONFIG_MAX_VIEWS];
-
-		Resolution m_resolution;
-		uint32_t m_frames;
-		uint32_t m_debug;
-
-		TextVideoMemBlitter m_textVideoMemBlitter;
-		ClearQuad m_clearQuad;
-
-#if BX_PLATFORM_WINDOWS
-		struct Window
-		{
-			Window()
-				: m_frame(true)
-				, m_update(false)
-			{
-			}
-
-			void init()
-			{
-				if (NULL == g_bgfxHwnd)
-				{					
-					HINSTANCE instance = (HINSTANCE)GetModuleHandle(NULL);
-
-					WNDCLASSEX wnd;
-					memset(&wnd, 0, sizeof(wnd) );
-					wnd.cbSize = sizeof(wnd);
-					wnd.lpfnWndProc = DefWindowProc;
-					wnd.hInstance = instance;
-					wnd.hIcon = LoadIcon(instance, IDI_APPLICATION);
-					wnd.hCursor = LoadCursor(instance, IDC_ARROW);
-					wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
-					wnd.lpszClassName = "bgfx_letterbox";
-					wnd.hIconSm = LoadIcon(instance, IDI_APPLICATION);
-					RegisterClassExA(&wnd);
-
-					memset(&wnd, 0, sizeof(wnd) );
-					wnd.cbSize = sizeof(wnd);
-					wnd.style = CS_HREDRAW | CS_VREDRAW;
-					wnd.lpfnWndProc = wndProc;
-					wnd.hInstance = instance;
-					wnd.hIcon = LoadIcon(instance, IDI_APPLICATION);
-					wnd.hCursor = LoadCursor(instance, IDC_ARROW);
-					wnd.lpszClassName = "bgfx";
-					wnd.hIconSm = LoadIcon(instance, IDI_APPLICATION);
-					RegisterClassExA(&wnd);
-
-					HWND hwnd = CreateWindowA("bgfx_letterbox"
-						, "BGFX"
-						, WS_POPUP|WS_SYSMENU
-						, -32000
-						, -32000
-						, 0
-						, 0
-						, NULL
-						, NULL
-						, instance
-						, 0
-						);
-
-					g_bgfxHwnd = CreateWindowA("bgfx"
-						, "BGFX"
-						, WS_OVERLAPPEDWINDOW|WS_VISIBLE
-						, 0
-						, 0
-						, BGFX_DEFAULT_WIDTH
-						, BGFX_DEFAULT_HEIGHT
-						, hwnd
-						, NULL
-						, instance
-						, 0
-						);
-
-					m_update = true;
-				}
-			}
-
-			LRESULT process(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam)
-			{
-				switch (_id)
-				{
-				case WM_CLOSE:
-					TerminateProcess(GetCurrentProcess(), 0);
-					break;
-
-				case WM_SIZING:
-					{
-						RECT clientRect;
-						GetClientRect(_hwnd, &clientRect);
-						uint32_t width = clientRect.right-clientRect.left;
-						uint32_t height = clientRect.bottom-clientRect.top;
-
-						RECT& rect = *(RECT*)_lparam;
-						uint32_t frameWidth = rect.right-rect.left - width;
-						uint32_t frameHeight = rect.bottom-rect.top - height;
-
-						switch (_wparam)
-						{
-						case WMSZ_LEFT:
-						case WMSZ_RIGHT:
-							{
-								float aspectRatio = 1.0f/m_aspectRatio;
-								width = bx::uint32_max(BGFX_DEFAULT_WIDTH/4, width);
-								height = uint32_t(float(width)*aspectRatio);
-							}
-							break;
-
-						default:
-							{
-								float aspectRatio = m_aspectRatio;
-								height = bx::uint32_max(BGFX_DEFAULT_HEIGHT/4, height);
-								width = uint32_t(float(height)*aspectRatio);
-							}
-							break;
-						}
-
-						rect.right = rect.left + width + frameWidth;
-						rect.bottom = rect.top + height + frameHeight;
-
-						SetWindowPos(_hwnd
-							, HWND_TOP
-							, rect.left
-							, rect.top
-							, (rect.right-rect.left)
-							, (rect.bottom-rect.top)
-							, SWP_SHOWWINDOW
-							);
-					}
-					return 0;
-
-				case WM_SYSCOMMAND:
-					switch (_wparam)
-					{
-					case SC_MINIMIZE:
-					case SC_RESTORE:
-						{
-							HWND parent = GetWindow(_hwnd, GW_OWNER);
-							if (NULL != parent)
-							{
-								PostMessage(parent, _id, _wparam, _lparam);
-							}
-						}
-					}
-					break;
-
-				case WM_KEYDOWN:
-				case WM_SYSKEYDOWN:
-					if ((WM_KEYDOWN == _id && VK_F11 == _wparam)
-					||  (WM_SYSKEYDOWN == _id && VK_RETURN == _wparam))
-					{
-						toggleWindowFrame();
-					}
-					break;
-
-				default:
-					break;
-				}
-
-				return DefWindowProc(_hwnd, _id, _wparam, _lparam);
-			}
-
-			void update()
-			{
-				if (m_update)
-				{
-					MSG msg;
-					msg.message = WM_NULL;
-					if (0 != PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) )
-					{
-						TranslateMessage(&msg);
-						DispatchMessage(&msg);
-					}
-				}
-			}
-
-			void adjust(uint32_t _width, uint32_t _height, bool _windowFrame)
-			{
-				m_width = _width;
-				m_height = _height;
-				m_aspectRatio = float(_width)/float(_height);
-
-				ShowWindow(g_bgfxHwnd, SW_SHOWNORMAL);
-				RECT rect;
-				RECT newrect = {0, 0, (LONG)_width, (LONG)_height};
-				DWORD style = WS_POPUP|WS_SYSMENU;
-
-				if (m_frame)
-				{
-					GetWindowRect(g_bgfxHwnd, &m_rect);
-					m_style = GetWindowLong(g_bgfxHwnd, GWL_STYLE);
-				}
-
-				if (_windowFrame)
-				{
-					rect = m_rect;
-					style = m_style;
-				}
-				else
-				{
-#if defined(__MINGW32__)
-					rect = m_rect;
-					style = m_style;
-#else
-					HMONITOR monitor = MonitorFromWindow(g_bgfxHwnd, MONITOR_DEFAULTTONEAREST);
-					MONITORINFO mi;
-					mi.cbSize = sizeof(mi);
-					GetMonitorInfo(monitor, &mi);
-					newrect = mi.rcMonitor;
-					rect = mi.rcMonitor;
-#endif // !defined(__MINGW__)
-				}
-
-				SetWindowLong(g_bgfxHwnd, GWL_STYLE, style);
-				AdjustWindowRect(&newrect, style, FALSE);
-				UpdateWindow(g_bgfxHwnd);
-
-				if (rect.left == -32000
-				||  rect.top == -32000)
-				{
-					rect.left = 0;
-					rect.top = 0;
-				}
-
-				int32_t left = rect.left;
-				int32_t top = rect.top;
-				int32_t width = (newrect.right-newrect.left);
-				int32_t height = (newrect.bottom-newrect.top);
-
-				if (!_windowFrame)
-				{
-					float aspectRatio = 1.0f/m_aspectRatio;
-					width = bx::uint32_max(BGFX_DEFAULT_WIDTH/4, width);
-					height = uint32_t(float(width)*aspectRatio);
-
-					left = newrect.left+(newrect.right-newrect.left-width)/2;
-					top = newrect.top+(newrect.bottom-newrect.top-height)/2;
-				}
-
-				HWND parent = GetWindow(g_bgfxHwnd, GW_OWNER);
-				if (NULL != parent)
-				{
-					if (_windowFrame)
-					{
-						SetWindowPos(parent
-							, HWND_TOP
-							, -32000
-							, -32000
-							, 0
-							, 0
-							, SWP_SHOWWINDOW
-							);
-					}
-					else
-					{
-						SetWindowPos(parent
-							, HWND_TOP
-							, newrect.left
-							, newrect.top
-							, newrect.right-newrect.left
-							, newrect.bottom-newrect.top
-							, SWP_SHOWWINDOW
-							);
-					}
-				}
-
-				SetWindowPos(g_bgfxHwnd
-					, HWND_TOP
-					, left
-					, top
-					, width
-					, height
-					, SWP_SHOWWINDOW
-					);
-
-				ShowWindow(g_bgfxHwnd, SW_RESTORE);
-
-				m_frame = _windowFrame;
-			}
-
-		private:
-			static LRESULT CALLBACK wndProc(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam);
-
-			void toggleWindowFrame()
-			{
-				adjust(m_width, m_height, !m_frame);
-			}
-
-			RECT m_rect;
-			DWORD m_style;
-			uint32_t m_width;
-			uint32_t m_height;
-			float m_aspectRatio;
-			bool m_frame;
-			bool m_update;
-		};
-
-		Window m_window;
-#endif // BX_PLATFORM_WINDOWS
-
-		bool m_rendererInitialized;
-		bool m_exit;
-	};
-
-} // namespace bgfx
-
-#endif // __BGFX_P_H__
+
+	struct PredefinedUniform
+	{
+		enum Enum
+		{
+			ViewRect,
+			ViewTexel,
+			View,
+			ViewProj,
+			ViewProjX,
+			Model,
+			ModelViewProj,
+			ModelViewProjX,
+			AlphaRef,
+			Count
+		};
+
+		uint8_t m_type;
+		uint16_t m_loc;
+		uint16_t m_count;
+	};
+
+	const char* getPredefinedUniformName(PredefinedUniform::Enum _enum);
+	PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name);
+
+	class StreamRead
+	{
+	public:
+		StreamRead(const void* _data, uint32_t _size)
+			: m_data( (uint8_t*)_data)
+			, m_size(_size)
+			, m_pos(0)
+		{
+		}
+
+		~StreamRead()
+		{
+		}
+
+		void skip(uint32_t _size)
+		{
+			BX_CHECK(m_size-m_pos >= _size, "Available %d, requested %d.", m_size-m_pos, _size);
+			m_pos += _size;
+		}
+
+		void read(void* _data, uint32_t _size)
+		{
+			BX_CHECK(m_size-m_pos >= _size, "Available %d, requested %d.", m_size-m_pos, _size);
+			memcpy(_data, &m_data[m_pos], _size);
+			m_pos += _size;
+		}
+
+		template<typename Ty>
+		void read(Ty& _value)
+		{
+			read(&_value, sizeof(Ty) );
+		}
+
+		const uint8_t* getDataPtr() const
+		{
+			return &m_data[m_pos];
+		}
+
+		uint32_t getPos() const
+		{
+			return m_pos;
+		}
+
+		void align(uint16_t _align)
+		{
+			m_pos = strideAlign(m_pos, _align);
+		}
+
+		uint32_t remaining() const
+		{
+			return m_size-m_pos;
+		}
+
+	private:
+		const uint8_t* m_data;
+		uint32_t m_size;
+		uint32_t m_pos;
+	};
+
+	class StreamWrite
+	{
+	public:
+		StreamWrite(void* _data, uint32_t _size)
+			: m_data( (uint8_t*)_data)
+			, m_size(_size)
+			, m_pos(0)
+		{
+		}
+
+		~StreamWrite()
+		{
+		}
+
+		void write(void* _data, uint32_t _size)
+		{
+			BX_CHECK(m_size-m_pos >= _size, "Write out of bounds. Available %d, requested %d.", m_size-m_pos, _size);
+			memcpy(&m_data[m_pos], _data, _size);
+			m_pos += _size;
+		}
+
+		template<typename Ty>
+		void write(Ty& _value)
+		{
+			write(&_value, sizeof(Ty) );
+		}
+
+		uint8_t* getDataPtr() const
+		{
+			return &m_data[m_pos];
+		}
+
+		uint32_t getPos() const
+		{
+			return m_pos;
+		}
+
+		void align(uint16_t _align)
+		{
+			m_pos = strideAlign(m_pos, _align);
+		}
+
+	private:
+		uint8_t* m_data;
+		uint32_t m_size;
+		uint32_t m_pos;
+	};
+
+	struct CommandBuffer
+	{
+		CommandBuffer()
+			: m_pos(0)
+			, m_size(BGFX_CONFIG_MAX_COMMAND_BUFFER_SIZE)
+		{
+			finish();
+		}
+
+		enum Enum
+		{
+			RendererInit,
+			CreateVertexDecl,
+			CreateIndexBuffer,
+			CreateVertexBuffer,
+			CreateDynamicIndexBuffer,
+			UpdateDynamicIndexBuffer,
+			CreateDynamicVertexBuffer,
+			UpdateDynamicVertexBuffer,
+			CreateVertexShader,
+			CreateFragmentShader,
+			CreateMaterial,
+			CreateTexture,
+			CreateRenderTarget,
+			CreateUniform,
+			End,
+			RendererShutdown,
+			DestroyVertexDecl,
+			DestroyIndexBuffer,
+			DestroyVertexBuffer,
+			DestroyDynamicIndexBuffer,
+			DestroyDynamicVertexBuffer,
+			DestroyVertexShader,
+			DestroyFragmentShader,
+			DestroyMaterial,
+			DestroyTexture,
+			DestroyRenderTarget,
+			DestroyUniform,
+			SaveScreenShot,
+		};
+
+		void write(const void* _data, uint32_t _size)
+		{
+			BX_CHECK(m_pos < m_size, "");
+			memcpy(&m_buffer[m_pos], _data, _size);
+			m_pos += _size;
+		}
+
+		template<typename Type>
+		void write(const Type& _in)
+		{
+			write(reinterpret_cast<const uint8_t*>(&_in), sizeof(Type) );
+		}
+
+		void read(void* _data, uint32_t _size)
+		{
+			BX_CHECK(m_pos < m_size, "");
+			memcpy(_data, &m_buffer[m_pos], _size);
+			m_pos += _size;
+		}
+
+		template<typename Type>
+		void read(Type& _in)
+		{
+			read(reinterpret_cast<uint8_t*>(&_in), sizeof(Type) );
+		}
+
+		void reset()
+		{
+			m_pos = 0;
+		}
+
+		void finish()
+		{
+			uint8_t cmd = End;
+			write(cmd);
+			m_pos = 0;
+		}
+
+		uint32_t m_pos;
+		uint32_t m_size;
+		uint8_t m_buffer[BGFX_CONFIG_MAX_COMMAND_BUFFER_SIZE];
+
+	private:
+		CommandBuffer(const CommandBuffer&);
+		void operator=(const CommandBuffer&);
+	};
+
+	struct SortKey
+	{
+		uint64_t encode()
+		{
+			// |               3               2               1               0|
+			// |fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210|
+			// |             vvvvvsssssssssssttmmmmmmmmmdddddddddddddddddddddddd|
+			// |                 ^          ^ ^        ^                       ^|
+			// |                 |          | |        |                       ||
+
+			uint64_t tmp0 = m_depth;
+			uint64_t tmp1 = uint64_t(m_material)<<0x18;
+			uint64_t tmp2 = uint64_t(m_trans)<<0x21;
+			uint64_t tmp3 = uint64_t(m_seq)<<0x23;
+			uint64_t tmp4 = uint64_t(m_view)<<0x2e;
+			uint64_t key = tmp0|tmp1|tmp2|tmp3|tmp4;
+			return key;
+		}
+
+		void decode(uint64_t _key)
+		{
+			m_depth = _key&0xffffffff;
+			m_material = (_key>>0x18)&(BGFX_CONFIG_MAX_MATERIALS-1);
+			m_trans = (_key>>0x21)&0x3;
+			m_seq = (_key>>0x23)&0x7ff;
+			m_view = (_key>>0x2e)&(BGFX_CONFIG_MAX_VIEWS-1);
+		}
+
+		void reset()
+		{
+			m_depth = 0;
+			m_material = 0;
+			m_seq = 0;
+			m_view = 0;
+			m_trans = 0;
+		}
+
+		int32_t m_depth;
+		uint16_t m_material;
+		uint16_t m_seq;
+		uint8_t m_view;
+		uint8_t m_trans;
+	};
+
+	BX_ALIGN_STRUCT_16(struct) Matrix4
+	{
+		float val[16];
+
+		void setIdentity()
+		{
+			memset(val, 0, sizeof(val) );
+			val[0] = val[5] = val[10] = val[15] = 1.0f;
+		}
+	};
+
+	void matrix_mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
+	void matrix_ortho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far);
+
+	struct MatrixCache
+	{
+		MatrixCache()
+			: m_num(1)
+		{
+			m_cache[0].setIdentity();
+		}
+
+		void reset()
+		{
+			m_num = 1;
+		}
+
+		uint32_t add(const void* _mtx, uint16_t _num)
+		{
+			if (NULL != _mtx)
+			{
+				BX_CHECK(m_num+_num < BGFX_CONFIG_MAX_MATRIX_CACHE, "Matrix cache overflow. %d (max: %d)", m_num+_num, BGFX_CONFIG_MAX_MATRIX_CACHE);
+
+				uint32_t num = uint32_min(BGFX_CONFIG_MAX_MATRIX_CACHE-m_num, _num);
+				uint32_t first = m_num;
+				memcpy(&m_cache[m_num], _mtx, sizeof(Matrix4)*num);
+				m_num += num;
+				return first;
+			}
+
+			return 0;
+		}
+
+		Matrix4 m_cache[BGFX_CONFIG_MAX_MATRIX_CACHE];
+		uint32_t m_num;
+	};
+
+	struct Sampler
+	{
+		uint16_t m_idx;
+		uint16_t m_flags;
+	};
+	
+	struct Constant
+	{
+		ConstantType::Enum m_type;
+		uint16_t m_num;
+	};
+
+#define CONSTANT_OPCODE_MASK(_bits) ( (1<<_bits)-1)
+
+#define CONSTANT_OPCODE_TYPE_BITS 8
+#define CONSTANT_OPCODE_TYPE_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_TYPE_BITS)
+#define CONSTANT_OPCODE_LOC_BITS 10
+#define CONSTANT_OPCODE_LOC_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_LOC_BITS)
+#define CONSTANT_OPCODE_NUM_BITS 10
+#define CONSTANT_OPCODE_NUM_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_NUM_BITS)
+#define CONSTANT_OPCODE_COPY_BITS 1
+#define CONSTANT_OPCODE_COPY_MASK CONSTANT_OPCODE_MASK(CONSTANT_OPCODE_COPY_BITS)
+
+#define BGFX_UNIFORM_FUNCTIONBIT UINT8_C(0x40)
+#define BGFX_UNIFORM_FRAGMENTBIT UINT8_C(0x80)
+#define BGFX_UNIFORM_TYPEMASK    UINT8_C(0x3f)
+
+	class ConstantBuffer
+	{
+	public:
+		static ConstantBuffer* create(uint32_t _size)
+		{
+			uint32_t size = BX_ALIGN_16(uint32_max(_size, sizeof(ConstantBuffer) ) );
+			void* data = g_realloc(NULL, size);
+			return ::new(data) ConstantBuffer(_size);
+		}
+
+		static void destroy(ConstantBuffer* _constantBuffer)
+		{
+			_constantBuffer->~ConstantBuffer();
+			g_free(_constantBuffer);
+		}
+
+		static uint32_t encodeOpcode(ConstantType::Enum _type, uint16_t _loc, uint16_t _num, uint16_t _copy)
+		{
+			uint32_t opcode = 0;
+
+			opcode <<= CONSTANT_OPCODE_TYPE_BITS;
+			opcode |= _type&CONSTANT_OPCODE_TYPE_MASK;
+
+			opcode <<= CONSTANT_OPCODE_LOC_BITS;
+			opcode |= _loc&CONSTANT_OPCODE_LOC_MASK;
+
+			opcode <<= CONSTANT_OPCODE_NUM_BITS;
+			opcode |= _num&CONSTANT_OPCODE_NUM_MASK;
+
+			opcode <<= CONSTANT_OPCODE_COPY_BITS;
+			opcode |= _copy&CONSTANT_OPCODE_COPY_MASK;
+
+			return opcode;
+		}
+
+		static void decodeOpcode(uint32_t _opcode, ConstantType::Enum& _type, uint16_t& _loc, uint16_t& _num, uint16_t& _copy)
+		{
+			uint32_t copy;
+			uint32_t num;
+			uint32_t loc;
+
+			copy = _opcode&CONSTANT_OPCODE_COPY_MASK;
+			_opcode >>= CONSTANT_OPCODE_COPY_BITS;
+
+			num = _opcode&CONSTANT_OPCODE_NUM_MASK;
+			_opcode >>= CONSTANT_OPCODE_NUM_BITS;
+
+			loc = _opcode&CONSTANT_OPCODE_LOC_MASK;
+			_opcode >>= CONSTANT_OPCODE_LOC_BITS;
+
+			_type = (ConstantType::Enum)(_opcode&CONSTANT_OPCODE_TYPE_MASK);
+			_opcode >>= CONSTANT_OPCODE_TYPE_BITS;
+
+			_copy = (uint16_t)copy;
+			_num = (uint16_t)num;
+			_loc = (uint16_t)loc;
+		}
+
+		void write(const void* _data, uint32_t _size)
+		{
+			BX_CHECK(m_pos + _size < m_size, "Write would go out of bounds. pos %d + size %d > max size: %d).", m_pos, _size, m_size);
+
+			if (m_pos + _size < m_size)
+			{
+				memcpy(&m_buffer[m_pos], _data, _size);
+				m_pos += _size;
+			}
+		}
+
+		void write(uint32_t _value)
+		{
+			write(&_value, sizeof(uint32_t) );
+		}
+
+		const char* read(uint32_t _size)
+		{
+			BX_CHECK(m_pos < m_size, "Out of bounds %d (size: %d).", m_pos, m_size);
+			const char* result = &m_buffer[m_pos];
+			m_pos += _size;
+			return result;
+		}
+
+		uint32_t read()
+		{
+			const char* result = read(sizeof(uint32_t) );
+			return *( (uint32_t*)result);
+		}
+
+		bool isEmpty() const
+		{
+			return 0 == m_pos;
+		}
+
+		uint32_t getPos() const
+		{
+			return m_pos;
+		}
+
+		void reset(uint32_t _pos = 0)
+		{
+			m_pos = _pos;
+		}
+
+		void finish()
+		{
+			write(ConstantType::End);
+			m_pos = 0;
+		}
+
+		void writeUniform(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
+		void writeUniformRef(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
+		void commit();
+
+	private:
+		ConstantBuffer(uint32_t _size)
+			: m_size(_size-sizeof(m_buffer) )
+			, m_pos(0)
+		{
+			BX_TRACE("ConstantBuffer %d, %d", _size, m_size);
+			finish();
+		}
+
+		~ConstantBuffer()
+		{
+		}
+
+		uint32_t m_size;
+		uint32_t m_pos;
+		char m_buffer[8];
+	};
+
+	typedef const void* (*UniformFn)(const void* _data);
+
+	struct UniformInfo
+	{
+		const void* m_data;
+		UniformFn m_func;
+	};
+
+ 	class UniformRegistry
+ 	{
+	public:
+		UniformRegistry()
+		{
+		}
+
+		~UniformRegistry()
+		{
+		}
+ 
+ 		const UniformInfo* find(const char* _name) const
+ 		{
+			UniformHashMap::const_iterator it = m_uniforms.find(_name);
+			if (it != m_uniforms.end() )
+			{
+				return &it->second;
+			}
+
+ 			return NULL;
+ 		}
+
+		const UniformInfo& reg(const char* _name, const void* _data, UniformFn _func = NULL)
+		{
+			UniformHashMap::const_iterator it = m_uniforms.find(_name);
+			if (it == m_uniforms.end() )
+			{
+				UniformInfo info;
+				info.m_data = _data;
+				info.m_func = _func;
+
+				stl::pair<UniformHashMap::iterator, bool> result = m_uniforms.insert(UniformHashMap::value_type(_name, info) );
+				return result.first->second;	
+			}
+
+			return it->second;
+		}
+
+ 	private:
+ 		typedef stl::unordered_map<stl::string, UniformInfo> UniformHashMap;
+ 		UniformHashMap m_uniforms;
+ 	};
+
+	struct RenderState
+	{
+		void reset()
+		{
+			m_constEnd = 0;
+			clear();
+		}
+
+		void clear()
+		{
+			m_constBegin = m_constEnd;
+			m_flags = BGFX_STATE_DEFAULT;
+			m_matrix = 0;
+			m_startIndex = BGFX_DRAW_WHOLE_INDEX_BUFFER;
+			m_numIndices = 0;
+			m_startVertex = 0;
+			m_numVertices = UINT32_C(0xffffffff);
+			m_instanceDataOffset = 0;
+			m_instanceDataStride = 0;
+			m_numInstances = 1;
+			m_num = 1;
+			m_vertexBuffer.idx = invalidHandle;
+			m_vertexDecl.idx = invalidHandle;
+			m_indexBuffer.idx = invalidHandle;
+			m_instanceDataBuffer.idx = invalidHandle;
+			
+			for (uint32_t ii = 0; ii < BGFX_STATE_TEX_COUNT; ++ii)
+			{
+				m_sampler[ii].m_idx = invalidHandle;
+				m_sampler[ii].m_flags = BGFX_SAMPLER_TEXTURE;
+			}
+		}
+
+		uint64_t m_flags;
+		uint32_t m_constBegin;
+		uint32_t m_constEnd;
+		uint32_t m_matrix;
+		uint32_t m_startIndex;
+		uint32_t m_numIndices;
+		uint32_t m_startVertex;
+		uint32_t m_numVertices;
+		uint32_t m_instanceDataOffset;
+		uint16_t m_instanceDataStride;
+		uint16_t m_numInstances;
+		uint16_t m_num;
+
+		VertexBufferHandle m_vertexBuffer;
+		VertexDeclHandle m_vertexDecl;
+		IndexBufferHandle m_indexBuffer;
+		VertexBufferHandle m_instanceDataBuffer;
+		Sampler m_sampler[BGFX_STATE_TEX_COUNT];
+	};
+
+	struct Resolution
+	{
+		Resolution()
+			: m_width(BGFX_DEFAULT_WIDTH)
+			, m_height(BGFX_DEFAULT_HEIGHT)
+			, m_flags(BGFX_RESET_NONE)
+		{
+		}
+
+		uint32_t m_width;
+		uint32_t m_height;
+		uint32_t m_flags;
+	};
+
+	struct DynamicIndexBuffer
+	{
+		IndexBufferHandle m_handle;
+		uint32_t m_offset;
+		uint32_t m_size;
+	};
+
+	struct DynamicVertexBuffer
+	{
+		VertexBufferHandle m_handle;
+		uint32_t m_offset;
+		uint32_t m_size;
+		uint32_t m_startVertex;
+		uint32_t m_numVertices;
+		uint32_t m_stride;
+		VertexDeclHandle m_decl;
+	};
+
+	struct Frame
+	{
+		BX_CACHE_LINE_ALIGN_MARKER();
+
+		Frame()
+		{
+		}
+
+		~Frame()
+		{
+		}
+
+		void create()
+		{
+			m_constantBuffer = ConstantBuffer::create(BGFX_CONFIG_MAX_CONSTANT_BUFFER_SIZE);
+			reset();
+			m_textVideoMem = new TextVideoMem;
+		}
+
+		void destroy()
+		{
+			ConstantBuffer::destroy(m_constantBuffer);
+			delete m_textVideoMem;
+		}
+
+		void reset()
+		{
+			m_state.reset();
+			m_matrixCache.reset();
+			m_key.reset();
+			m_num = 0;
+			m_numRenderStates = 0;
+			m_numDropped = 0;
+			m_iboffset = 0;
+			m_vboffset = 0;
+			m_cmdPre.reset();
+			m_cmdPost.reset();
+			m_constantBuffer->reset();
+			m_discard = false;
+			resetFreeHandles();
+		}
+
+		void finish()
+		{
+			m_cmdPre.finish();
+			m_cmdPost.finish();
+			m_constantBuffer->finish();
+
+			if (0 < m_numDropped)
+			{
+				BX_TRACE("Too many draw calls: %d, dropped %d (max: %d)", m_num+m_numDropped, m_numDropped, BGFX_CONFIG_MAX_DRAW_CALLS);
+			}
+		}
+
+		void setViewTransform(uint8_t _id, const void* _view, const void* _proj, uint8_t _other)
+		{
+			if (BGFX_CONFIG_MAX_VIEWS > _other)
+			{
+				m_other[_id] = _other;
+			}
+			else
+			{
+				m_other[_id] = _id;
+			}
+
+			if (NULL != _view)
+			{
+				memcpy(m_view[_id].val, _view, sizeof(Matrix4) );
+			}
+			else
+			{
+				m_view[_id].setIdentity();
+			}
+
+			if (NULL != _proj)
+			{
+				memcpy(m_proj[_id].val, _proj, sizeof(Matrix4) );
+			}
+			else
+			{
+				m_view[_id].setIdentity();
+			}
+		}
+
+		void setViewTransformMask(uint32_t _viewMask, const void* _view, const void* _proj, uint8_t _other)
+		{
+			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
+			{
+				viewMask >>= ntz;
+				id += ntz;
+
+				setViewTransform(id, _view, _proj, _other);
+			}
+		}
+
+		void setState(uint64_t _state)
+		{
+			uint8_t blend = ( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT)&0xff;
+			m_key.m_trans = "\x0\x1\x1\x2\x2\x1\x2\x1\x2\x1\x1\x1\x1\x1\x1\x1\x1"[( (blend)&0xf) + (!!blend)];
+			m_state.m_flags = _state;
+		}
+
+		uint32_t setTransform(const void* _mtx, uint16_t _num)
+		{
+			m_state.m_matrix = m_matrixCache.add(_mtx, _num);
+			m_state.m_num = _num;
+
+			return m_state.m_matrix;
+		}
+
+		void setTransform(uint32_t _cache, uint16_t _num)
+		{
+			m_state.m_matrix = _cache;
+			m_state.m_num = _num;
+		}
+
+		void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
+		{
+			m_state.m_startIndex = _firstIndex;
+			m_state.m_numIndices = _numIndices;
+			m_state.m_indexBuffer = _handle;
+		}
+
+		void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices)
+		{
+			m_state.m_indexBuffer = _ib->handle;
+			m_state.m_startIndex = _ib->startIndex;
+			m_state.m_numIndices = _numIndices;
+			m_discard = 0 == _numIndices;
+			g_free(const_cast<TransientIndexBuffer*>(_ib) );
+		}
+
+		void setVertexBuffer(VertexBufferHandle _handle)
+		{
+			BX_CHECK(_handle.idx < BGFX_CONFIG_MAX_VERTEX_BUFFERS, "Invalid vertex buffer handle. %d (< %d)", _handle.idx, BGFX_CONFIG_MAX_VERTEX_BUFFERS);
+			m_state.m_startVertex = 0;
+			m_state.m_numVertices = UINT32_C(0xffffffff);
+			m_state.m_vertexBuffer = _handle;
+		}
+
+		void setVertexBuffer(const DynamicVertexBuffer& dvb)
+		{
+			m_state.m_startVertex = dvb.m_startVertex;
+			m_state.m_numVertices = dvb.m_numVertices;
+			m_state.m_vertexBuffer = dvb.m_handle;
+			m_state.m_vertexDecl = dvb.m_decl;
+		}
+
+		void setVertexBuffer(const TransientVertexBuffer* _vb)
+		{
+			m_state.m_startVertex = _vb->startVertex;
+			m_state.m_numVertices = _vb->size/_vb->stride;
+			m_state.m_vertexBuffer = _vb->handle;
+			m_state.m_vertexDecl = _vb->decl;
+			g_free(const_cast<TransientVertexBuffer*>(_vb) );
+		}
+
+		void setInstanceDataBuffer(const InstanceDataBuffer* _idb)
+		{
+#if BGFX_CONFIG_RENDERER_OPENGLES2
+#else
+ 			m_state.m_instanceDataOffset = _idb->offset;
+			m_state.m_instanceDataStride = _idb->stride;
+			m_state.m_numInstances = _idb->num;
+			m_state.m_instanceDataBuffer = _idb->handle;
+			g_free(const_cast<InstanceDataBuffer*>(_idb) );
+#endif // BGFX_CONFIG_RENDERER_OPENGLES
+		}
+
+		void setMaterial(MaterialHandle _handle)
+		{
+			BX_CHECK(invalidHandle != _handle.idx, "Can't set material with invalid handle.");
+			m_key.m_material = _handle.idx;
+		}
+
+		void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle)
+		{
+			m_flags |= BGFX_STATE_TEX0<<_stage;
+			Sampler& sampler = m_state.m_sampler[_stage];
+			sampler.m_idx = _handle.idx;
+			sampler.m_flags = BGFX_SAMPLER_TEXTURE;
+
+			if (invalidHandle != _sampler.idx)
+			{
+				uint32_t stage = _stage;
+				setUniform(_sampler, &stage);
+			}
+		}
+
+		void setTexture(uint8_t _stage, UniformHandle _sampler, RenderTargetHandle _handle, bool _depth)
+		{
+			m_flags |= BGFX_STATE_TEX0<<_stage;
+			Sampler& sampler = m_state.m_sampler[_stage];
+			sampler.m_idx = _handle.idx;
+			sampler.m_flags = _depth ? BGFX_SAMPLER_RENDERTARGET_DEPTH : BGFX_SAMPLER_RENDERTARGET_COLOR;
+
+			if (invalidHandle != _sampler.idx)
+			{
+				uint32_t stage = _stage;
+				setUniform(_sampler, &stage);
+			}
+		}
+
+		void submit(uint8_t _id);
+		void submitMask(uint32_t _viewMask);
+		void sort();
+
+		bool checkAvailTransientIndexBuffer(uint16_t _num)
+		{
+			uint32_t offset = m_iboffset;
+			uint32_t iboffset = offset + _num*sizeof(uint16_t);
+			iboffset = uint32_min(iboffset, BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
+			uint32_t num = (iboffset-offset)/sizeof(uint16_t);
+			return num == _num;
+		}
+
+		uint32_t allocTransientIndexBuffer(uint16_t& _num)
+		{
+			uint32_t offset = m_iboffset;
+			m_iboffset = offset + _num*sizeof(uint16_t);
+			m_iboffset = uint32_min(m_iboffset, BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
+			_num = uint16_t( (m_iboffset-offset)/sizeof(uint16_t) );
+			return offset;
+		}
+
+		bool checkAvailTransientVertexBuffer(uint16_t _num, uint16_t _stride)
+		{
+			uint32_t offset = strideAlign(m_vboffset, _stride);
+			uint32_t vboffset = offset + _num * _stride;
+			vboffset = uint32_min(vboffset, BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
+			uint32_t num = (vboffset-offset)/_stride;
+			return num == _num;
+		}
+
+		uint32_t allocTransientVertexBuffer(uint16_t& _num, uint16_t _stride)
+		{
+			uint32_t offset = strideAlign(m_vboffset, _stride);
+			m_vboffset = offset + _num * _stride;
+			m_vboffset = uint32_min(m_vboffset, BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
+			_num = uint16_t( (m_vboffset-offset)/_stride);
+			return offset;
+		}
+
+		void writeConstant(ConstantType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num)
+		{
+			m_constantBuffer->writeUniform(_type, _handle.idx, _value, _num);
+		}
+
+		void free(IndexBufferHandle _handle)
+		{
+			m_freeIndexBufferHandle[m_numFreeIndexBufferHandles] = _handle;
+			++m_numFreeIndexBufferHandles;
+		}
+
+		void free(VertexDeclHandle _handle)
+		{
+			m_freeVertexDeclHandle[m_numFreeVertexDeclHandles] = _handle;
+			++m_numFreeVertexDeclHandles;
+		}
+
+		void free(VertexBufferHandle _handle)
+		{
+			m_freeVertexBufferHandle[m_numFreeVertexBufferHandles] = _handle;
+			++m_numFreeVertexBufferHandles;
+		}
+
+		void free(VertexShaderHandle _handle)
+		{
+			m_freeVertexShaderHandle[m_numFreeVertexShaderHandles] = _handle;
+			++m_numFreeVertexShaderHandles;
+		}
+
+		void free(FragmentShaderHandle _handle)
+		{
+			m_freeFragmentShaderHandle[m_numFreeFragmentShaderHandles] = _handle;
+			++m_numFreeFragmentShaderHandles;
+		}
+
+		void free(MaterialHandle _handle)
+		{
+			m_freeMaterialHandle[m_numFreeMaterialHandles] = _handle;
+			++m_numFreeMaterialHandles;
+		}
+
+		void free(TextureHandle _handle)
+		{
+			m_freeTextureHandle[m_numFreeTextureHandles] = _handle;
+			++m_numFreeTextureHandles;
+		}
+
+		void free(RenderTargetHandle _handle)
+		{
+			m_freeRenderTargetHandle[m_numFreeRenderTargetHandles] = _handle;
+			++m_numFreeRenderTargetHandles;
+		}
+
+		void free(UniformHandle _handle)
+		{
+			m_freeUniformHandle[m_numFreeUniformHandles] = _handle;
+			++m_numFreeUniformHandles;
+		}
+
+		void resetFreeHandles()
+		{
+			m_numFreeIndexBufferHandles = 0;
+			m_numFreeVertexDeclHandles = 0;
+			m_numFreeVertexBufferHandles = 0;
+			m_numFreeVertexShaderHandles = 0;
+			m_numFreeFragmentShaderHandles = 0;
+			m_numFreeFragmentShaderHandles = 0;
+			m_numFreeMaterialHandles = 0;
+			m_numFreeTextureHandles = 0;
+			m_numFreeRenderTargetHandles = 0;
+			m_numFreeUniformHandles = 0;
+		}
+
+		SortKey m_key;
+
+		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
+		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
+		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
+		Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
+		Matrix4 m_proj[BGFX_CONFIG_MAX_VIEWS];
+		uint8_t m_other[BGFX_CONFIG_MAX_VIEWS];
+
+		uint64_t m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS];
+		uint16_t m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS];
+		RenderState m_renderState[BGFX_CONFIG_MAX_DRAW_CALLS];
+		RenderState m_state;
+		uint64_t m_flags;
+
+		ConstantBuffer* m_constantBuffer;
+
+		uint16_t m_num;
+		uint16_t m_numRenderStates;
+		uint16_t m_numDropped;
+
+		MatrixCache m_matrixCache;
+
+		uint32_t m_iboffset;
+		uint32_t m_vboffset;
+		TransientIndexBuffer* m_transientIb;
+		TransientVertexBuffer* m_transientVb;
+
+		Resolution m_resolution;
+		uint32_t m_debug;
+
+		CommandBuffer m_cmdPre;
+		CommandBuffer m_cmdPost;
+
+		uint16_t m_numFreeIndexBufferHandles;
+		uint16_t m_numFreeVertexDeclHandles;
+		uint16_t m_numFreeVertexBufferHandles;
+		uint16_t m_numFreeVertexShaderHandles;
+		uint16_t m_numFreeFragmentShaderHandles;
+		uint16_t m_numFreeMaterialHandles;
+		uint16_t m_numFreeTextureHandles;
+		uint16_t m_numFreeRenderTargetHandles;
+		uint16_t m_numFreeUniformHandles;
+
+		IndexBufferHandle m_freeIndexBufferHandle[BGFX_CONFIG_MAX_INDEX_BUFFERS];
+		VertexDeclHandle m_freeVertexDeclHandle[BGFX_CONFIG_MAX_VERTEX_DECLS];
+		VertexBufferHandle m_freeVertexBufferHandle[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
+		VertexShaderHandle m_freeVertexShaderHandle[BGFX_CONFIG_MAX_VERTEX_SHADERS];
+		FragmentShaderHandle m_freeFragmentShaderHandle[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
+		MaterialHandle m_freeMaterialHandle[BGFX_CONFIG_MAX_MATERIALS];
+		TextureHandle m_freeTextureHandle[BGFX_CONFIG_MAX_TEXTURES];
+		RenderTargetHandle m_freeRenderTargetHandle[BGFX_CONFIG_MAX_RENDER_TARGETS];
+		UniformHandle m_freeUniformHandle[BGFX_CONFIG_MAX_UNIFORMS];
+		TextVideoMem* m_textVideoMem;
+
+		int64_t m_waitSubmit;
+		int64_t m_waitRender;
+
+		bool m_discard;
+	};
+
+	struct MaterialRef
+	{
+		MaterialRef()
+		{
+		}
+
+		MaterialHandle find(uint32_t _hash)
+		{
+			MaterialMap::const_iterator it = m_materialMap.find(_hash);
+			if (it != m_materialMap.end() )
+			{
+				return it->second;
+			}
+
+			MaterialHandle result = BGFX_INVALID_HANDLE;
+			return result;
+		}
+
+		void add(MaterialHandle _handle, uint32_t _hash)
+		{
+			m_materialMap.insert(stl::make_pair(_hash, _handle) );
+		}
+
+		typedef stl::unordered_map<uint32_t, MaterialHandle> MaterialMap;
+		MaterialMap m_materialMap;
+	};
+
+	struct VertexDeclRef
+	{
+		VertexDeclRef()
+		{
+			memset(m_vertexDeclRef, 0, sizeof(m_vertexDeclRef) );
+			memset(m_vertexBufferRef, 0xff, sizeof(m_vertexBufferRef) );
+		}
+
+		VertexDeclHandle find(uint32_t _hash)
+		{
+			VertexDeclMap::const_iterator it = m_vertexDeclMap.find(_hash);
+			if (it != m_vertexDeclMap.end() )
+			{
+				return it->second;
+			}
+
+			VertexDeclHandle result = BGFX_INVALID_HANDLE;
+			return result;
+		}
+
+		void add(VertexBufferHandle _handle, VertexDeclHandle _declHandle, uint32_t _hash)
+		{
+			m_vertexBufferRef[_handle.idx] = _declHandle;
+			m_vertexDeclRef[_declHandle.idx]++;
+			m_vertexDeclMap.insert(stl::make_pair(_hash, _declHandle) );
+		}
+
+		VertexDeclHandle release(VertexBufferHandle _handle)
+		{
+			VertexDeclHandle declHandle = m_vertexBufferRef[_handle.idx];
+			m_vertexDeclRef[declHandle.idx]--;
+
+			if (0 != m_vertexDeclRef[declHandle.idx])
+			{
+				VertexDeclHandle invalid = BGFX_INVALID_HANDLE;
+				return invalid;
+			}
+
+			return declHandle;
+		}
+
+		typedef stl::unordered_map<uint32_t, VertexDeclHandle> VertexDeclMap;
+		VertexDeclMap m_vertexDeclMap;
+		uint16_t m_vertexDeclRef[BGFX_CONFIG_MAX_VERTEX_DECLS];
+		VertexDeclHandle m_vertexBufferRef[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
+	};
+
+	// First-fit non-local allocator.
+	class NonLocalAllocator
+	{
+	public:
+		static const uint64_t invalidBlock = UINT64_MAX;
+
+		NonLocalAllocator()
+		{
+		}
+
+		~NonLocalAllocator()
+		{
+		}
+
+		void reset()
+		{
+			m_free.clear();
+			m_used.clear();
+		}
+
+		void add(uint64_t _ptr, uint32_t _size)
+		{
+			m_free.push_back(Free(_ptr, _size) );
+		}
+
+		uint64_t alloc(uint32_t _size)
+		{
+			for (FreeList::iterator it = m_free.begin(), itEnd = m_free.end(); it != itEnd; ++it)
+			{
+				if (it->m_size >= _size)
+				{
+					uint64_t ptr = it->m_ptr;
+
+					m_used.insert(stl::make_pair(ptr, _size) );
+
+					if (it->m_size != _size)
+					{
+						it->m_size -= _size;
+						it->m_ptr += _size;
+					}
+					else
+					{
+						m_free.erase(it);
+					}
+
+					return ptr;
+				}
+			}
+
+			// there is no block large enough.
+			return invalidBlock;
+		}
+
+		void free(uint64_t _block)
+		{
+			UsedList::iterator it = m_used.find(_block);
+			if (it != m_used.end() )
+			{
+				m_free.push_front(Free(it->first, it->second) );
+				m_used.erase(it);
+			}
+		}
+
+		void compact()
+		{
+			m_free.sort();
+
+			for (FreeList::iterator it = m_free.begin(), next = it, itEnd = m_free.end(); next != itEnd;)
+			{
+				if ( (it->m_ptr + it->m_size) == next->m_ptr)
+				{
+					it->m_size += next->m_size;
+					next = m_free.erase(next);
+				}
+				else
+				{
+					it = next;
+					++next;
+				}
+			}
+		}
+
+	private:
+		struct Free
+		{
+			Free(uint64_t _ptr, uint32_t _size)
+				: m_ptr(_ptr)
+				, m_size(_size)
+			{
+			}
+
+			bool operator<(const Free& rhs) const
+			{
+				return m_ptr < rhs.m_ptr;
+			}
+
+			uint64_t m_ptr;
+			uint32_t m_size;
+		};
+
+		typedef std::list<Free> FreeList;
+		FreeList m_free;
+
+		typedef stl::unordered_map<uint64_t, uint32_t> UsedList;
+		UsedList m_used;
+	};
+
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
+	DWORD WINAPI renderThread(LPVOID _arg);
+#elif BX_PLATFORM_LINUX
+	void* renderThread(void*);
+#endif // BX_PLATFORM_
+
+	struct Context
+	{
+		Context()
+			: m_render(&m_frame[0])
+			, m_submit(&m_frame[1])
+			, m_dynamicIndexBufferHandle(BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS)
+			, m_dynamicVertexBufferHandle(BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS)
+			, m_indexBufferHandle(BGFX_CONFIG_MAX_INDEX_BUFFERS)
+			, m_vertexDeclHandle(BGFX_CONFIG_MAX_VERTEX_DECLS)
+			, m_vertexBufferHandle(BGFX_CONFIG_MAX_VERTEX_BUFFERS)
+			, m_vertexShaderHandle(BGFX_CONFIG_MAX_VERTEX_SHADERS)
+			, m_fragmentShaderHandle(BGFX_CONFIG_MAX_FRAGMENT_SHADERS)
+			, m_materialHandle(BGFX_CONFIG_MAX_MATERIALS)
+			, m_textureHandle(BGFX_CONFIG_MAX_TEXTURES)
+			, m_renderTargetHandle(BGFX_CONFIG_MAX_RENDER_TARGETS)
+			, m_uniformHandle(BGFX_CONFIG_MAX_UNIFORMS)
+			, m_frames(0)
+			, m_debug(BGFX_DEBUG_NONE)
+			, m_rendererInitialized(false)
+			, m_exit(false)
+		{
+		}
+
+		~Context()
+		{
+		}
+
+		// game thread
+		void init(bool _createRenderThread);
+		void shutdown();
+
+		void frame()
+		{
+#if BX_PLATFORM_WINDOWS
+			m_window.update();
+#endif // BX_PLATFORM_WINDOWS
+
+			// wait for render thread to finish
+			renderSemWait();
+
+			swap();
+
+			// release render thread
+			gameSemPost();
+
+#if !BGFX_CONFIG_MULTITHREADED
+			renderFrame();
+#endif // BGFX_CONFIG_MULTITHREADED
+		}
+
+		CommandBuffer& getCommandBuffer(CommandBuffer::Enum _cmd)
+		{
+			CommandBuffer& cmdbuf = _cmd < CommandBuffer::End ? m_submit->m_cmdPre : m_submit->m_cmdPost;
+			uint8_t cmd = (uint8_t)_cmd;
+			cmdbuf.write(cmd);
+			return cmdbuf;
+		}
+
+		void reset(uint32_t _width, uint32_t _height, uint32_t _flags)
+		{
+			m_resolution.m_width = _width;
+			m_resolution.m_height = _height;
+			m_resolution.m_flags = _flags&(~BGFX_RESET_FULLSCREEN_FAKE);
+
+			memset(m_rt, 0xff, sizeof(m_rt) );
+
+#if BX_PLATFORM_WINDOWS
+			uint32_t fullscreen = (_flags&BGFX_RESET_FULLSCREEN_MASK)>>BGFX_RESET_FULLSCREEN_SHIFT;
+			m_window.adjust(_width, _height, BGFX_RESET_FULLSCREEN_FAKE != fullscreen);
+#endif // BX_PLATFORM_WINDOWS
+		}
+
+		void dbgTextClear(uint8_t _attr, bool _small)
+		{
+			m_submit->m_textVideoMem->resize(_small, m_resolution.m_width, m_resolution.m_height);
+			m_submit->m_textVideoMem->clear(_attr);
+		}
+
+		void dbgTextPrintfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
+		{
+			m_submit->m_textVideoMem->printfVargs(_x, _y, _attr, _format, _argList);
+		}
+
+		IndexBufferHandle createIndexBuffer(const Memory* _mem)
+		{
+			IndexBufferHandle handle = { m_indexBufferHandle.alloc() };
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateIndexBuffer);
+			cmdbuf.write(handle);
+			cmdbuf.write(_mem);
+			return handle;
+		}
+
+		void destroyIndexBuffer(IndexBufferHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyIndexBuffer);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		VertexDeclHandle findVertexDecl(const VertexDecl& _decl)
+		{
+			VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash);
+
+			if (invalidHandle == declHandle.idx)
+			{
+				VertexDeclHandle temp = { m_vertexDeclHandle.alloc() };
+				declHandle = temp;
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexDecl);
+				cmdbuf.write(declHandle);
+				cmdbuf.write(_decl);
+			}
+
+			return declHandle;
+		}
+
+		VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
+		{
+			VertexBufferHandle handle = { m_vertexBufferHandle.alloc() };
+
+			VertexDeclHandle declHandle = findVertexDecl(_decl);
+			m_declRef.add(handle, declHandle, _decl.m_hash);
+
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexBuffer);
+			cmdbuf.write(handle);
+			cmdbuf.write(_mem);
+			cmdbuf.write(declHandle);
+			return handle;
+		}
+
+		void destroyVertexBuffer(VertexBufferHandle _handle)
+		{
+			VertexDeclHandle declHandle = m_declRef.release(_handle);
+			if (invalidHandle != declHandle.idx)
+			{
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexDecl);
+				cmdbuf.write(declHandle);
+			}
+
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexBuffer);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		DynamicIndexBufferHandle createDynamicIndexBuffer(uint16_t _num)
+		{
+			DynamicIndexBufferHandle handle = BGFX_INVALID_HANDLE;
+			uint32_t size = BX_ALIGN_16(uint32_t(_num*2) );
+			uint64_t ptr = m_dynamicIndexBufferAllocator.alloc(size);
+			if (ptr == NonLocalAllocator::invalidBlock)
+			{
+				IndexBufferHandle indexBufferHandle = { m_indexBufferHandle.alloc() };
+				if (indexBufferHandle.idx == invalidHandle)
+				{
+					return handle;
+				}
+
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
+				cmdbuf.write(indexBufferHandle);
+				cmdbuf.write(BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
+
+				m_dynamicIndexBufferAllocator.add(uint64_t(indexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
+				ptr = m_dynamicIndexBufferAllocator.alloc(size);
+			}
+
+			handle.idx = m_dynamicIndexBufferHandle.alloc();
+			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[handle.idx];
+			dib.m_handle.idx = uint16_t(ptr>>32);
+			dib.m_offset = uint32_t(ptr);
+			dib.m_size = size;
+
+			return handle;
+		}
+
+		DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem)
+		{
+			DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/2);
+			updateDynamicIndexBuffer(handle, _mem);
+			return handle;
+		}
+
+		void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem)
+		{
+			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicIndexBuffer);
+			cmdbuf.write(dib.m_handle);
+			cmdbuf.write(dib.m_offset);
+			cmdbuf.write(dib.m_size);
+			cmdbuf.write(_mem);
+		}
+
+		void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle)
+		{
+			m_freeDynamicIndexBufferHandle[m_numFreeDynamicIndexBufferHandles++] = _handle;
+		}
+
+		void destroyDynamicIndexBufferInternal(DynamicIndexBufferHandle _handle)
+		{
+			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
+			m_dynamicIndexBufferAllocator.free(uint64_t(dib.m_handle.idx)<<32 | dib.m_offset);
+			m_dynamicIndexBufferHandle.free(_handle.idx);
+		}
+
+		DynamicVertexBufferHandle createDynamicVertexBuffer(uint16_t _num, const VertexDecl& _decl)
+		{
+			DynamicVertexBufferHandle handle = BGFX_INVALID_HANDLE;
+			uint32_t size = strideAlign16(_num*_decl.m_stride, _decl.m_stride);
+			uint64_t ptr = m_dynamicVertexBufferAllocator.alloc(size);
+			if (ptr == NonLocalAllocator::invalidBlock)
+			{
+				VertexBufferHandle vertexBufferHandle = { m_vertexBufferHandle.alloc() };
+
+				if (vertexBufferHandle.idx == invalidHandle)
+				{
+					return handle;
+				}
+
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer);
+				cmdbuf.write(vertexBufferHandle);
+				cmdbuf.write(BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
+
+				m_dynamicVertexBufferAllocator.add(uint64_t(vertexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
+				ptr = m_dynamicVertexBufferAllocator.alloc(size);
+			}
+
+			VertexDeclHandle declHandle = findVertexDecl(_decl);
+
+			handle.idx = m_dynamicVertexBufferHandle.alloc();
+			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[handle.idx];
+			dvb.m_handle.idx = uint16_t(ptr>>32);
+			dvb.m_offset = uint32_t(ptr);
+			dvb.m_size = size;
+			dvb.m_startVertex = dvb.m_offset/_decl.m_stride;
+			dvb.m_numVertices = dvb.m_size/_decl.m_stride;
+			dvb.m_decl = declHandle;
+			m_declRef.add(dvb.m_handle, declHandle, _decl.m_hash);
+
+			return handle;
+		}
+
+		DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
+		{
+			DynamicVertexBufferHandle handle = createDynamicVertexBuffer(_mem->size/_decl.m_stride, _decl);
+			updateDynamicVertexBuffer(handle, _mem);
+			return handle;
+		}
+
+		void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, const Memory* _mem)
+		{
+			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx];
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicVertexBuffer);
+			cmdbuf.write(dvb.m_handle);
+			cmdbuf.write(dvb.m_offset);
+			cmdbuf.write(dvb.m_size);
+			cmdbuf.write(_mem);
+		}
+
+		void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle)
+		{
+			m_freeDynamicVertexBufferHandle[m_numFreeDynamicVertexBufferHandles++] = _handle;
+		}
+
+		void destroyDynamicVertexBufferInternal(DynamicVertexBufferHandle _handle)
+		{
+			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx];
+
+			VertexDeclHandle declHandle = m_declRef.release(dvb.m_handle);
+			if (invalidHandle != declHandle.idx)
+			{
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexDecl);
+				cmdbuf.write(declHandle);
+			}
+
+			m_dynamicVertexBufferAllocator.free(uint64_t(dvb.m_handle.idx)<<32 | dvb.m_offset);
+			m_dynamicVertexBufferHandle.free(_handle.idx);
+		}
+
+		TransientIndexBuffer* createTransientIndexBuffer(uint32_t _size)
+		{
+			IndexBufferHandle handle = { m_indexBufferHandle.alloc() };
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
+			cmdbuf.write(handle);
+			cmdbuf.write(_size);
+
+			TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer)+_size);
+			ib->data = (uint8_t*)&ib[1];
+			ib->size = _size;
+			ib->handle = handle;
+
+			return ib;
+		}
+
+		void destroyTransientIndexBuffer(TransientIndexBuffer* _ib)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyDynamicIndexBuffer);
+			cmdbuf.write(_ib->handle);
+
+			m_submit->free(_ib->handle);
+			g_free(const_cast<TransientIndexBuffer*>(_ib) );
+		}
+
+		const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num)
+		{
+			uint32_t offset = m_submit->allocTransientIndexBuffer(_num);
+
+			TransientIndexBuffer& dib = *m_submit->m_transientIb;
+
+			TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer) );
+			ib->data = &dib.data[offset];
+			ib->size = _num * sizeof(uint16_t);
+			ib->handle = dib.handle;
+			ib->startIndex = offset/sizeof(uint16_t);
+
+			return ib;
+		}
+
+		TransientVertexBuffer* createTransientVertexBuffer(uint32_t _size, const VertexDecl* _decl = NULL)
+		{
+			VertexBufferHandle handle = { m_vertexBufferHandle.alloc() };
+
+			uint16_t stride = 0;
+			VertexDeclHandle declHandle = BGFX_INVALID_HANDLE;
+
+			if (NULL != _decl)
+			{
+				declHandle = findVertexDecl(*_decl);
+				m_declRef.add(handle, declHandle, _decl->m_hash);
+
+				stride = _decl->m_stride;
+			}
+
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer);
+			cmdbuf.write(handle);
+			cmdbuf.write(_size);
+
+			TransientVertexBuffer* vb = (TransientVertexBuffer*)g_realloc(NULL, sizeof(TransientVertexBuffer)+_size);
+			vb->data = (uint8_t*)&vb[1];
+			vb->size = _size;
+			vb->startVertex = 0;
+			vb->stride = stride;
+			vb->handle = handle;
+			vb->decl = declHandle;
+
+			return vb;
+		}
+
+		void destroyTransientVertexBuffer(TransientVertexBuffer* _vb)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyDynamicVertexBuffer);
+			cmdbuf.write(_vb->handle);
+
+			m_submit->free(_vb->handle);
+			g_free(const_cast<TransientVertexBuffer*>(_vb) );
+		}
+
+		const TransientVertexBuffer* allocTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl)
+		{
+			VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash);
+
+			TransientVertexBuffer& dvb = *m_submit->m_transientVb;
+
+			if (invalidHandle == declHandle.idx)
+			{
+				VertexDeclHandle temp = { m_vertexDeclHandle.alloc() };
+				declHandle = temp;
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexDecl);
+				cmdbuf.write(declHandle);
+				cmdbuf.write(_decl);
+				m_declRef.add(dvb.handle, declHandle, _decl.m_hash);
+			}
+
+			uint32_t offset = m_submit->allocTransientVertexBuffer(_num, _decl.m_stride);
+
+			TransientVertexBuffer* vb = (TransientVertexBuffer*)g_realloc(NULL, sizeof(TransientVertexBuffer) );
+			vb->data = &dvb.data[offset];
+			vb->size = _num * _decl.m_stride;
+			vb->startVertex = offset/_decl.m_stride;
+			vb->stride = _decl.m_stride;
+			vb->handle = dvb.handle;
+			vb->decl = declHandle;
+
+			return vb;
+		}
+
+		const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride)
+		{
+#if BGFX_CONFIG_RENDERER_OPENGLES2
+			return NULL;
+#else
+			uint16_t stride = BX_ALIGN_16(_stride);
+			uint32_t offset = m_submit->allocTransientVertexBuffer(_num, stride);
+
+			TransientVertexBuffer& dvb = *m_submit->m_transientVb;
+			InstanceDataBuffer* idb = (InstanceDataBuffer*)g_realloc(NULL, sizeof(InstanceDataBuffer) );
+			idb->data = &dvb.data[offset];
+			idb->size = _num * stride;
+			idb->offset = offset;
+			idb->stride = stride;
+			idb->num = _num;
+			idb->handle = dvb.handle;
+
+			return idb;
+#endif // BGFX_CONFIG_RENDERER_OPENGLES
+		}
+
+		VertexShaderHandle createVertexShader(const Memory* _mem)
+		{
+			VertexShaderHandle handle = { m_vertexShaderHandle.alloc() };
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexShader);
+			cmdbuf.write(handle);
+			cmdbuf.write(_mem);
+			return handle;
+		}
+
+		void destroyVertexShader(VertexShaderHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexShader);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		FragmentShaderHandle createFragmentShader(const Memory* _mem)
+		{
+			FragmentShaderHandle handle = { m_fragmentShaderHandle.alloc() };
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFragmentShader);
+			cmdbuf.write(handle);
+			cmdbuf.write(_mem);
+			return handle;
+		}
+
+		void destroyFragmentShader(FragmentShaderHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFragmentShader);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		MaterialHandle createMaterial(VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
+		{
+			MaterialHandle handle;
+// 			uint32_t hash = _vsh.idx<<16 | _fsh.idx;
+// 
+// 			MaterialHandle handle = m_materialRef.find(hash);
+// 
+// 			if (invalidHandle != handle.idx)
+// 			{
+// 				return handle;
+// 			}
+// 
+ 			handle.idx = m_materialHandle.alloc();
+// 			m_materialRef.add(handle, hash);
+
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateMaterial);
+			cmdbuf.write(handle);
+			cmdbuf.write(_vsh);
+			cmdbuf.write(_fsh);
+			return handle;
+		}
+
+		void destroyMaterial(MaterialHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyMaterial);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height)
+		{
+			if (NULL != _width
+			||  NULL != _height)
+			{
+				int width = 0;
+				int height = 0;
+
+				Dds dds;
+				if (parseDds(dds, _mem) )
+				{
+					width = dds.m_width;
+					height = dds.m_height;
+				}
+
+				if (NULL != _width)
+				{
+					*_width = (uint16_t)width;
+				}
+
+				if (NULL != _height)
+				{
+					*_height = (uint16_t)height;
+				}
+			}
+
+			TextureHandle handle = { m_textureHandle.alloc() };
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTexture);
+			cmdbuf.write(handle);
+			cmdbuf.write(_mem);
+			cmdbuf.write(_flags);
+			return handle;
+		}
+
+		void destroyTexture(TextureHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyTexture);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		RenderTargetHandle createRenderTarget(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
+		{
+			RenderTargetHandle handle = { m_renderTargetHandle.alloc() };
+
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateRenderTarget);
+			cmdbuf.write(handle);
+			cmdbuf.write(_width);
+			cmdbuf.write(_height);
+			cmdbuf.write(_flags);
+			cmdbuf.write(_textureFlags);
+			return handle;
+		}
+
+		void destroyRenderTarget(RenderTargetHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyRenderTarget);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		UniformHandle createUniform(const char* _name, ConstantType::Enum _type, uint16_t _num)
+		{
+			BX_CHECK(PredefinedUniform::Count == nameToPredefinedUniformEnum(_name), "%s is predefined uniform name.", _name);
+
+			UniformHandle handle = { m_uniformHandle.alloc() };
+
+			Constant& constant = m_constant[handle.idx];
+			constant.m_type = _type;
+			constant.m_num = _num;
+
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateUniform);
+			cmdbuf.write(handle);
+			cmdbuf.write(_type);
+			cmdbuf.write(_num);
+			uint8_t len = (uint8_t)strlen(_name);
+			cmdbuf.write(len);
+			cmdbuf.write(_name, len);
+			return handle;
+		}
+
+		void destroyUniform(UniformHandle _handle)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyUniform);
+			cmdbuf.write(_handle);
+			m_submit->free(_handle);
+		}
+
+		void saveScreenShot(const Memory* _mem)
+		{
+			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::SaveScreenShot);
+			cmdbuf.write(_mem);
+		}
+
+		void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
+		{
+			Constant& constant = m_constant[_handle.idx];
+			BX_CHECK(constant.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, constant.m_num);
+			m_submit->writeConstant(constant.m_type, _handle, _value, uint16_min(constant.m_num, _num) );
+		}
+
+		void setUniform(MaterialHandle /*_material*/, UniformHandle /*_handle*/, const void* /*_value*/)
+		{
+			BX_CHECK(false, "NOT IMPLEMENTED!");
+		}
+
+		void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+		{
+			Rect& rect = m_rect[_id];
+			rect.m_x = _x;
+			rect.m_y = _y;
+			rect.m_width = uint16_max(_width, 1);
+			rect.m_height = uint16_max(_height, 1);
+		}
+
+		void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+		{
+			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
+			{
+				viewMask >>= ntz;
+				id += ntz;
+
+				setViewRect(id, _x, _y, _width, _height);
+			}
+		}
+
+		void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
+		{
+			Clear& clear = m_clear[_id];
+			clear.m_flags = _flags;
+			clear.m_rgba = _rgba;
+			clear.m_depth = _depth;
+			clear.m_stencil = _stencil;
+		}
+
+		void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
+		{
+			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
+			{
+				viewMask >>= ntz;
+				id += ntz;
+
+				setViewClear(id, _flags, _rgba, _depth, _stencil);
+			}
+		}
+
+		void setViewSeq(uint8_t _id, bool _enabled)
+		{
+			m_seqMask[_id] = _enabled ? 0xffff : 0x0;
+		}
+
+		void setViewSeqMask(uint32_t _viewMask, bool _enabled)
+		{
+			uint16_t mask = _enabled ? 0xffff : 0x0;
+			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
+			{
+				viewMask >>= ntz;
+				id += ntz;
+
+				m_seqMask[id] = mask;
+			}
+		}
+
+		void setViewRenderTarget(uint8_t _id, RenderTargetHandle _handle)
+		{
+			m_rt[_id] = _handle;
+		}
+
+		void setViewRenderTargetMask(uint32_t _viewMask, RenderTargetHandle _handle)
+		{
+			for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
+			{
+				viewMask >>= ntz;
+				id += ntz;
+
+				m_rt[id] = _handle;
+			}
+		}
+
+		void dumpViewStats()
+		{
+#if 0 // BGFX_CONFIG_DEBUG
+			for (uint8_t view = 0; view < BGFX_CONFIG_MAX_VIEWS; ++view)
+			{
+				if (0 < m_seq[view])
+				{
+					BX_TRACE("%d: %d", view, m_seq[view]);
+				}
+			}
+#endif // BGFX_CONFIG_DEBUG
+		}
+
+		void freeDynamicBuffers()
+		{
+			for (uint16_t ii = 0, num = m_numFreeDynamicIndexBufferHandles; ii < num; ++ii)
+			{
+				destroyDynamicIndexBufferInternal(m_freeDynamicIndexBufferHandle[ii]);
+			}
+			m_numFreeDynamicIndexBufferHandles = 0;
+
+			for (uint16_t ii = 0, num = m_numFreeDynamicVertexBufferHandles; ii < num; ++ii)
+			{
+				destroyDynamicVertexBufferInternal(m_freeDynamicVertexBufferHandle[ii]);
+			}
+			m_numFreeDynamicVertexBufferHandles = 0;
+		}
+
+		void freeAllHandles(Frame* _frame)
+		{
+			for (uint16_t ii = 0, num = _frame->m_numFreeIndexBufferHandles; ii < num; ++ii)
+			{
+				m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
+			{
+				m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
+			{
+				m_vertexBufferHandle.free(_frame->m_freeVertexBufferHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeVertexShaderHandles; ii < num; ++ii)
+			{
+				m_vertexShaderHandle.free(_frame->m_freeVertexShaderHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeFragmentShaderHandles; ii < num; ++ii)
+			{
+				m_fragmentShaderHandle.free(_frame->m_freeFragmentShaderHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeMaterialHandles; ii < num; ++ii)
+			{
+				m_materialHandle.free(_frame->m_freeMaterialHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeTextureHandles; ii < num; ++ii)
+			{
+				m_textureHandle.free(_frame->m_freeTextureHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeRenderTargetHandles; ii < num; ++ii)
+			{
+				m_renderTargetHandle.free(_frame->m_freeRenderTargetHandle[ii].idx);
+			}
+
+			for (uint16_t ii = 0, num = _frame->m_numFreeUniformHandles; ii < num; ++ii)
+			{
+				m_uniformHandle.free(_frame->m_freeUniformHandle[ii].idx);
+			}
+		}
+
+		void swap()
+		{
+			freeDynamicBuffers();
+			m_submit->m_resolution = m_resolution;
+			m_submit->m_debug = m_debug;
+			memcpy(m_submit->m_rt, m_rt, sizeof(m_rt) );
+			memcpy(m_submit->m_clear, m_clear, sizeof(m_clear) );
+			memcpy(m_submit->m_rect, m_rect, sizeof(m_rect) );
+			m_submit->finish();
+
+			dumpViewStats();
+
+			freeAllHandles(m_render);
+
+			memset(m_seq, 0, sizeof(m_seq) );
+			Frame* temp = m_render;
+			m_render = m_submit;
+			m_submit = temp;
+			m_frames++;
+			m_submit->reset();
+
+			m_submit->m_textVideoMem->resize(m_render->m_textVideoMem->m_small, m_resolution.m_width, m_resolution.m_height);
+		}
+
+		void flip();
+
+		// render thread
+		bool renderFrame()
+		{
+			flip();
+
+			gameSemWait();
+			
+			rendererExecCommands(m_render->m_cmdPre);
+			if (m_rendererInitialized)
+			{
+				rendererSubmit();
+			}
+			rendererExecCommands(m_render->m_cmdPost);
+
+			renderSemPost();
+
+			return m_exit;
+		}
+
+		void rendererInit();
+		void rendererShutdown();
+		void rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem);
+		void rendererDestroyIndexBuffer(IndexBufferHandle _handle);
+		void rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle);
+		void rendererDestroyVertexBuffer(VertexBufferHandle _handle);
+		void rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size);
+		void rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem);
+		void rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle);
+		void rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size);
+		void rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem);
+		void rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle);
+		void rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl);
+		void rendererDestroyVertexDecl(VertexDeclHandle _handle);
+		void rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem);
+		void rendererDestroyVertexShader(VertexShaderHandle _handle);
+		void rendererCreateFragmentShader(FragmentShaderHandle _handle, Memory* _mem);
+		void rendererDestroyFragmentShader(FragmentShaderHandle _handle);
+		void rendererCreateMaterial(MaterialHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
+		void rendererDestroyMaterial(FragmentShaderHandle _handle);
+		void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags);
+		void rendererDestroyTexture(TextureHandle _handle);
+		void rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
+		void rendererDestroyRenderTarget(RenderTargetHandle _handle);
+		void rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name);
+		void rendererDestroyUniform(UniformHandle _handle);
+		void rendererSaveScreenShot(Memory* _mem);
+		void rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size);
+
+		void rendererUpdateUniforms(ConstantBuffer* _constantBuffer, uint32_t _begin, uint32_t _end)
+		{
+			_constantBuffer->reset(_begin);
+			while (_constantBuffer->getPos() < _end)
+			{
+				uint32_t opcode = _constantBuffer->read();
+
+				if (ConstantType::End == opcode)
+				{
+					break;
+				}
+
+				ConstantType::Enum type;
+				uint16_t loc;
+				uint16_t num;
+				uint16_t copy;
+				ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy);
+
+				const char* data;
+				uint32_t size = g_constantTypeSize[type]*num;
+				data = _constantBuffer->read(size);
+				rendererUpdateUniform(loc, data, size);
+			}
+		}
+		
+		void rendererExecCommands(CommandBuffer& _cmdbuf)
+		{
+			_cmdbuf.reset();
+
+			bool end = false;
+
+			do
+			{
+				uint8_t command;
+				_cmdbuf.read(command);
+
+				switch (command)
+				{
+				case CommandBuffer::RendererInit:
+					{
+						rendererInit();
+						m_rendererInitialized = true;
+					}
+					break;
+
+				case CommandBuffer::RendererShutdown:
+					{
+						rendererShutdown();
+						m_rendererInitialized = false;
+						m_exit = true;
+					}
+					break;
+
+				case CommandBuffer::CreateIndexBuffer:
+					{
+						IndexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						rendererCreateIndexBuffer(handle, mem);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyIndexBuffer:
+					{
+						IndexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyIndexBuffer(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateVertexDecl:
+					{
+						VertexDeclHandle handle;
+						_cmdbuf.read(handle);
+
+						VertexDecl decl;
+						_cmdbuf.read(decl);
+
+						rendererCreateVertexDecl(handle, decl);
+					}
+					break;
+
+				case CommandBuffer::DestroyVertexDecl:
+					{
+						VertexDeclHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyVertexDecl(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateVertexBuffer:
+					{
+						VertexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						VertexDeclHandle declHandle;
+						_cmdbuf.read(declHandle);
+
+						rendererCreateVertexBuffer(handle, mem, declHandle);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyVertexBuffer:
+					{
+						VertexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyVertexBuffer(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateDynamicIndexBuffer:
+					{
+						IndexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						uint32_t size;
+						_cmdbuf.read(size);
+
+						rendererCreateDynamicIndexBuffer(handle, size);
+					}
+					break;
+
+				case CommandBuffer::UpdateDynamicIndexBuffer:
+					{
+						IndexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						uint32_t offset;
+						_cmdbuf.read(offset);
+
+						uint32_t size;
+						_cmdbuf.read(size);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						rendererUpdateDynamicIndexBuffer(handle, offset, size, mem);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyDynamicIndexBuffer:
+					{
+						IndexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyDynamicIndexBuffer(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateDynamicVertexBuffer:
+					{
+						VertexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						uint32_t size;
+						_cmdbuf.read(size);
+
+						rendererCreateDynamicVertexBuffer(handle, size);
+					}
+					break;
+
+				case CommandBuffer::UpdateDynamicVertexBuffer:
+					{
+						VertexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						uint32_t offset;
+						_cmdbuf.read(offset);
+
+						uint32_t size;
+						_cmdbuf.read(size);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						rendererUpdateDynamicVertexBuffer(handle, offset, size, mem);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyDynamicVertexBuffer:
+					{
+						VertexBufferHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyDynamicVertexBuffer(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateVertexShader:
+					{
+						VertexShaderHandle handle;
+						_cmdbuf.read(handle);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						rendererCreateVertexShader(handle, mem);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyVertexShader:
+					{
+						VertexShaderHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyVertexShader(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateFragmentShader:
+					{
+						FragmentShaderHandle handle;
+						_cmdbuf.read(handle);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						rendererCreateFragmentShader(handle, mem);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyFragmentShader:
+					{
+						FragmentShaderHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyFragmentShader(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateMaterial:
+					{
+						MaterialHandle handle;
+						_cmdbuf.read(handle);
+
+						VertexShaderHandle vsh;
+						_cmdbuf.read(vsh);
+
+						FragmentShaderHandle fsh;
+						_cmdbuf.read(fsh);
+
+						rendererCreateMaterial(handle, vsh, fsh);
+					}
+					break;
+
+				case CommandBuffer::DestroyMaterial:
+					{
+						FragmentShaderHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyMaterial(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateTexture:
+					{
+						TextureHandle handle;
+						_cmdbuf.read(handle);
+
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						uint32_t flags;
+						_cmdbuf.read(flags);
+
+						rendererCreateTexture(handle, mem, flags);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::DestroyTexture:
+					{
+						TextureHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyTexture(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateRenderTarget:
+					{
+						RenderTargetHandle handle;
+						_cmdbuf.read(handle);
+
+						uint16_t width;
+						_cmdbuf.read(width);
+
+						uint16_t height;
+						_cmdbuf.read(height);
+
+						uint32_t flags;
+						_cmdbuf.read(flags);
+
+						uint32_t textureFlags;
+						_cmdbuf.read(textureFlags);
+
+						rendererCreateRenderTarget(handle, width, height, flags, textureFlags);
+					}
+					break;
+
+				case CommandBuffer::DestroyRenderTarget:
+					{
+						RenderTargetHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyRenderTarget(handle);
+					}
+					break;
+
+				case CommandBuffer::CreateUniform:
+					{
+						UniformHandle handle;
+						_cmdbuf.read(handle);
+
+						ConstantType::Enum type;
+						_cmdbuf.read(type);
+
+						uint16_t num;
+						_cmdbuf.read(num);
+
+						uint8_t len;
+						_cmdbuf.read(len);
+
+						char name[256];
+						_cmdbuf.read(name, len);
+						name[len] = '\0';
+
+						rendererCreateUniform(handle, type, num, name);
+					}
+					break;
+
+				case CommandBuffer::DestroyUniform:
+					{
+						UniformHandle handle;
+						_cmdbuf.read(handle);
+
+						rendererDestroyUniform(handle);
+					}
+					break;
+
+				case CommandBuffer::SaveScreenShot:
+					{
+						Memory* mem;
+						_cmdbuf.read(mem);
+
+						rendererSaveScreenShot(mem);
+
+						release(mem);
+					}
+					break;
+
+				case CommandBuffer::End:
+					end = true;
+					break;
+
+				default:
+					BX_CHECK(false, "WTF!");
+					break;
+				}
+			} while (!end);
+		}
+
+		void rendererSubmit();
+
+#if BGFX_CONFIG_MULTITHREADED
+		void gameSemPost()
+		{
+// 			BX_TRACE("game post");
+			m_gameSem.post();
+		}
+
+		void gameSemWait()
+		{
+// 			BX_TRACE("game wait");
+			int64_t start = bx::getHPCounter();
+			m_gameSem.wait();
+			m_render->m_waitSubmit = bx::getHPCounter()-start;
+		}
+
+		void renderSemPost()
+		{
+// 			BX_TRACE("render post");
+			m_renderSem.post();
+		}
+
+		void renderSemWait()
+		{
+// 			BX_TRACE("render wait");
+			int64_t start = bx::getHPCounter();
+			m_renderSem.wait();
+			m_submit->m_waitRender = bx::getHPCounter() - start;
+		}
+
+		Semaphore m_renderSem;
+		Semaphore m_gameSem;
+
+#	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
+		HANDLE m_renderThread;
+#	else
+		pthread_t m_renderThread;
+#	endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
+
+#else
+		void gameSemPost()
+		{
+		}
+
+		void gameSemWait()
+		{
+		}
+
+		void renderSemPost()
+		{
+		}
+
+		void renderSemWait()
+		{
+		}
+#endif // BGFX_CONFIG_MULTITHREADED
+
+		Frame m_frame[2];
+		Frame* m_render;
+		Frame* m_submit;
+
+		uint64_t m_tempKeys[BGFX_CONFIG_MAX_DRAW_CALLS];
+		uint16_t m_tempValues[BGFX_CONFIG_MAX_DRAW_CALLS];
+
+		DynamicIndexBuffer m_dynamicIndexBuffers[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS];
+		DynamicVertexBuffer m_dynamicVertexBuffers[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
+
+		uint16_t m_numFreeDynamicIndexBufferHandles;
+		uint16_t m_numFreeDynamicVertexBufferHandles;
+		DynamicIndexBufferHandle m_freeDynamicIndexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS];
+		DynamicVertexBufferHandle m_freeDynamicVertexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
+
+		NonLocalAllocator m_dynamicIndexBufferAllocator;
+		HandleAlloc m_dynamicIndexBufferHandle;
+		NonLocalAllocator m_dynamicVertexBufferAllocator;
+		HandleAlloc m_dynamicVertexBufferHandle;
+
+		HandleAlloc m_indexBufferHandle;
+		HandleAlloc m_vertexDeclHandle;
+		HandleAlloc m_vertexBufferHandle;
+		HandleAlloc m_vertexShaderHandle;
+		HandleAlloc m_fragmentShaderHandle;
+		HandleAlloc m_materialHandle;
+		HandleAlloc m_textureHandle;
+		HandleAlloc m_renderTargetHandle;
+		HandleAlloc m_uniformHandle;
+
+		MaterialRef m_materialRef;
+		VertexDeclRef m_declRef;
+
+		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
+		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
+		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
+		Constant m_constant[BGFX_CONFIG_MAX_UNIFORMS];
+		uint16_t m_seq[BGFX_CONFIG_MAX_VIEWS];
+		uint16_t m_seqMask[BGFX_CONFIG_MAX_VIEWS];
+
+		Resolution m_resolution;
+		uint32_t m_frames;
+		uint32_t m_debug;
+
+		TextVideoMemBlitter m_textVideoMemBlitter;
+		ClearQuad m_clearQuad;
+
+#if BX_PLATFORM_WINDOWS
+		struct Window
+		{
+			Window()
+				: m_frame(true)
+				, m_update(false)
+			{
+			}
+
+			void init()
+			{
+				if (NULL == g_bgfxHwnd)
+				{					
+					HINSTANCE instance = (HINSTANCE)GetModuleHandle(NULL);
+
+					WNDCLASSEX wnd;
+					memset(&wnd, 0, sizeof(wnd) );
+					wnd.cbSize = sizeof(wnd);
+					wnd.lpfnWndProc = DefWindowProc;
+					wnd.hInstance = instance;
+					wnd.hIcon = LoadIcon(instance, IDI_APPLICATION);
+					wnd.hCursor = LoadCursor(instance, IDC_ARROW);
+					wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+					wnd.lpszClassName = "bgfx_letterbox";
+					wnd.hIconSm = LoadIcon(instance, IDI_APPLICATION);
+					RegisterClassExA(&wnd);
+
+					memset(&wnd, 0, sizeof(wnd) );
+					wnd.cbSize = sizeof(wnd);
+					wnd.style = CS_HREDRAW | CS_VREDRAW;
+					wnd.lpfnWndProc = wndProc;
+					wnd.hInstance = instance;
+					wnd.hIcon = LoadIcon(instance, IDI_APPLICATION);
+					wnd.hCursor = LoadCursor(instance, IDC_ARROW);
+					wnd.lpszClassName = "bgfx";
+					wnd.hIconSm = LoadIcon(instance, IDI_APPLICATION);
+					RegisterClassExA(&wnd);
+
+					HWND hwnd = CreateWindowA("bgfx_letterbox"
+						, "BGFX"
+						, WS_POPUP|WS_SYSMENU
+						, -32000
+						, -32000
+						, 0
+						, 0
+						, NULL
+						, NULL
+						, instance
+						, 0
+						);
+
+					g_bgfxHwnd = CreateWindowA("bgfx"
+						, "BGFX"
+						, WS_OVERLAPPEDWINDOW|WS_VISIBLE
+						, 0
+						, 0
+						, BGFX_DEFAULT_WIDTH
+						, BGFX_DEFAULT_HEIGHT
+						, hwnd
+						, NULL
+						, instance
+						, 0
+						);
+
+					m_update = true;
+				}
+			}
+
+			LRESULT process(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam)
+			{
+				switch (_id)
+				{
+				case WM_CLOSE:
+					TerminateProcess(GetCurrentProcess(), 0);
+					break;
+
+				case WM_SIZING:
+					{
+						RECT clientRect;
+						GetClientRect(_hwnd, &clientRect);
+						uint32_t width = clientRect.right-clientRect.left;
+						uint32_t height = clientRect.bottom-clientRect.top;
+
+						RECT& rect = *(RECT*)_lparam;
+						uint32_t frameWidth = rect.right-rect.left - width;
+						uint32_t frameHeight = rect.bottom-rect.top - height;
+
+						switch (_wparam)
+						{
+						case WMSZ_LEFT:
+						case WMSZ_RIGHT:
+							{
+								float aspectRatio = 1.0f/m_aspectRatio;
+								width = bx::uint32_max(BGFX_DEFAULT_WIDTH/4, width);
+								height = uint32_t(float(width)*aspectRatio);
+							}
+							break;
+
+						default:
+							{
+								float aspectRatio = m_aspectRatio;
+								height = bx::uint32_max(BGFX_DEFAULT_HEIGHT/4, height);
+								width = uint32_t(float(height)*aspectRatio);
+							}
+							break;
+						}
+
+						rect.right = rect.left + width + frameWidth;
+						rect.bottom = rect.top + height + frameHeight;
+
+						SetWindowPos(_hwnd
+							, HWND_TOP
+							, rect.left
+							, rect.top
+							, (rect.right-rect.left)
+							, (rect.bottom-rect.top)
+							, SWP_SHOWWINDOW
+							);
+					}
+					return 0;
+
+				case WM_SYSCOMMAND:
+					switch (_wparam)
+					{
+					case SC_MINIMIZE:
+					case SC_RESTORE:
+						{
+							HWND parent = GetWindow(_hwnd, GW_OWNER);
+							if (NULL != parent)
+							{
+								PostMessage(parent, _id, _wparam, _lparam);
+							}
+						}
+					}
+					break;
+
+				case WM_KEYDOWN:
+				case WM_SYSKEYDOWN:
+					if ((WM_KEYDOWN == _id && VK_F11 == _wparam)
+					||  (WM_SYSKEYDOWN == _id && VK_RETURN == _wparam))
+					{
+						toggleWindowFrame();
+					}
+					break;
+
+				default:
+					break;
+				}
+
+				return DefWindowProc(_hwnd, _id, _wparam, _lparam);
+			}
+
+			void update()
+			{
+				if (m_update)
+				{
+					MSG msg;
+					msg.message = WM_NULL;
+					if (0 != PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) )
+					{
+						TranslateMessage(&msg);
+						DispatchMessage(&msg);
+					}
+				}
+			}
+
+			void adjust(uint32_t _width, uint32_t _height, bool _windowFrame)
+			{
+				m_width = _width;
+				m_height = _height;
+				m_aspectRatio = float(_width)/float(_height);
+
+				ShowWindow(g_bgfxHwnd, SW_SHOWNORMAL);
+				RECT rect;
+				RECT newrect = {0, 0, (LONG)_width, (LONG)_height};
+				DWORD style = WS_POPUP|WS_SYSMENU;
+
+				if (m_frame)
+				{
+					GetWindowRect(g_bgfxHwnd, &m_rect);
+					m_style = GetWindowLong(g_bgfxHwnd, GWL_STYLE);
+				}
+
+				if (_windowFrame)
+				{
+					rect = m_rect;
+					style = m_style;
+				}
+				else
+				{
+#if defined(__MINGW32__)
+					rect = m_rect;
+					style = m_style;
+#else
+					HMONITOR monitor = MonitorFromWindow(g_bgfxHwnd, MONITOR_DEFAULTTONEAREST);
+					MONITORINFO mi;
+					mi.cbSize = sizeof(mi);
+					GetMonitorInfo(monitor, &mi);
+					newrect = mi.rcMonitor;
+					rect = mi.rcMonitor;
+#endif // !defined(__MINGW__)
+				}
+
+				SetWindowLong(g_bgfxHwnd, GWL_STYLE, style);
+				AdjustWindowRect(&newrect, style, FALSE);
+				UpdateWindow(g_bgfxHwnd);
+
+				if (rect.left == -32000
+				||  rect.top == -32000)
+				{
+					rect.left = 0;
+					rect.top = 0;
+				}
+
+				int32_t left = rect.left;
+				int32_t top = rect.top;
+				int32_t width = (newrect.right-newrect.left);
+				int32_t height = (newrect.bottom-newrect.top);
+
+				if (!_windowFrame)
+				{
+					float aspectRatio = 1.0f/m_aspectRatio;
+					width = bx::uint32_max(BGFX_DEFAULT_WIDTH/4, width);
+					height = uint32_t(float(width)*aspectRatio);
+
+					left = newrect.left+(newrect.right-newrect.left-width)/2;
+					top = newrect.top+(newrect.bottom-newrect.top-height)/2;
+				}
+
+				HWND parent = GetWindow(g_bgfxHwnd, GW_OWNER);
+				if (NULL != parent)
+				{
+					if (_windowFrame)
+					{
+						SetWindowPos(parent
+							, HWND_TOP
+							, -32000
+							, -32000
+							, 0
+							, 0
+							, SWP_SHOWWINDOW
+							);
+					}
+					else
+					{
+						SetWindowPos(parent
+							, HWND_TOP
+							, newrect.left
+							, newrect.top
+							, newrect.right-newrect.left
+							, newrect.bottom-newrect.top
+							, SWP_SHOWWINDOW
+							);
+					}
+				}
+
+				SetWindowPos(g_bgfxHwnd
+					, HWND_TOP
+					, left
+					, top
+					, width
+					, height
+					, SWP_SHOWWINDOW
+					);
+
+				ShowWindow(g_bgfxHwnd, SW_RESTORE);
+
+				m_frame = _windowFrame;
+			}
+
+		private:
+			static LRESULT CALLBACK wndProc(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam);
+
+			void toggleWindowFrame()
+			{
+				adjust(m_width, m_height, !m_frame);
+			}
+
+			RECT m_rect;
+			DWORD m_style;
+			uint32_t m_width;
+			uint32_t m_height;
+			float m_aspectRatio;
+			bool m_frame;
+			bool m_update;
+		};
+
+		Window m_window;
+#endif // BX_PLATFORM_WINDOWS
+
+		bool m_rendererInitialized;
+		bool m_exit;
+	};
+
+} // namespace bgfx
+
+#endif // __BGFX_P_H__

+ 31 - 30
src/fs_clear_dx11.bin.h

@@ -1,37 +1,38 @@
-static const uint8_t fs_clear_dx11[539] =
+static const uint8_t fs_clear_dx11[560] =
 {
-	0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x44, 0x58, 0x42, 0x43, 0xda, 0x0f, 0xc3, 0x91, 0x70, 0x6f, // ......DXBC....po
-	0xd4, 0x7b, 0xeb, 0xe0, 0x21, 0x07, 0x79, 0xd8, 0x54, 0xd4, 0x01, 0x00, 0x00, 0x00, 0x14, 0x02, // .{..!.y.T.......
-	0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, // ......4.........
-	0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x00, // ..4...x...RDEFp.
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, // ..............<.
-	0x00, 0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x52, 0x44, // ..........<...RD
-	0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, // 11<....... ...(.
-	0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, // ..$...........Mi
-	0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, // crosoft (R) HLSL
-	0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, //  Shader Compiler
-	0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, //  9.29.952.3111..
-	0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, // ..ISGNL.........
-	0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, // ..8.............
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........D.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, // ................
-	0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, // ..SV_POSITION.CO
-	0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, // LOR...OSGN,.....
-	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...... .........
-	0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, // ..............SV
-	0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x3c, 0x00, // _TARGET...SHEX<.
-	0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x62, 0x10, // ..P.......j...b.
-	0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, // ..........e.... 
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, // ......6.... ....
-	0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, // ..F.......>...ST
-	0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // AT..............
-	0x00, 0x00, 0x02, 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, // ................
+	0x02, 0x00, 0x0b, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x05, // ...SV_POSITION..
+	0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x44, 0x58, 0x42, 0x43, 0xda, // COLOR......DXBC.
+	0x0f, 0xc3, 0x91, 0x70, 0x6f, 0xd4, 0x7b, 0xeb, 0xe0, 0x21, 0x07, 0x79, 0xd8, 0x54, 0xd4, 0x01, // ...po.{..!.y.T..
+	0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, // ...........4....
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x52, // .......4...x...R
+	0x44, 0x45, 0x46, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // DEFp............
+	0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, // ...<...........<
+	0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, // ...RD11<....... 
+	0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, // ...(...$........
+	0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, // ...Microsoft (R)
+	0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, //  HLSL Shader Com
+	0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, // piler 9.29.952.3
+	0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, // 111....ISGNL....
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // .......8........
+	0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, // ...............D
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, // ................
+	0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, // .......SV_POSITI
+	0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, // ON.COLOR...OSGN,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, // ........... ....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, // ................
+	0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, // ...SV_TARGET...S
+	0x48, 0x45, 0x58, 0x3c, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6a, // HEX<...P.......j
+	0x08, 0x00, 0x01, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, // ...b...........e
+	0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, // .... ......6....
+	0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, //  ......F.......>
+	0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // ...STAT.........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 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, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 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,                               // ...........
 };

+ 55 - 52
src/fs_debugfont_dx11.bin.h

@@ -1,58 +1,61 @@
-static const uint8_t fs_debugfont_dx11[879] =
+static const uint8_t fs_debugfont_dx11[917] =
 {
-	0x00, 0x00, 0x00, 0x00, 0x68, 0x03, 0x44, 0x58, 0x42, 0x43, 0x86, 0xad, 0xb6, 0x81, 0xa7, 0x03, // ....h.DXBC......
-	0x01, 0x3e, 0x2a, 0x57, 0xe1, 0x88, 0xd8, 0x74, 0xb7, 0x81, 0x01, 0x00, 0x00, 0x00, 0x68, 0x03, // .>*W...t......h.
-	0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x80, 0x01, // ......4.........
-	0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xb8, 0x00, // ..........RDEF..
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, // ..............<.
-	0x00, 0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x52, 0x44, // ..............RD
-	0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, // 11<....... ...(.
-	0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, // ..$...........|.
-	0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, // ..............|.
-	0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x75, 0x5f, // ..............u_
-	0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, // texColor.Microso
-	0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, // ft (R) HLSL Shad
-	0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, // er Compiler 9.29
-	0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x49, 0x53, 0x47, 0x4e, 0x84, 0x00, // .952.3111.ISGN..
-	0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........h.....
-	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, // ................
-	0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..t.............
-	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, // ..........t.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, // ................
-	0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..z.............
-	0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, // ..........SV_POS
-	0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, // ITION.COLOR.TEXC
-	0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, // OORD..OSGN,.....
-	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...... .........
-	0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, // ..............SV
-	0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x10, 0x01, // _TARGET...SHEX..
-	0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5a, 0x00, // ..P...D...j...Z.
-	0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, // ...`......X....p
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, // ......UU..b.....
-	0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x02, 0x00, // ......b.........
-	0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x65, 0x00, // ..b...2.......e.
-	0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x02, 0x00, // ... ......h.....
-	0x00, 0x00, 0x45, 0x00, 0x00, 0x8b, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x12, 0x00, // ..E.......CU....
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x7e, // ......F.......F~
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .......`........
-	0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, // ..........F.....
-	0x00, 0x00, 0x46, 0x1e, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, // ..F...A.......2.
-	0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, // ..F.......F.....
-	0x00, 0x00, 0x31, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, // ..1...........:.
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x81, 0x80, 0x80, 0x3b, 0x0d, 0x00, // .......@.....;..
-	0x04, 0x03, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, // ..........6.... 
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, // ......F.......>.
-	0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, // ..STAT..........
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x04, 0x00, 0x0b, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x05, // ...SV_POSITION..
+	0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x01, 0x05, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x08, 0x54, 0x45, // COLOR..COLOR..TE
+	0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x00, 0x68, 0x03, 0x44, 0x58, 0x42, 0x43, // XCOORD....h.DXBC
+	0x86, 0xad, 0xb6, 0x81, 0xa7, 0x03, 0x01, 0x3e, 0x2a, 0x57, 0xe1, 0x88, 0xd8, 0x74, 0xb7, 0x81, // .......>*W...t..
+	0x01, 0x00, 0x00, 0x00, 0x68, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, // ....h.......4...
+	0xf4, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, // ................
+	0x52, 0x44, 0x45, 0x46, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // RDEF............
+	0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, // ....<...........
+	0x87, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, // ....RD11<.......
+	0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, //  ...(...$.......
+	0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....|...........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ................
+	0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, // ....|...........
+	0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ................
+	0x0c, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x4d, // ....u_texColor.M
+	0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, // icrosoft (R) HLS
+	0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, // L Shader Compile
+	0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, // r 9.29.952.3111.
+	0x49, 0x53, 0x47, 0x4e, 0x84, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ISGN............
+	0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // h...............
+	0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........t.......
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, // ................
+	0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // t...............
+	0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........z.......
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, // ................
+	0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, // SV_POSITION.COLO
+	0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, // R.TEXCOORD..OSGN
+	0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, // ,........... ...
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, // ....SV_TARGET...
+	0x53, 0x48, 0x45, 0x58, 0x10, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, // SHEX....P...D...
+	0x6a, 0x08, 0x00, 0x01, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // j...Z....`......
+	0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, // X....p......UU..
+	0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, // b...........b...
+	0xf2, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, // ........b...2...
+	0x03, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....e.... ......
+	0x68, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x8b, 0xc2, 0x00, 0x00, 0x80, // h.......E.......
+	0x43, 0x55, 0x15, 0x00, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, // CU..........F...
+	0x03, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, // ....F~.......`..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ................
+	0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, // F.......F...A...
+	0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....2...........
+	0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ........F.......
+	0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, // F.......1.......
+	0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, // ....:........@..
+	0x81, 0x80, 0x80, 0x3b, 0x0d, 0x00, 0x04, 0x03, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ...;............
+	0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, // 6.... ......F...
+	0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, // ....>...STAT....
+	0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, // ................
+	0x02, 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, 0x01, 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, 0x01, 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, 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,                                                                   // .....
 };

+ 225 - 90
src/renderer_d3d11.cpp

@@ -42,7 +42,7 @@ namespace bgfx
 
 	static const D3D11_COMPARISON_FUNC s_depthFunc[] =
 	{
-		(D3D11_COMPARISON_FUNC)0, // ignored
+		D3D11_COMPARISON_LESS, // ignored
 		D3D11_COMPARISON_LESS,
 		D3D11_COMPARISON_LESS_EQUAL,
 		D3D11_COMPARISON_EQUAL,
@@ -60,6 +60,19 @@ namespace bgfx
 		D3D11_CULL_BACK,
 	};
 
+	static DXGI_FORMAT s_colorFormat[] =
+	{
+		DXGI_FORMAT_UNKNOWN, // ignored
+		DXGI_FORMAT_R8G8B8A8_UNORM,
+		DXGI_FORMAT_R32_FLOAT,
+	};
+
+	static const DXGI_FORMAT s_depthFormat[] =
+	{
+		DXGI_FORMAT_UNKNOWN, // ignored
+		DXGI_FORMAT_D24_UNORM_S8_UINT,
+	};
+
 	static const D3D11_TEXTURE_ADDRESS_MODE s_textureAddress[] =
 	{
 		D3D11_TEXTURE_ADDRESS_WRAP,
@@ -155,7 +168,7 @@ namespace bgfx
 
 						default:
 						case 4:
-							format = DXGI_FORMAT_R8G8B8A8_UNORM; //DXGI_FORMAT_R8G8B8A8_UINT;
+							format = DXGI_FORMAT_R8G8B8A8_UINT;
 							break;
 						}
 					}
@@ -229,10 +242,23 @@ namespace bgfx
 		return elem;
 	}
 
+	struct TextureStage
+	{
+		TextureStage()
+		{
+			memset(m_srv, 0, sizeof(m_srv) );
+			memset(m_sampler, 0, sizeof(m_sampler) );
+		}
+
+		ID3D11ShaderResourceView* m_srv[BGFX_STATE_TEX_COUNT];
+		ID3D11SamplerState* m_sampler[BGFX_STATE_TEX_COUNT];
+	};
+
 	struct RendererContext
 	{
 		RendererContext()
-			: m_vsChanges(0)
+			: m_wireframe(false)
+			, m_vsChanges(0)
 			, m_fsChanges(0)
 		{
 		}
@@ -242,18 +268,10 @@ namespace bgfx
 			m_d3d11dll = LoadLibrary("d3d11.dll");
 			BGFX_FATAL(NULL != m_d3d11dll, Fatal::D3D11_UnableToInitialize, "Failed to load d3d11.dll.");
 
-			m_dxgidll = LoadLibrary("dxgi.dll");
-			BGFX_FATAL(NULL != m_dxgidll, Fatal::D3D11_UnableToInitialize, "Failed to load dxgi.dll.");
-
 			PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN d3D11CreateDeviceAndSwapChain = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(m_d3d11dll, "D3D11CreateDeviceAndSwapChain");
 			BGFX_FATAL(NULL != d3D11CreateDeviceAndSwapChain, Fatal::D3D11_UnableToInitialize, "Function D3D11CreateDeviceAndSwapChain not found.");
 
-			CreateDXGIFactoryFn createDXGIFactory = (CreateDXGIFactoryFn)GetProcAddress(m_dxgidll, "CreateDXGIFactory");
-			BGFX_FATAL(NULL != createDXGIFactory, Fatal::D3D11_UnableToInitialize, "Function CreateDXGIFactory not found.");
-
 			HRESULT hr;
-// 			IDXGIFactory* factory;
-// 			hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&factory) );
 
 			D3D_FEATURE_LEVEL features[] =
 			{
@@ -296,39 +314,19 @@ namespace bgfx
 				);
 			BGFX_FATAL(SUCCEEDED(hr), Fatal::D3D11_UnableToInitialize, "Unable to create Direct3D11 device.");
 
-			ID3D11Texture2D* color;
-			DX_CHECK(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&color) );
-			DX_CHECK(m_device->CreateRenderTargetView(color, NULL, &m_backBufferColor) );
-			DX_RELEASE(color, 0);
-
-			D3D11_TEXTURE2D_DESC dsd;
-			dsd.Width = m_scd.BufferDesc.Width;
-			dsd.Height = m_scd.BufferDesc.Height;
-			dsd.MipLevels = 1;
-			dsd.ArraySize = 1;
-			dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
-			dsd.SampleDesc = m_scd.SampleDesc;
-			dsd.Usage = D3D11_USAGE_DEFAULT;
-			dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
-			dsd.CPUAccessFlags = 0;
-			dsd.MiscFlags = 0;
-
-			ID3D11Texture2D* depthStencil;
-			DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
-			DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_backBufferDepthStencil) );
-			DX_RELEASE(depthStencil, 0);
-
-			m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);
-
 			for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
 			{
 				m_predefinedUniforms[ii].create(ConstantType::Uniform4x4fv, 1, false);
 				m_uniformReg.reg(getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
 			}
+
+			postReset();
 		}
 
 		void shutdown()
 		{
+			preReset();
+
 			m_deviceCtx->ClearState();
 
 			invalidateCache();
@@ -373,16 +371,49 @@ namespace bgfx
 				m_predefinedUniforms[ii].destroy();
 			}
 
-			DX_RELEASE(m_backBufferDepthStencil, 0);
-			DX_RELEASE(m_backBufferColor, 0);
 			DX_RELEASE(m_swapChain, 0);
 			DX_RELEASE(m_deviceCtx, 0);
 			DX_RELEASE(m_device, 0);
 
-			FreeLibrary(m_dxgidll);
 			FreeLibrary(m_d3d11dll);
 		}
 
+		void preReset()
+		{
+			DX_RELEASE(m_backBufferDepthStencil, 0);
+			DX_RELEASE(m_backBufferColor, 0);
+
+//			invalidateCache();
+		}
+
+		void postReset()
+		{
+			ID3D11Texture2D* color;
+			DX_CHECK(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&color) );
+
+			DX_CHECK(m_device->CreateRenderTargetView(color, NULL, &m_backBufferColor) );
+			DX_RELEASE(color, 0);
+
+			D3D11_TEXTURE2D_DESC dsd;
+			dsd.Width = m_scd.BufferDesc.Width;
+			dsd.Height = m_scd.BufferDesc.Height;
+			dsd.MipLevels = 1;
+			dsd.ArraySize = 1;
+			dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+			dsd.SampleDesc = m_scd.SampleDesc;
+			dsd.Usage = D3D11_USAGE_DEFAULT;
+			dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+			dsd.CPUAccessFlags = 0;
+			dsd.MiscFlags = 0;
+
+			ID3D11Texture2D* depthStencil;
+			DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
+			DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_backBufferDepthStencil) );
+			DX_RELEASE(depthStencil, 0);
+
+			m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);
+		}
+
 		void flip()
 		{
 			if (NULL != m_swapChain)
@@ -411,30 +442,19 @@ namespace bgfx
 				m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
 				m_textVideoMem.clear();
 
-#if 0
-				D3DDEVICE_CREATION_PARAMETERS dcp;
-				DX_CHECK(m_device->GetCreationParameters(&dcp) );
-
-				D3DDISPLAYMODE dm;
-				DX_CHECK(m_d3d9->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm) );
-
-				m_params.BackBufferFormat = dm.Format;
-
-				m_params.BackBufferWidth = _resolution.m_width;
-				m_params.BackBufferHeight = _resolution.m_height;
-				m_params.FullScreen_RefreshRateInHz = BGFX_RESET_FULLSCREEN == (m_flags&BGFX_RESET_FULLSCREEN_MASK) ? 60 : 0;
-				m_params.PresentationInterval = !!(m_flags&BGFX_RESET_VSYNC) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
+				m_scd.BufferDesc.Width = _resolution.m_width;
+				m_scd.BufferDesc.Height = _resolution.m_height;
 
-				updateMsaa();
+				preReset();
 
-				Msaa& msaa = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
-				m_params.MultiSampleType = msaa.m_type;
-				m_params.MultiSampleQuality = msaa.m_quality;
+				DX_CHECK(m_swapChain->ResizeBuffers(2
+					, m_scd.BufferDesc.Width
+					, m_scd.BufferDesc.Height
+					, m_scd.BufferDesc.Format
+					, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
+					) );
 
-				preReset();
-				DX_CHECK(m_device->Reset(&m_params) );
 				postReset();
-#endif // 0
 			}
 		}
 
@@ -483,13 +503,13 @@ namespace bgfx
 			}
 			else
 			{
+				RenderTarget& renderTarget = m_renderTargets[_rt.idx];
+				m_deviceCtx->OMSetRenderTargets(1, &renderTarget.m_rtv, m_backBufferDepthStencil);
 			}
 		}
 
-		void clear(const Rect& _rect, const Clear& _clear)
+		void clear(const Clear& _clear)
 		{
-			
-
 //			DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE) );
 //			DX_CHECK(s_renderCtx.m_device->SetScissorRect(&rc) );
 
@@ -521,7 +541,7 @@ namespace bgfx
 			{
 				D3D11_INPUT_ELEMENT_DESC vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
 				D3D11_INPUT_ELEMENT_DESC* elem = fillVertexDecl(vertexElements, Attrib::Count, _vertexDecl);
-				DX_CHECK(m_device->CreateInputLayout(vertexElements
+				/*DX_CHECK*/(m_device->CreateInputLayout(vertexElements
 					, uint32_t(elem-vertexElements)
 					, _material.m_vsh->m_code->data
 					, _material.m_vsh->m_code->size
@@ -591,9 +611,19 @@ namespace bgfx
 			m_deviceCtx->OMSetDepthStencilState(dss, 0);
 		}
 
+		void setDebugWireframe(bool _wireframe)
+		{
+			if (m_wireframe != _wireframe)
+			{
+				m_wireframe = _wireframe;
+				m_rasterizerStateCache.invalidate();
+			}
+		}
+
 		void setRasterizerState(uint64_t _state, bool _wireframe = false)
 		{
 			_state &= BGFX_STATE_CULL_MASK;
+			_state |= _wireframe ? BGFX_STATE_PT_LINES : BGFX_STATE_NONE;
 
 			ID3D11RasterizerState* rs = m_rasterizerStateCache.find(_state);
 			if (NULL == rs)
@@ -613,7 +643,11 @@ namespace bgfx
 			m_deviceCtx->RSSetState(rs);
 		}
 
-
+		void commitTextureStage()
+		{
+			m_deviceCtx->PSSetShaderResources(0, BGFX_STATE_TEX_COUNT, m_textureStage.m_srv);
+			m_deviceCtx->PSSetSamplers(0, BGFX_STATE_TEX_COUNT, m_textureStage.m_sampler);
+		}
 
 		void saveScreenShot(Memory* _mem)
 		{
@@ -654,13 +688,14 @@ namespace bgfx
 		}
 
 		HMODULE m_d3d11dll;
-		HMODULE m_dxgidll;
 		IDXGISwapChain* m_swapChain;
 		ID3D11Device* m_device;
 		ID3D11DeviceContext* m_deviceCtx;
 		ID3D11RenderTargetView* m_backBufferColor;
 		ID3D11DepthStencilView* m_backBufferDepthStencil;
 
+		bool m_wireframe;
+
 		DXGI_SWAP_CHAIN_DESC m_scd;
 		uint32_t m_flags;
 
@@ -685,6 +720,8 @@ namespace bgfx
 		TextVideoMem m_textVideoMem;
 		RenderTargetHandle m_rt;
 
+		TextureStage m_textureStage;
+
 		Material* m_currentMaterial;
 
 		uint8_t m_vsScratch[64<<10];
@@ -888,7 +925,7 @@ namespace bgfx
 			
  		s_renderCtx.setBlendState(state);
  		s_renderCtx.setDepthStencilState(state);
- 		s_renderCtx.setRasterizerState(state);
+ 		s_renderCtx.setRasterizerState(state, false);
 
 		Material& material = s_renderCtx.m_materials[m_material.idx];
 		s_renderCtx.m_currentMaterial = &material;
@@ -916,6 +953,7 @@ namespace bgfx
 
 		s_renderCtx.commitShaderConstants();
 		s_renderCtx.m_textures[m_texture.idx].commit(0);
+		s_renderCtx.commitTextureStage();
 	}
 
 	void TextVideoMemBlitter::render(uint32_t _numIndices)
@@ -942,28 +980,19 @@ namespace bgfx
 		&&  width == _rect.m_width
 		&&  height == _rect.m_height)
 		{
-			s_renderCtx.clear(_rect, _clear);
+			s_renderCtx.clear(_clear);
 		}
 		else
 		{
 			ID3D11DeviceContext* deviceCtx = s_renderCtx.m_deviceCtx;
 
-			D3D11_VIEWPORT vp;
-			vp.TopLeftX = _rect.m_x;
-			vp.TopLeftY = _rect.m_y;
-			vp.Width = (float)_rect.m_width;
-			vp.Height = (float)_rect.m_height;
-			vp.MinDepth = 0.0f;
-			vp.MaxDepth = 1.0f;
-			deviceCtx->RSSetViewports(1, &vp);
-
 			uint64_t state = 0;
 			state |= _clear.m_flags & BGFX_CLEAR_COLOR_BIT ? BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE : 0;
 			state |= _clear.m_flags & BGFX_CLEAR_DEPTH_BIT ? BGFX_STATE_DEPTH_WRITE : 0;
 
 			s_renderCtx.setBlendState(state);
 			s_renderCtx.setDepthStencilState(state);
-			s_renderCtx.setRasterizerState(state);
+			s_renderCtx.setRasterizerState(state, false);
 
 			Material& material = s_renderCtx.m_materials[m_material.idx];
 			s_renderCtx.m_currentMaterial = &material;
@@ -989,7 +1018,7 @@ namespace bgfx
 				vertex->m_x = -1.0f;
 				vertex->m_y = -1.0f;
 				vertex->m_z = _clear.m_depth;
-				vertex->m_abgr = rand(); //bx::endianSwap(_clear.m_rgba);
+				vertex->m_abgr = bx::endianSwap(_clear.m_rgba);
 				vertex++;
 				vertex->m_x =  1.0f;
 				vertex->m_y = -1.0f;
@@ -1024,6 +1053,27 @@ namespace bgfx
 		m_constantBuffer = ConstantBuffer::create(1024);
 
 		StreamRead stream(_mem->data, _mem->size);
+
+		uint8_t numAttr;
+		stream.read(numAttr);
+
+		for (uint8_t ii = 0; ii < numAttr; ++ii)
+		{
+			uint8_t semanticIndex;
+			stream.read(semanticIndex);
+
+			uint8_t len;
+			stream.read(len);
+
+			char temp[256];
+			memcpy(temp, stream.getDataPtr(), len);
+			temp[len] = '\0';
+
+			BX_TRACE("\t: %s %d", temp, semanticIndex);
+
+			stream.skip(len);
+		}
+
 		uint16_t count;
 		stream.read(count);
 
@@ -1243,7 +1293,15 @@ namespace bgfx
 						if (getRawImageData(dds, 0, lod, _mem, mip) )
 						{
 							srd[kk].pSysMem = mip.m_data;
-							srd[kk].SysMemPitch = mip.m_width*mip.m_bpp;
+							if (TextureFormat::Unknown > dds.m_type)
+							{
+								srd[kk].SysMemPitch = (mip.m_width/4)*mip.m_blockSize;
+							}
+							else
+							{
+								srd[kk].SysMemPitch = mip.m_width*mip.m_bpp;
+							}
+
 							srd[kk].SysMemSlicePitch = 0;
 							++kk;
 						}
@@ -1338,18 +1396,71 @@ namespace bgfx
 
 	void Texture::commit(uint8_t _stage)
 	{
-		s_renderCtx.m_deviceCtx->PSSetShaderResources(0, 1, &m_ptr);
-		s_renderCtx.m_deviceCtx->PSSetSamplers(0, 1, &m_sampler);
+		s_renderCtx.m_textureStage.m_srv[_stage] = m_ptr;
+		s_renderCtx.m_textureStage.m_sampler[_stage] = m_sampler;
 	}
 
 	void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
 	{
+		m_width = _width;
+		m_height = _height;
+		m_flags = _flags;
+
+		uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
+
+		D3D11_TEXTURE2D_DESC desc;
+		desc.Width = _width;
+		desc.Height = _height;
+		desc.MipLevels = 1;
+		desc.ArraySize = 1;
+		desc.Format = s_colorFormat[colorFormat];
+		desc.SampleDesc.Count = 1;
+		desc.SampleDesc.Quality = 0;
+		desc.Usage = D3D11_USAGE_DEFAULT;
+		desc.BindFlags = D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET;
+		desc.CPUAccessFlags = 0;
+		desc.MiscFlags = 0;
+
+		DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, NULL, &m_colorTexture) );
+		DX_CHECK(s_renderCtx.m_device->CreateRenderTargetView(m_colorTexture, NULL, &m_rtv) );
+		DX_CHECK(s_renderCtx.m_device->CreateShaderResourceView(m_colorTexture, NULL, &m_srv) );
+
+		m_sampler = s_renderCtx.m_samplerStateCache.find(_flags);
+		if (NULL == m_sampler)
+		{
+			D3D11_SAMPLER_DESC desc;
+			desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+			desc.AddressU = s_textureAddress[(_textureFlags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
+			desc.AddressV = s_textureAddress[(_textureFlags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT];
+			desc.AddressW = s_textureAddress[(_textureFlags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT];
+			desc.MipLODBias = 0.0f;
+			desc.MaxAnisotropy = 1;
+			desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
+			desc.BorderColor[0] = 0.0f;
+			desc.BorderColor[1] = 0.0f;
+			desc.BorderColor[2] = 0.0f;
+			desc.BorderColor[3] = 0.0f;
+			desc.MinLOD = 0;
+			desc.MaxLOD = D3D11_FLOAT32_MAX;
+			s_renderCtx.m_device->CreateSamplerState(&desc, &m_sampler);
+
+			s_renderCtx.m_samplerStateCache.add(_flags, m_sampler);
+		}
+	}
+
+	void RenderTarget::destroy()
+	{
+		DX_RELEASE(m_srv, 0);
+		DX_RELEASE(m_rtv, 0);
+		DX_RELEASE(m_colorTexture, 0);
 
+		m_flags = 0;
 	}
 
 	void RenderTarget::commit(uint8_t _stage)
 	{
-
+		s_renderCtx.m_textureStage.m_srv[_stage] = m_srv;
+		s_renderCtx.m_textureStage.m_sampler[_stage] = m_sampler;
 	}
 
 	void Uniform::create(ConstantType::Enum _type, uint16_t _num, bool _alloc)
@@ -1559,7 +1670,9 @@ namespace bgfx
 			matrix_mul(viewProj[ii].val, m_render->m_view[ii].val, m_render->m_proj[ii].val);
 		}
 
-//		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_FILLMODE, m_render->m_debug&BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID) );
+		bool wireframe = !!(m_render->m_debug&BGFX_DEBUG_WIREFRAME);
+		s_renderCtx.setDebugWireframe(wireframe);
+
 		uint16_t materialIdx = invalidHandle;
 		SortKey key;
 		uint8_t view = 0xff;
@@ -1621,7 +1734,7 @@ namespace bgfx
 
 					s_renderCtx.setBlendState(BGFX_STATE_DEFAULT);
 					s_renderCtx.setDepthStencilState(BGFX_STATE_DEFAULT);
-					s_renderCtx.setRasterizerState(BGFX_STATE_DEFAULT);
+					s_renderCtx.setRasterizerState(BGFX_STATE_DEFAULT, wireframe);
 
 					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
 					if (primType != s_primType[primIndex])
@@ -1649,7 +1762,7 @@ namespace bgfx
 
 					if ( (BGFX_STATE_CULL_MASK) & changedFlags)
 					{
-						s_renderCtx.setRasterizerState(newFlags);
+						s_renderCtx.setRasterizerState(newFlags, wireframe);
 					}
 				}
 
@@ -1812,6 +1925,7 @@ namespace bgfx
 
 //				if (BGFX_STATE_TEX_MASK & changedFlags)
 				{
+					uint32_t changes = 0;
 					uint64_t flag = BGFX_STATE_TEX0;
 					for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
 					{
@@ -1826,11 +1940,11 @@ namespace bgfx
 								switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
 								{
 								case BGFX_SAMPLER_TEXTURE:
-//									s_renderCtx.m_textures[sampler.m_idx].commit(stage);
+									s_renderCtx.m_textures[sampler.m_idx].commit(stage);
 									break;
 
 								case BGFX_SAMPLER_RENDERTARGET_COLOR:
-//									s_renderCtx.m_renderTargets[sampler.m_idx].commit(stage);
+									s_renderCtx.m_renderTargets[sampler.m_idx].commit(stage);
 									break;
 
 								case BGFX_SAMPLER_RENDERTARGET_DEPTH:
@@ -1840,13 +1954,21 @@ namespace bgfx
 							}
 							else
 							{
-//								DX_CHECK(device->SetTexture(stage, NULL) );
+								s_renderCtx.m_textureStage.m_srv[stage] = NULL;
+								s_renderCtx.m_textureStage.m_sampler[stage] = NULL;
 							}
+
+							++changes;
 						}
 
 						current = sampler;
 						flag <<= 1;
 					}
+
+					if (0 < changes)
+					{
+						s_renderCtx.commitTextureStage();
+					}
 				}
 
 				if (currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx || materialChanged)
@@ -1930,7 +2052,7 @@ namespace bgfx
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-							deviceCtx->DrawIndexed(numIndices, 0, 0);
+							deviceCtx->DrawIndexed(numIndices, 0, state.m_startVertex);
 						}
 						else if (primNumVerts <= state.m_numIndices)
 						{
@@ -1939,7 +2061,7 @@ namespace bgfx
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-							deviceCtx->DrawIndexed(numIndices, state.m_startIndex, 0);
+							deviceCtx->DrawIndexed(numIndices, state.m_startIndex, state.m_startVertex);
 						}
 					}
 					else
@@ -1966,6 +2088,11 @@ namespace bgfx
 		int64_t frameTime = now - last;
 		last = now;
 
+		static int64_t min = frameTime;
+		static int64_t max = frameTime;
+		min = min > frameTime ? frameTime : min;
+		max = max < frameTime ? frameTime : max;
+
 		if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
 		{
 //			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugstats");
@@ -1984,7 +2111,12 @@ namespace bgfx
 				tvm.clear();
 				uint16_t pos = 10;
 				tvm.printf(0, 0, 0x8f, " " BGFX_RENDERER_NAME " ");
-				tvm.printf(10, pos++, 0x8e, "      Frame: %3.4f [ms] / %3.2f", frameTime*toMs, freq/frameTime);
+				tvm.printf(10, pos++, 0x8e, "      Frame: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
+					, double(frameTime)*toMs
+					, double(min)*toMs
+					, double(max)*toMs
+					, freq/frameTime
+					);
 				tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms]"
 					, m_render->m_num
 					, elapsedCpuMs
@@ -2003,6 +2135,9 @@ namespace bgfx
 
 				tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", m_render->m_waitSubmit*toMs);
 				tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", m_render->m_waitRender*toMs);
+
+				min = frameTime;
+				max = frameTime;
 			}
 
 			m_textVideoMemBlitter.blit(tvm);

+ 6 - 10
src/renderer_d3d11.h

@@ -9,8 +9,6 @@
 #include <d3d11.h>
 #include "renderer_d3d.h"
 
-typedef HRESULT (WINAPI *CreateDXGIFactoryFn)(REFIID, void**);
-
 namespace bgfx
 {
 	template <typename Ty>
@@ -258,14 +256,7 @@ namespace bgfx
 		}
 
 		void create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
-// 		void createTextures();
-// 		void destroyTextures();
-
-		void destroy()
-		{
-//			destroyTextures();
-			m_flags = 0;
-		}
+		void destroy();
 
  		void commit(uint8_t _stage);
 // 		void resolve();
@@ -278,6 +269,11 @@ namespace bgfx
 // 		IDirect3DSurface9* m_depth;
 // 		D3DTEXTUREFILTERTYPE m_minFilter;
 // 		D3DTEXTUREFILTERTYPE m_magFilter;
+
+		ID3D11Texture2D* m_colorTexture;
+		ID3D11RenderTargetView* m_rtv;
+		ID3D11ShaderResourceView* m_srv;
+		ID3D11SamplerState* m_sampler;
 		uint16_t m_width;
 		uint16_t m_height;
 		uint32_t m_flags;

+ 2431 - 2417
src/renderer_d3d9.cpp

@@ -1,2417 +1,2431 @@
-/*
- * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
- * License: http://www.opensource.org/licenses/BSD-2-Clause
- */
-
-#include "bgfx_p.h"
-
-#if BGFX_CONFIG_RENDERER_DIRECT3D9
-#	include "renderer_d3d9.h"
-
-namespace bgfx
-{
-	static const D3DPRIMITIVETYPE s_primType[] =
-	{
-		D3DPT_TRIANGLELIST,
-		D3DPT_LINELIST,
-		D3DPT_POINTLIST,
-	};
-
-	static const uint32_t s_primNumVerts[] =
-	{
-		3,
-		2,
-		1,
-	};
-
-	static const D3DMULTISAMPLE_TYPE s_checkMsaa[] =
-	{
-		D3DMULTISAMPLE_NONE,
-		D3DMULTISAMPLE_2_SAMPLES,
-		D3DMULTISAMPLE_4_SAMPLES,
-		D3DMULTISAMPLE_8_SAMPLES,
-		D3DMULTISAMPLE_16_SAMPLES,
-	};
-
-	static Msaa s_msaa[] =
-	{
-		{ D3DMULTISAMPLE_NONE,       0 },
-		{ D3DMULTISAMPLE_2_SAMPLES,  0 },
-		{ D3DMULTISAMPLE_4_SAMPLES,  0 },
-		{ D3DMULTISAMPLE_8_SAMPLES,  0 },
-		{ D3DMULTISAMPLE_16_SAMPLES, 0 },
-	};
-
-	static const D3DBLEND s_blendFactor[] =
-	{
-		(D3DBLEND)0, // ignored
-		D3DBLEND_ZERO,
-		D3DBLEND_ONE,
-		D3DBLEND_SRCCOLOR,
-		D3DBLEND_INVSRCCOLOR,
-		D3DBLEND_SRCALPHA,
-		D3DBLEND_INVSRCALPHA,
-		D3DBLEND_DESTALPHA,
-		D3DBLEND_INVDESTALPHA,
-		D3DBLEND_DESTCOLOR,
-		D3DBLEND_INVDESTCOLOR,
-		D3DBLEND_SRCALPHASAT,
-	};
-
-	static const D3DCMPFUNC s_depthFunc[] =
-	{
-		(D3DCMPFUNC)0, // ignored
-		D3DCMP_LESS,
-		D3DCMP_LESSEQUAL,
-		D3DCMP_EQUAL,
-		D3DCMP_GREATEREQUAL,
-		D3DCMP_GREATER,
-		D3DCMP_NOTEQUAL,
-		D3DCMP_NEVER,
-		D3DCMP_ALWAYS,
-	};
-
-	static const D3DCULL s_cullMode[] =
-	{
-		D3DCULL_NONE,
-		D3DCULL_CW,
-		D3DCULL_CCW,
-	};
-
-	static const D3DFORMAT s_checkColorFormats[] =
-	{
-		D3DFMT_UNKNOWN,
-		D3DFMT_A8R8G8B8, D3DFMT_UNKNOWN,
-		D3DFMT_R32F, D3DFMT_R16F, D3DFMT_G16R16, D3DFMT_A8R8G8B8, D3DFMT_UNKNOWN,
-
-		D3DFMT_UNKNOWN, // terminator
-	};
-
-	static D3DFORMAT s_colorFormat[] =
-	{
-		D3DFMT_UNKNOWN, // ignored
-		D3DFMT_A8R8G8B8,
-		D3DFMT_R32F,
-	};
-
-	static const D3DFORMAT s_depthFormat[] =
-	{
-		D3DFMT_UNKNOWN, // ignored
-		D3DFMT_D24S8,
-	};
-
-	static const D3DTEXTUREADDRESS s_textureAddress[] =
-	{
-		D3DTADDRESS_WRAP,
-		D3DTADDRESS_MIRROR,
-		D3DTADDRESS_CLAMP,
-	};
-
-	static const D3DTEXTUREFILTERTYPE s_textureFilter[] =
-	{
-		D3DTEXF_LINEAR,
-		D3DTEXF_POINT,
-		D3DTEXF_ANISOTROPIC,
-	};
-
-	struct TextureFormatInfo
-	{
-		D3DFORMAT m_fmt;
-		uint8_t m_bpp;
-	};
-
-	static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
-	{
-		{ D3DFMT_DXT1,         1 },
-		{ D3DFMT_DXT3,         1 },
-		{ D3DFMT_DXT5,         1 },
-		{ D3DFMT_UNKNOWN,      0 },
-		{ D3DFMT_L8,           1 },
-		{ D3DFMT_X8R8G8B8,     4 },
-		{ D3DFMT_A8R8G8B8,     4 },
-		{ D3DFMT_A16B16G16R16, 8 },
-	};
-
-	static ExtendedFormat s_extendedFormats[ExtendedFormat::Count] =
-	{
-		{ D3DFMT_ATI1, 0,                     D3DRTYPE_TEXTURE, false },
-		{ D3DFMT_ATI2, 0,                     D3DRTYPE_TEXTURE, false },
-		{ D3DFMT_DF16, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
-		{ D3DFMT_DF24, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
-		{ D3DFMT_INST, 0,                     D3DRTYPE_SURFACE, false },
-		{ D3DFMT_INTZ, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
-		{ D3DFMT_NULL, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, false },
-		{ D3DFMT_RESZ, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, false },
-		{ D3DFMT_RAWZ, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
-	};
-
-	struct RendererContext
-	{
-		RendererContext()
-			: m_flags(BGFX_RESET_NONE)
-			, m_initialized(false)
-			, m_amd(false)
-			, m_nvidia(false)
-			, m_instancing(false)
-			, m_rtMsaa(false)
-		{
-			m_rt.idx = invalidHandle;
-		}
-
-		void init()
-		{
-			D3DFORMAT adapterFormat = D3DFMT_X8R8G8B8;
-
-			// http://msdn.microsoft.com/en-us/library/windows/desktop/bb172588%28v=vs.85%29.aspx
-			memset(&m_params, 0, sizeof(m_params) );
-			m_params.BackBufferWidth = BGFX_DEFAULT_WIDTH;
-			m_params.BackBufferHeight = BGFX_DEFAULT_HEIGHT;
-			m_params.BackBufferFormat = adapterFormat;
-			m_params.BackBufferCount = 1;
-			m_params.MultiSampleType = D3DMULTISAMPLE_NONE;
-			m_params.MultiSampleQuality = 0;
-			m_params.EnableAutoDepthStencil = TRUE;
-			m_params.AutoDepthStencilFormat = D3DFMT_D24S8;
-			m_params.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
-#if BX_PLATFORM_WINDOWS
-			m_params.FullScreen_RefreshRateInHz = 0;
-			m_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
-			m_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
-			m_params.hDeviceWindow = g_bgfxHwnd;
-			m_params.Windowed = true;
-
-			RECT rect;
-			GetWindowRect(g_bgfxHwnd, &rect);
-			m_params.BackBufferWidth = rect.right-rect.left;
-			m_params.BackBufferHeight = rect.bottom-rect.top;
-
-			m_d3d9dll = LoadLibrary("d3d9.dll");
-			BGFX_FATAL(NULL != m_d3d9dll, Fatal::D3D9_UnableToCreateInterface, "Failed to load d3d9.dll.");
-
-			m_D3DPERF_SetMarker = (D3DPERF_SetMarkerFunc)GetProcAddress(m_d3d9dll, "D3DPERF_SetMarker");
-			m_D3DPERF_BeginEvent = (D3DPERF_BeginEventFunc)GetProcAddress(m_d3d9dll, "D3DPERF_BeginEvent");
-			m_D3DPERF_EndEvent = (D3DPERF_EndEventFunc)GetProcAddress(m_d3d9dll, "D3DPERF_EndEvent");
-
-#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
-			Direct3DCreate9ExFn direct3DCreate9Ex = (Direct3DCreate9ExFn)GetProcAddress(m_d3d9dll, "Direct3DCreate9Ex");
-			BGFX_FATAL(NULL != direct3DCreate9Ex, Fatal::D3D9_UnableToCreateInterface, "Function Direct3DCreate9Ex not found.");
-			direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d9);
-#else
-			Direct3DCreate9Fn direct3DCreate9 = (Direct3DCreate9Fn)GetProcAddress(m_d3d9dll, "Direct3DCreate9");
-			BGFX_FATAL(NULL != direct3DCreate9, Fatal::D3D9_UnableToCreateInterface, "Function Direct3DCreate9 not found.");
-			m_d3d9 = direct3DCreate9(D3D_SDK_VERSION);
-#endif // defined(D3D_DISABLE_9EX)
-
-			BGFX_FATAL(m_d3d9, Fatal::D3D9_UnableToCreateInterface, "Unable to create Direct3D.");
-
-			m_adapter = D3DADAPTER_DEFAULT;
-			m_deviceType = D3DDEVTYPE_HAL;
-
-			uint32_t adapterCount = m_d3d9->GetAdapterCount();
-			for (uint32_t ii = 0; ii < adapterCount; ++ii)
-			{
-				D3DADAPTER_IDENTIFIER9 identifier;
-				DX_CHECK(m_d3d9->GetAdapterIdentifier(ii, 0, &identifier) );
-
-				BX_TRACE("Adapter #%d", ii);
-				BX_TRACE("\tDriver: %s", identifier.Driver);
-				BX_TRACE("\tDescription: %s", identifier.Description);
-				BX_TRACE("\tDeviceName: %s", identifier.DeviceName);
-				BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x"
-						, identifier.VendorId
-						, identifier.DeviceId
-						, identifier.SubSysId
-						, identifier.Revision
-						);
-
-#if BGFX_CONFIG_DEBUG_PERFHUD
-				if (0 != strstr(identifier.Description, "PerfHUD") )
-				{
-					m_adapter = ii;
-					m_deviceType = D3DDEVTYPE_REF;
-				}
-#endif // BGFX_CONFIG_DEBUG_PERFHUD
-			}
-
-			D3DADAPTER_IDENTIFIER9 identifier;
-			DX_CHECK(m_d3d9->GetAdapterIdentifier(m_adapter, 0, &identifier) );
-			m_amd = identifier.VendorId == 0x1002;
-			m_nvidia = identifier.VendorId == 0x10de;
-
-			uint32_t behaviorFlags[] =
-			{
-				D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE,
-				D3DCREATE_MIXED_VERTEXPROCESSING,
-				D3DCREATE_SOFTWARE_VERTEXPROCESSING,
-			};
-
-			for (uint32_t ii = 0; ii < countof(behaviorFlags) && NULL == m_device; ++ii)
-			{
-#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
-				DX_CHECK(m_d3d9->CreateDeviceEx(m_adapter
-						, m_deviceType
-						, g_bgfxHwnd
-						, behaviorFlags[ii]
-						, &m_params
-						, NULL
-						, &m_device
-						) );
-#else
-				DX_CHECK(m_d3d9->CreateDevice(m_adapter
-					, m_deviceType
-					, g_bgfxHwnd
-					, behaviorFlags[ii]
-					, &m_params
-					, &m_device
-					) );
-#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
-			}
-
-			BGFX_FATAL(m_device, Fatal::D3D9_UnableToCreateDevice, "Unable to create Direct3D9 device.");
-
-			DX_CHECK(m_device->GetDeviceCaps(&m_caps) );
-
-			// For shit GPUs that can create DX9 device but can't do simple stuff. GTFO!
-			BGFX_FATAL( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) == 0, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_SQUAREONLY");
-			BGFX_FATAL( (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) == D3DPTEXTURECAPS_MIPMAP, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_MIPMAP");
-			BGFX_FATAL( (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) == D3DPTEXTURECAPS_ALPHA, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_ALPHA");
-			BGFX_FATAL(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1)
-					  , Fatal::MinimumRequiredSpecs
-					  , "Shader Model Version (vs: %x, ps: %x)."
-					  , m_caps.VertexShaderVersion
-					  , m_caps.PixelShaderVersion
-					  );
-			BGFX_FATAL(m_caps.MaxTextureWidth >= 2048 && m_caps.MaxTextureHeight >= 2048
-					  , Fatal::MinimumRequiredSpecs
-					  , "Maximum texture size is below 2048 (w: %d, h: %d)."
-					  , m_caps.MaxTextureWidth
-					  , m_caps.MaxTextureHeight
-					  );
-
-			BX_TRACE("Max vertex shader 3.0 instr. slots: %d", m_caps.MaxVertexShader30InstructionSlots);
-			BX_TRACE("Max vertex shader constants: %d", m_caps.MaxVertexShaderConst);
-			BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots);
-			BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots);
-
-			BX_TRACE("Extended formats:");
-			for (uint32_t ii = 0; ii < ExtendedFormat::Count; ++ii)
-			{
-				ExtendedFormat& fmt = s_extendedFormats[ii];
-				fmt.m_supported = SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter, m_deviceType, adapterFormat, fmt.m_usage, fmt.m_type, fmt.m_fmt) );
-				const char* fourcc = (const char*)&fmt.m_fmt;
-				BX_TRACE("\t%2d: %c%c%c%c %s", ii, fourcc[0], fourcc[1], fourcc[2], fourcc[3], fmt.m_supported ? "supported" : "");
-				BX_UNUSED(fourcc);
-			}
-
-			m_instancing = false
-				|| s_extendedFormats[ExtendedFormat::Inst].m_supported
-				|| (m_caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) )
-				;
-
-			if (m_amd
-			&&  s_extendedFormats[ExtendedFormat::Inst].m_supported)
-			{
-				// ATi only
-				m_device->SetRenderState(D3DRS_POINTSIZE, D3DFMT_INST);
-			}
-
-			uint32_t index = 1;
-			for (const D3DFORMAT* fmt = &s_checkColorFormats[index]; *fmt != D3DFMT_UNKNOWN; ++fmt, ++index)
-			{
-				for (; *fmt != D3DFMT_UNKNOWN; ++fmt)
-				{
-					if (SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter, m_deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, *fmt) ) )
-					{
-						s_colorFormat[index] = *fmt;
-						break;
-					}
-				}
-
-				for (; *fmt != D3DFMT_UNKNOWN; ++fmt);
-			}
-
-			m_fmtDepth = D3DFMT_D24S8;
-
-#elif BX_PLATFORM_XBOX360
-			m_params.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
-			m_params.DisableAutoBackBuffer = FALSE;
-			m_params.DisableAutoFrontBuffer = FALSE;
-			m_params.FrontBufferFormat = D3DFMT_X8R8G8B8;
-			m_params.FrontBufferColorSpace = D3DCOLORSPACE_RGB;
-
-			m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
-			BX_TRACE("Creating D3D9 %p", m_d3d9);
-
-			XVIDEO_MODE videoMode;
-			XGetVideoMode(&videoMode);
-			if (!videoMode.fIsWideScreen)
-			{
-				m_params.Flags |= D3DPRESENTFLAG_NO_LETTERBOX;
-			}
-
-			BX_TRACE("Creating device");
-			DX_CHECK(m_d3d9->CreateDevice(m_adapter
-					, m_deviceType
-					, NULL
-					, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_BUFFER_2_FRAMES
-					, &m_params
-					, &m_device
-					) );
-
-			BX_TRACE("Device %p", m_device);
-
-			m_fmtDepth = D3DFMT_D24FS8;
-#endif // BX_PLATFORM_WINDOWS
-
-			postReset();
-
-			m_initialized = true;
-		}
-
-		void shutdown()
-		{
-			preReset();
-
-			for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
-			{
-				m_indexBuffers[ii].destroy();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_vertexBuffers); ++ii)
-			{
-				m_vertexBuffers[ii].destroy();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_vertexShaders); ++ii)
-			{
-				m_vertexShaders[ii].destroy();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_fragmentShaders); ++ii)
-			{
-				m_fragmentShaders[ii].destroy();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_textures); ++ii)
-			{
-				m_textures[ii].destroy();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_vertexDecls); ++ii)
-			{
-				m_vertexDecls[ii].destroy();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_renderTargets); ++ii)
-			{
-				m_renderTargets[ii].destroy();
-			}
-
-			DX_RELEASE(m_device, 0);
-			DX_RELEASE(m_d3d9, 0);
-
-#if BX_PLATFORM_WINDOWS
-			FreeLibrary(m_d3d9dll);
-#endif // BX_PLATFORM_WINDOWS
-
-			m_initialized = false;
-		}
-
-		void updateMsaa()
-		{
-			for (uint32_t ii = 1, last = 0; ii < countof(s_checkMsaa); ++ii)
-			{
-				D3DMULTISAMPLE_TYPE msaa = s_checkMsaa[ii];
-				DWORD quality;
-
-				HRESULT hr = m_d3d9->CheckDeviceMultiSampleType(m_adapter
-					, m_deviceType
-					, m_params.BackBufferFormat
-					, m_params.Windowed
-					, msaa
-					, &quality
-					);
-
-				if (SUCCEEDED(hr) )
-				{
-					s_msaa[ii].m_type = msaa;
-					s_msaa[ii].m_quality = uint32_imax(0, quality-1);
-					last = ii;
-				}
-				else
-				{
-					s_msaa[ii] = s_msaa[last];
-				}
-			}
-		}
-
-		void updateResolution(const Resolution& _resolution)
-		{
-			if (m_params.BackBufferWidth != _resolution.m_width
-			||  m_params.BackBufferHeight != _resolution.m_height
-			||  m_flags != _resolution.m_flags)
-			{
-				m_flags = _resolution.m_flags;
-
-				m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
-				m_textVideoMem.clear();
-
-#if BX_PLATFORM_WINDOWS
-				D3DDEVICE_CREATION_PARAMETERS dcp;
-				DX_CHECK(m_device->GetCreationParameters(&dcp) );
-
-				D3DDISPLAYMODE dm;
-				DX_CHECK(m_d3d9->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm) );
-				
-				m_params.BackBufferFormat = dm.Format;
-#endif // BX_PLATFORM_WINDOWS
-
-				m_params.BackBufferWidth = _resolution.m_width;
-				m_params.BackBufferHeight = _resolution.m_height;
-				m_params.FullScreen_RefreshRateInHz = BGFX_RESET_FULLSCREEN == (m_flags&BGFX_RESET_FULLSCREEN_MASK) ? 60 : 0;
-				m_params.PresentationInterval = !!(m_flags&BGFX_RESET_VSYNC) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
-
-				updateMsaa();
-
-				Msaa& msaa = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
-				m_params.MultiSampleType = msaa.m_type;
-				m_params.MultiSampleQuality = msaa.m_quality;
-
-				preReset();
-				DX_CHECK(m_device->Reset(&m_params) );
-				postReset();
-			}
-		}
-
-		void setRenderTarget(RenderTargetHandle _rt, bool _msaa = true)
-		{
-			if (_rt.idx == invalidHandle)
-			{
-				DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
-				DX_CHECK(m_device->SetDepthStencilSurface(m_backBufferDepthStencil) );
-			}
-			else
-			{
-				RenderTarget& renderTarget = m_renderTargets[_rt.idx];
-				if (NULL != renderTarget.m_rt)
-				{
-					DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_rt) );
-				}
-				else
-				{
-					DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_color) );
-				}
-
-				DX_CHECK(m_device->SetDepthStencilSurface(NULL != renderTarget.m_depth ? renderTarget.m_depth : m_backBufferDepthStencil) );
-			}
-
-			if (m_rt.idx != invalidHandle
-			&&  m_rt.idx != _rt.idx
-			&&  m_rtMsaa)
-			{
-				RenderTarget& renderTarget = m_renderTargets[m_rt.idx];
-				if (!renderTarget.m_depthOnly
-				&&  renderTarget.m_rt != NULL)
-				{
-					renderTarget.resolve();
-				}
-			}
-
-			m_rt = _rt;
-			m_rtMsaa = _msaa;
-		}
-
-		void setShaderConstantF(uint8_t _flags, uint16_t _regIndex, const float* _val, uint16_t _numRegs)
-		{
-			if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
-			{
-				DX_CHECK(m_device->SetPixelShaderConstantF(_regIndex, _val, _numRegs) );
-			}
-			else
-			{
-				DX_CHECK(m_device->SetVertexShaderConstantF(_regIndex, _val, _numRegs) );
-			}
-		}
-
-		void reset()
-		{
-			preReset();
-
-			HRESULT hr;
-
-			do 
-			{
-				hr = m_device->Reset(&m_params);
-			} while (FAILED(hr) );
-
-			postReset();
-		}
-
-		bool isLost(HRESULT _hr) const
-		{
-			return D3DERR_DEVICELOST == _hr
-				|| D3DERR_DRIVERINTERNALERROR == _hr
-#if !defined(D3D_DISABLE_9EX)
-				|| D3DERR_DEVICEHUNG == _hr
-				|| D3DERR_DEVICEREMOVED == _hr
-#endif // !defined(D3D_DISABLE_9EX)
-				;
-		}
-
-		void flip()
-		{
-			if (NULL != m_device)
-			{
-#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
-				DX_CHECK(m_device->WaitForVBlank(0) );
-#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
-
-				HRESULT hr;
-				hr = m_device->Present(NULL, NULL, NULL, NULL);
-
-#if BX_PLATFORM_WINDOWS
-				if (isLost(hr) )
-				{
-					do
-					{
-						do 
-						{
-							hr = m_device->TestCooperativeLevel();
-						}
-						while (D3DERR_DEVICENOTRESET != hr);
-
-						reset();
-						hr = m_device->TestCooperativeLevel();
-					}
-					while (FAILED(hr) );
-				}
-				else if (FAILED(hr) )
-				{
-					BX_TRACE("Present failed with err 0x%08x.", hr);
-				}
-#endif // BX_PLATFORM_
-			}
-		}
-
-		void preReset()
-		{
-			for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
-			{
-				DX_CHECK(m_device->SetTexture(stage, NULL) );
-			}
-
-			DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
-			DX_CHECK(m_device->SetDepthStencilSurface(m_backBufferDepthStencil) );
-			DX_CHECK(m_device->SetVertexShader(NULL) );
-			DX_CHECK(m_device->SetPixelShader(NULL) );
-			DX_CHECK(m_device->SetStreamSource(0, NULL, 0, 0) );
-			DX_CHECK(m_device->SetIndices(NULL) );
-
-			DX_RELEASE(m_backBufferColor, 0);
-			DX_RELEASE(m_backBufferDepthStencil, 0);
-
-			for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
-			{
-				m_indexBuffers[ii].preReset();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_vertexBuffers); ++ii)
-			{
-				m_vertexBuffers[ii].preReset();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_renderTargets); ++ii)
-			{
-				m_renderTargets[ii].preReset();
-			}
-		}
-
-		void postReset()
-		{
-			DX_CHECK(m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_backBufferColor) );
-			DX_CHECK(m_device->GetDepthStencilSurface(&m_backBufferDepthStencil) );
-
-			for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
-			{
-				m_indexBuffers[ii].postReset();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_vertexBuffers); ++ii)
-			{
-				m_vertexBuffers[ii].postReset();
-			}
-
-			for (uint32_t ii = 0; ii < countof(m_renderTargets); ++ii)
-			{
-				m_renderTargets[ii].postReset();
-			}
-		}
-
-		void saveScreenShot(Memory* _mem)
-		{
-#if BX_PLATFORM_WINDOWS
-			IDirect3DSurface9* surface;
-			D3DDEVICE_CREATION_PARAMETERS dcp;
-			DX_CHECK(m_device->GetCreationParameters(&dcp) );
-
-			D3DDISPLAYMODE dm;
-			DX_CHECK(m_d3d9->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm) );
-
-			DX_CHECK(m_device->CreateOffscreenPlainSurface(dm.Width
-				, dm.Height
-				, D3DFMT_A8R8G8B8
-				, D3DPOOL_SCRATCH
-				, &surface
-				, NULL
-				) );
-
-			DX_CHECK(m_device->GetFrontBufferData(0, surface) );
-
-			D3DLOCKED_RECT rect;
-			DX_CHECK(surface->LockRect(&rect
-				, NULL
-				, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY
-				) );
-
-			RECT rc;
-			GetClientRect(g_bgfxHwnd, &rc);
-			POINT point;
-			point.x = rc.left;
-			point.y = rc.top;
-			ClientToScreen(g_bgfxHwnd, &point);
-			uint8_t* data = (uint8_t*)rect.pBits;
-			uint32_t bpp = rect.Pitch/dm.Width;
-			saveTga( (const char*)_mem->data, m_params.BackBufferWidth, m_params.BackBufferHeight, rect.Pitch, &data[point.y*rect.Pitch+point.x*bpp]);
-
-			DX_CHECK(surface->UnlockRect() );
-			DX_RELEASE(surface, 0);
-#endif // BX_PLATFORM_WINDOWS
-		}
-
-#if BX_PLATFORM_WINDOWS
-		D3DCAPS9 m_caps;
-
-		D3DPERF_SetMarkerFunc m_D3DPERF_SetMarker;
-		D3DPERF_BeginEventFunc  m_D3DPERF_BeginEvent;
-		D3DPERF_EndEventFunc m_D3DPERF_EndEvent;
-#endif // BX_PLATFORM_WINDOWS
-
-#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
-		IDirect3D9Ex* m_d3d9;
-		IDirect3DDevice9Ex* m_device;
-#else
-		IDirect3D9* m_d3d9;
-		IDirect3DDevice9* m_device;
-#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
-
-		IDirect3DSurface9* m_backBufferColor;
-		IDirect3DSurface9* m_backBufferDepthStencil;
-		IDirect3DVertexDeclaration9* m_instanceDataDecls[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
-
-		HMODULE m_d3d9dll;
-		uint32_t m_adapter;
-		D3DDEVTYPE m_deviceType;
-		D3DPRESENT_PARAMETERS m_params;
-		uint32_t m_flags;
-
-		bool m_initialized;
-		bool m_amd;
-		bool m_nvidia;
-		bool m_instancing;
-
-		D3DFORMAT m_fmtDepth;
-
-		IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
-		VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
-		Shader m_vertexShaders[BGFX_CONFIG_MAX_VERTEX_SHADERS];
-		Shader m_fragmentShaders[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
-		Material m_materials[BGFX_CONFIG_MAX_MATERIALS];
-		Texture m_textures[BGFX_CONFIG_MAX_TEXTURES];
-		VertexDeclaration m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
-		RenderTarget m_renderTargets[BGFX_CONFIG_MAX_RENDER_TARGETS];
-		UniformRegistry m_uniformReg;
-		void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
-
-		TextVideoMem m_textVideoMem;
-		RenderTargetHandle m_rt;
-		bool m_rtMsaa;
-	};
-
-	static RendererContext s_renderCtx;
-
-	void IndexBuffer::create(uint32_t _size, void* _data)
-	{
-		m_size = _size;
-		m_dynamic = NULL == _data;
-
-		uint32_t usage = D3DUSAGE_WRITEONLY;
-		D3DPOOL pool = D3DPOOL_MANAGED;
-
-		if (m_dynamic)
-		{
-			usage |= D3DUSAGE_DYNAMIC;
-			pool = D3DPOOL_DEFAULT;
-		}
-
-		DX_CHECK(s_renderCtx.m_device->CreateIndexBuffer(m_size
-			, usage
-			, D3DFMT_INDEX16
-			, pool
-			, &m_ptr
-			, NULL
-			) );
-
-		if (NULL != _data)
-		{
-			update(0, _size, _data);
-		}
-	}
-
-	void IndexBuffer::preReset()
-	{
-		if (m_dynamic)
-		{
-			DX_RELEASE(m_ptr, 0);
-		}
-	}
-
-	void IndexBuffer::postReset()
-	{
-		if (m_dynamic)
-		{
-			DX_CHECK(s_renderCtx.m_device->CreateIndexBuffer(m_size
-				, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC
-				, D3DFMT_INDEX16
-				, D3DPOOL_DEFAULT
-				, &m_ptr
-				, NULL
-				) );
-		}
-	}
-
-	void VertexBuffer::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle)
-	{
-		m_size = _size;
-		m_decl = _declHandle;
-		m_dynamic = NULL == _data;
-
-		uint32_t usage = D3DUSAGE_WRITEONLY;
-		D3DPOOL pool = D3DPOOL_MANAGED;
-
-		if (m_dynamic)
-		{
-			usage |= D3DUSAGE_DYNAMIC;
-			pool = D3DPOOL_DEFAULT;
-		}
-
-		DX_CHECK(s_renderCtx.m_device->CreateVertexBuffer(m_size
-				, usage
-				, 0
-				, pool
-				, &m_ptr
-				, NULL 
-				) );
-
-		if (NULL != _data)
-		{
-			update(0, _size, _data);
-		}
-	}
-
-	void VertexBuffer::preReset()
-	{
-		if (m_dynamic)
-		{
-			DX_RELEASE(m_ptr, 0);
-		}
-	}
-
-	void VertexBuffer::postReset()
-	{
-		if (m_dynamic)
-		{
-			DX_CHECK(s_renderCtx.m_device->CreateVertexBuffer(m_size
-					, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC
-					, 0
-					, D3DPOOL_DEFAULT
-					, &m_ptr
-					, NULL 
-					) );
-		}
-	}
-
-	static const D3DVERTEXELEMENT9 s_attrib[Attrib::Count+1] =
-	{
-		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,     0 },
-		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,       0 },
-		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        0 },
-		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        1 },
-		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
-		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,  0 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     0 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     1 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     2 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     3 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     4 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     5 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     6 },
-		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     7 },
-		D3DDECL_END()
-	};
-
-	static D3DVERTEXELEMENT9* fillVertexDecl(D3DVERTEXELEMENT9* _out, uint32_t _count, const VertexDecl& _decl)
-	{
-		D3DVERTEXELEMENT9* elem = _out;
-
-		for (uint32_t attr = 0; attr < Attrib::Count; ++attr)
-		{
-			if (0xff != _decl.m_attributes[attr])
-			{
-				uint8_t num;
-				AttribType::Enum type;
-				bool normalized;
-				_decl.decode(Attrib::Enum(attr), num, type, normalized);
-
-				memcpy(elem, &s_attrib[attr], sizeof(D3DVERTEXELEMENT9) );
-
-				D3DDECLTYPE declType = D3DDECLTYPE(elem->Type);
-
-				switch (type)
-				{
-				case AttribType::Uint8:
-					if (normalized)
-					{
-						declType = D3DDECLTYPE_UBYTE4N;
-					}
-					else
-					{
-						declType = D3DDECLTYPE_UBYTE4;
-					}
-					break;
-
-				case AttribType::Uint16:
-					if (normalized)
-					{
-						switch (num)
-						{
-						default:
-						case 2:
-							declType = D3DDECLTYPE_SHORT2N;
-							break;
-
-						case 4:
-							declType = D3DDECLTYPE_SHORT4N;
-							break;
-						}
-					}
-					else
-					{
-						switch (num)
-						{
-						default:
-						case 2:
-							declType = D3DDECLTYPE_SHORT2;
-							break;
-
-						case 4:
-							declType = D3DDECLTYPE_SHORT4;
-							break;
-						}
-					}
-					break;
-
-				case AttribType::Float:
-					switch (num)
-					{
-					case 1:
-						declType = D3DDECLTYPE_FLOAT1;
-						break;
-
-					case 2:
-						declType = D3DDECLTYPE_FLOAT2;
-						break;
-
-					default:
-					case 3:
-						declType = D3DDECLTYPE_FLOAT3;
-						break;
-
-					case 4:
-						declType = D3DDECLTYPE_FLOAT4;
-						break;
-					}
-
-					break;
-
-				default:
-					BX_CHECK(false, "Invalid attrib type.");
-					break;
-				}
-
-				elem->Type = declType;
-				elem->Offset = _decl.m_offset[attr];
-				++elem;
-			}
-		}
-
-		return elem;
-	}
-
-	static IDirect3DVertexDeclaration9* createVertexDecl(const VertexDecl& _decl, uint8_t _numInstanceData)
-	{
-		D3DVERTEXELEMENT9 vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
-		D3DVERTEXELEMENT9* elem = fillVertexDecl(vertexElements, Attrib::Count, _decl);
-
-		const D3DVERTEXELEMENT9 inst = { 1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 };
-
-		for (uint32_t ii = 0; ii < _numInstanceData; ++ii)
-		{
-			memcpy(elem, &inst, sizeof(D3DVERTEXELEMENT9) );
-			elem->UsageIndex = 8-_numInstanceData+ii;
-			elem->Offset = ii*16;
-			++elem;
-		}
-
-		memcpy(elem, &s_attrib[Attrib::Count], sizeof(D3DVERTEXELEMENT9) );
-
-		IDirect3DVertexDeclaration9* ptr;
-		DX_CHECK(s_renderCtx.m_device->CreateVertexDeclaration(vertexElements, &ptr) );
-		return ptr;
-	}
-
-	void VertexDeclaration::create(const VertexDecl& _decl)
-	{
-		memcpy(&m_decl, &_decl, sizeof(VertexDecl) );
-		dump(m_decl);
-		m_ptr = createVertexDecl(_decl, 0);
-	}
-
-	void Shader::create(bool _fragment, const Memory* _mem)
-	{
-		m_constantBuffer = ConstantBuffer::create(1024);
-
-		StreamRead stream(_mem->data, _mem->size);
-		uint16_t count;
-		stream.read(count);
-
-		m_numPredefined = 0;
-
-		BX_TRACE("Shader consts %d", count);
-
-		uint8_t fragmentBit = _fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0;
-
-		for (uint32_t ii = 0; ii < count; ++ii)
-		{
-			uint8_t nameSize;
-			stream.read(nameSize);
-
-			char name[256];
-			stream.read(&name, nameSize);
-			name[nameSize] = '\0';
-
-			uint8_t type;
-			stream.read(type);
-
-			uint8_t num;
-			stream.read(num);
-
-			uint16_t regIndex;
-			stream.read(regIndex);
-
-			uint16_t regCount;
-			stream.read(regCount);
-
-			const char* kind = "invalid";
-
-			const void* data = NULL;
-			PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
-			if (PredefinedUniform::Count != predefined)
-			{
-				kind = "predefined";
-				m_predefined[m_numPredefined].m_loc = regIndex;
-				m_predefined[m_numPredefined].m_count = regCount;
-				m_predefined[m_numPredefined].m_type = predefined|fragmentBit;
-				m_numPredefined++;
-			}
-			else
-			{
-				const UniformInfo* info = s_renderCtx.m_uniformReg.find(name);
-				BX_CHECK(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
-				if (NULL != info)
-				{
-					kind = "user";
-					data = info->m_data;
-					m_constantBuffer->writeUniformRef( (ConstantType::Enum)(type|fragmentBit), regIndex, data, regCount);
-				}
-			}
-
-			BX_TRACE("\t%s: %s, type %2d, num %2d, r.index %3d, r.count %2d"
-				, kind
-				, name
-				, type
-				, num
-				, regIndex
-				, regCount
-				);
-			BX_UNUSED(kind);
-		}
-
-		uint16_t shaderSize;
-		stream.read(shaderSize);
-
-		m_constantBuffer->finish();
-
-		const DWORD* code = (const DWORD*)stream.getDataPtr();
-
-		if (_fragment)
-		{
-			DX_CHECK(s_renderCtx.m_device->CreatePixelShader(code, (IDirect3DPixelShader9**)&m_ptr) );
-		}
-		else
-		{
-			DX_CHECK(s_renderCtx.m_device->CreateVertexShader(code, (IDirect3DVertexShader9**)&m_ptr) );
-		}
-	}
-
-	void Texture::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips, D3DFORMAT _fmt)
-	{
-		m_type = Texture2D;
-
-		DX_CHECK(s_renderCtx.m_device->CreateTexture(_width
-			, _height
-			, _numMips
-			, 0
-			, _fmt
-			, D3DPOOL_MANAGED
-			, (IDirect3DTexture9**)&m_ptr
-			, NULL
-			) );
-
-		BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create texture (size: %dx%d, mips: %d, fmt: 0x%08x)."
-			, _width
-			, _height
-			, _numMips
-			, _fmt
-			);
-	}
-
-	void Texture::createVolumeTexture(uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _numMips, D3DFORMAT _fmt)
-	{
-		m_type = Texture3D;
-
-		DX_CHECK(s_renderCtx.m_device->CreateVolumeTexture(_width
-			, _height
-			, _depth
-			, _numMips
-			, 0
-			, _fmt
-			, D3DPOOL_MANAGED
-			, (IDirect3DVolumeTexture9**)&m_ptr
-			, NULL
-			) );
-
-		BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create volume texture (size: %dx%dx%d, mips: %d, fmt: 0x%08x)."
-			, _width
-			, _height
-			, _depth
-			, _numMips
-			, _fmt
-			);
-	}
-
-	void Texture::createCubeTexture(uint32_t _edge, uint32_t _numMips, D3DFORMAT _fmt)
-	{
-		m_type = TextureCube;
-
-		DX_CHECK(s_renderCtx.m_device->CreateCubeTexture(_edge
-			, _numMips
-			, 0
-			, _fmt
-			, D3DPOOL_MANAGED
-			, (IDirect3DCubeTexture9**)&m_ptr
-			, NULL
-			) );
-
-		BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create cube texture (edge: %d, mips: %d, fmt: 0x%08x)."
-			, _edge
-			, _numMips
-			, _fmt
-			);
-	}
-
-	uint8_t* Texture::lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch)
-	{
-		switch (m_type)
-		{
-		case Texture2D:
-			{
-				IDirect3DTexture9* texture = (IDirect3DTexture9*)m_ptr;
-				D3DLOCKED_RECT rect;
-				DX_CHECK(texture->LockRect(_lod, &rect, NULL, 0) );
-				_pitch = rect.Pitch;
-				_slicePitch = 0;
-				return (uint8_t*)rect.pBits;
-			}
-
-		case Texture3D:
-			{
-				IDirect3DVolumeTexture9* texture = (IDirect3DVolumeTexture9*)m_ptr;
-				D3DLOCKED_BOX box;
-				DX_CHECK(texture->LockBox(_lod, &box, NULL, 0) );
-				_pitch = box.RowPitch;
-				_slicePitch = box.SlicePitch;
-				return (uint8_t*)box.pBits;
-			}
-
-		case TextureCube:
-			{
-				IDirect3DCubeTexture9* texture = (IDirect3DCubeTexture9*)m_ptr;
-				D3DLOCKED_RECT rect;
-				DX_CHECK(texture->LockRect(D3DCUBEMAP_FACES(_side), _lod, &rect, NULL, 0) );
-				_pitch = rect.Pitch;
-				_slicePitch = 0;
-				return (uint8_t*)rect.pBits;
-			}
-		}
-
-		BX_CHECK(false, "You should not be here.");
-		return NULL;
-	}
-
-	void Texture::unlock(uint8_t _side, uint8_t _lod)
-	{
-		switch (m_type)
-		{
-		case Texture2D:
-			{
-				IDirect3DTexture9* texture = (IDirect3DTexture9*)m_ptr;
-				DX_CHECK(texture->UnlockRect(_lod) );
-			}
-			return;
-
-		case Texture3D:
-			{
-				IDirect3DVolumeTexture9* texture = (IDirect3DVolumeTexture9*)m_ptr;
-				DX_CHECK(texture->UnlockBox(_lod) );
-			}
-			return;
-
-		case TextureCube:
-			{
-				IDirect3DCubeTexture9* texture = (IDirect3DCubeTexture9*)m_ptr;
-				DX_CHECK(texture->UnlockRect(D3DCUBEMAP_FACES(_side), _lod) );
-			}
-			return;
-		}
-
-		BX_CHECK(false, "You should not be here.");
-	}
-
-	void Texture::create(const Memory* _mem, uint32_t _flags)
-	{
-		m_tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
-		m_tav = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT];
-		m_taw = s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT];
-		m_minFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
-		m_magFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
-		m_mipFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT];
-		m_srgb = (_flags&BGFX_TEXTURE_SRGB) == BGFX_TEXTURE_SRGB;
-
-		Dds dds;
-
-		if (parseDds(dds, _mem) )
-		{
-			uint8_t bpp = dds.m_bpp;
-
-			bool decompress = false;
-
-			if (dds.m_cubeMap)
-			{
-				createCubeTexture(dds.m_width, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
-			}
-			else if (dds.m_depth > 1)
-			{
-				createVolumeTexture(dds.m_width, dds.m_height, dds.m_depth, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
-			}
-			else
-			{
-				createTexture(dds.m_width, dds.m_height, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
-			}
-
-			if (decompress
-			||  TextureFormat::Unknown < dds.m_type)
-			{
-				for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
-				{
-					uint32_t width = dds.m_width;
-					uint32_t height = dds.m_height;
-					uint32_t depth = dds.m_depth;
-
-					for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
-					{
-						width = uint32_max(1, width);
-						height = uint32_max(1, height);
-						depth = uint32_max(1, depth);
-
-						Mip mip;
-						if (getRawImageData(dds, side, lod, _mem, mip) )
-						{
-							uint32_t pitch;
-							uint32_t slicePitch;
-							uint8_t* bits = lock(side, lod, pitch, slicePitch);
-
-							if (width != mip.m_width
-							||  height != mip.m_height)
-							{
-								uint32_t srcpitch = mip.m_width*bpp;
-
-								uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
-								mip.decode(temp);
-
-								uint32_t dstpitch = pitch;
-								for (uint32_t yy = 0; yy < height; ++yy)
-								{
-									uint8_t* src = &temp[yy*srcpitch];
-									uint8_t* dst = &bits[yy*dstpitch];
-									memcpy(dst, src, srcpitch);
-								}
-
-								g_free(temp);
-							}
-							else
-							{
-								mip.decode(bits);
-							}
-
-							unlock(side, lod);
-						}
-
-						width >>= 1;
-						height >>= 1;
-						depth >>= 1;
-					}
-				}
-			}
-			else
-			{
-				for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
-				{
-					for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
-					{
-						Mip mip;
-						if (getRawImageData(dds, 0, lod, _mem, mip) )
-						{
-							uint32_t pitch;
-							uint32_t slicePitch;
-							uint8_t* dst = lock(side, lod, pitch, slicePitch);
-
-							memcpy(dst, mip.m_data, mip.m_size);
-
-							unlock(side, lod);
-						}
-					}
-				}
-			}
-		}
-		else
-		{
-			StreamRead stream(_mem->data, _mem->size);
-
-			uint32_t magic;
-			stream.read(magic);
-
-			if (BGFX_MAGIC == magic)
-			{
-				uint16_t width;
-				stream.read(width);
-
-				uint16_t height;
-				stream.read(height);
-
-				uint8_t bpp;
-				stream.read(bpp);
-
-				uint8_t numMips;
-				stream.read(numMips);
-
-				stream.align(16);
-
-				D3DFORMAT fmt = 1 == bpp ? D3DFMT_L8 : D3DFMT_A8R8G8B8;
-
-				createTexture(width, height, numMips, fmt);
-
-				for (uint8_t mip = 0; mip < numMips; ++mip)
-				{
-					width = uint32_max(width, 1);
-					height = uint32_max(height, 1);
-
-					uint32_t pitch;
-					uint32_t slicePitch;
-					uint8_t* dst = lock(0, mip, pitch, slicePitch);
-					stream.read(dst, width*height*bpp);
-					unlock(0, mip);
-
-					width >>= 1;
-					height >>= 1;
-				}
-			}
-			else
-			{
-				//
-			}
-		}
-	}
-
-	void Texture::commit(uint8_t _stage)
-	{
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MINFILTER, m_minFilter) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MAGFILTER, m_magFilter) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, m_mipFilter) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, m_tau) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, m_tav) );
-		if (m_type == Texture3D)
-		{
-			DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSW, m_taw) );
-		}
-#if BX_PLATFORM_WINDOWS
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, m_srgb) );
-#endif // BX_PLATFORM_WINDOWS
-		DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_ptr) );
-	}
-
-	void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
-	{
-		m_width = _width;
-		m_height = _height;
-		m_flags = _flags;
-		m_minFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
-		m_magFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
-
-		createTextures();
-	}
-
-	void RenderTarget::createTextures()
-	{
-		if (0 != m_flags)
-		{
-			m_msaa = s_msaa[(m_flags&BGFX_RENDER_TARGET_MSAA_MASK)>>BGFX_RENDER_TARGET_MSAA_SHIFT];
-			uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
-			uint32_t depthFormat = (m_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT;
-			m_depthOnly = (0 == colorFormat && 0 < depthFormat);
-
-			// CheckDeviceFormat D3DUSAGE_SRGBWRITE
-
-			if (m_depthOnly)
-			{
-				DX_CHECK(s_renderCtx.m_device->CreateRenderTarget(1
-					, 1
-					, D3DFMT_R5G6B5
-					, D3DMULTISAMPLE_NONE
-					, 0
-					, false
-					, &m_rt
-					, NULL
-					) );
-
-				BGFX_FATAL(m_rt, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create 1x1 render target.");
-
-				DX_CHECK(s_renderCtx.m_device->CreateTexture(m_width
-					, m_height
-					, 1
-					, D3DUSAGE_DEPTHSTENCIL
-					, D3DFMT_DF24 //s_depthFormat[depthFormat]
-					, D3DPOOL_DEFAULT
-					, &m_depthTexture
-					, NULL
-					) );
-
-				BGFX_FATAL(m_depthTexture, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create depth texture.");
-
-				DX_CHECK(m_depthTexture->GetSurfaceLevel(0, &m_depth) );
-			}
-			else
-			{
-				if (D3DMULTISAMPLE_NONE != m_msaa.m_type)
-				{
-					DX_CHECK(s_renderCtx.m_device->CreateRenderTarget(m_width
-						, m_height
-						, s_colorFormat[colorFormat]
-						, m_msaa.m_type
-						, m_msaa.m_quality
-						, false
-						, &m_rt
-						, NULL
-						) );
-
-					BGFX_FATAL(m_rt, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create MSAA render target.");
-				}
-
-				if (0 < colorFormat)
-				{
-					DX_CHECK(s_renderCtx.m_device->CreateTexture(m_width
-						, m_height
-						, 1
-						, D3DUSAGE_RENDERTARGET
-						, s_colorFormat[colorFormat]
-						, D3DPOOL_DEFAULT
-						, &m_colorTexture
-						, NULL
-						) );
-
-					BGFX_FATAL(m_colorTexture, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create color render target.");
-
-					DX_CHECK(m_colorTexture->GetSurfaceLevel(0, &m_color) );
-				}
-
-				if (0 < depthFormat)
-				{
-					DX_CHECK(s_renderCtx.m_device->CreateDepthStencilSurface(m_width
-							, m_height
-							, s_depthFormat[depthFormat] // s_renderCtx.m_fmtDepth
-							, m_msaa.m_type
-							, m_msaa.m_quality
-							, FALSE
-							, &m_depth
-							, NULL
-							) );
-
-					BGFX_FATAL(m_depth, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create depth stencil surface.");
-				}
-			}
-		}
-	}
-
-	void RenderTarget::destroyTextures()
-	{
-		if (0 != m_flags)
-		{
-			if (m_depthOnly)
-			{
-				DX_RELEASE(m_rt, 0);
-
-				DX_RELEASE(m_depth, 1);
-				DX_RELEASE(m_depthTexture, 0);
-			}
-			else
-			{
-				uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
-				uint32_t depthFormat = (m_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT;
-
-				if (D3DMULTISAMPLE_NONE != m_msaa.m_type)
-				{
-					DX_RELEASE(m_rt, 0);
-				}
-
-				if (0 < colorFormat)
-				{
-					DX_RELEASE(m_color, 1);
-					DX_RELEASE(m_colorTexture, 0);
-				}
-
-				if (0 < depthFormat)
-				{
-					DX_RELEASE(m_depth, 0);
-				}
-			}
-		}
-	}
-
-	void RenderTarget::commit(uint8_t _stage)
-	{
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MINFILTER, m_minFilter) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MAGFILTER, m_magFilter) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, D3DTEXF_POINT) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP) );
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP) );
-#if BX_PLATFORM_WINDOWS
-		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, (m_flags&BGFX_RENDER_TARGET_SRGBWRITE) == BGFX_RENDER_TARGET_SRGBWRITE) );
-#endif // BX_PLATFORM_WINDOWS
-		DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_depthOnly ? m_depthTexture : m_colorTexture) );
-	}
-
-	void RenderTarget::resolve()
-	{
-#if BX_PLATFORM_WINDOWS
-		DX_CHECK(s_renderCtx.m_device->StretchRect(m_rt
-				, NULL
-				, m_color
-				, NULL
-				, D3DTEXF_NONE
-				) );
-#endif // BX_PLATFORM_WINDOWS
-	}
-
-	void ConstantBuffer::commit()
-	{
-		reset();
-
-		do
-		{
-			uint32_t opcode = read();
-
-			if (ConstantType::End == opcode)
-			{
-				break;
-			}
-
-			ConstantType::Enum type;
-			uint16_t loc;
-			uint16_t num;
-			uint16_t copy;
-			decodeOpcode(opcode, type, loc, num, copy);
-
-			const char* data;
-			if (copy)
-			{
-				data = read(g_constantTypeSize[type]*num);
-			}
-			else
-			{
-				memcpy(&data, read(sizeof(void*) ), sizeof(void*) );
-			}
-
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
-		case ConstantType::_uniform: \
-		{ \
-			_type* value = (_type*)data; \
-			s_renderCtx.m_device->SetVertexShaderConstant##_dxsuffix(loc, value, num); \
-		} \
-		break; \
-		\
-		case ConstantType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
-		{ \
-			_type* value = (_type*)data; \
-			s_renderCtx.m_device->SetPixelShaderConstant##_dxsuffix(loc, value, num); \
-		} \
-		break;
-
-			switch ((int32_t)type)
-			{
-			CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
-			CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
-			CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform3x3fv, Matrix3fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, Matrix4fv, F, float);
-
-			case ConstantType::End:
-				break;
-
-			default:
-				BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", m_pos, opcode, type, loc, num, copy);
-				break;
-			}
-
-#undef CASE_IMPLEMENT_UNIFORM
-
-		} while (true);
-	}
-
-	void TextVideoMemBlitter::setup()
-	{
-		uint32_t width = s_renderCtx.m_params.BackBufferWidth;
-		uint32_t height = s_renderCtx.m_params.BackBufferHeight;
-
-		RenderTargetHandle rt = BGFX_INVALID_HANDLE;
-		s_renderCtx.setRenderTarget(rt, false);
-
-		D3DVIEWPORT9 vp;
-		vp.X = 0;
-		vp.Y = 0;
-		vp.Width = width;
-		vp.Height = height;
-		vp.MinZ = 0.0f;
-		vp.MaxZ = 1.0f;
-		DX_CHECK(s_renderCtx.m_device->SetViewport(&vp) );
-
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ZENABLE, FALSE) );
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS) );
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE) );
-		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID) );
-
-		Material& material = s_renderCtx.m_materials[m_material.idx];
-		s_renderCtx.m_device->SetVertexShader( (IDirect3DVertexShader9*)material.m_vsh->m_ptr);
-		s_renderCtx.m_device->SetPixelShader( (IDirect3DPixelShader9*)material.m_fsh->m_ptr);
-
-		VertexBuffer& vb = s_renderCtx.m_vertexBuffers[m_vb->handle.idx];
-		VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[m_vb->decl.idx];
-		DX_CHECK(s_renderCtx.m_device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) );
-		DX_CHECK(s_renderCtx.m_device->SetVertexDeclaration(vertexDecl.m_ptr) );
-
-		IndexBuffer& ib = s_renderCtx.m_indexBuffers[m_ib->handle.idx];
-		DX_CHECK(s_renderCtx.m_device->SetIndices(ib.m_ptr) );
-
-		float proj[16];
-		matrix_ortho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f);
-
-		PredefinedUniform& predefined = material.m_predefined[0];
-		uint8_t flags = predefined.m_type;
-		s_renderCtx.setShaderConstantF(flags, predefined.m_loc, proj, 4);
-
-		s_renderCtx.m_textures[m_texture.idx].commit(0);
-	}
-
-	void TextVideoMemBlitter::render(uint32_t _numIndices)
-	{
-		uint32_t numVertices = _numIndices*4/6;
-		s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(0, _numIndices*2, m_ib->data);
-		s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(0, numVertices*m_decl.m_stride, m_vb->data);
-
-		DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST
-			, 0
-			, 0
-			, numVertices
-			, 0
-			, _numIndices/3
-			) );
-	}
-
-	void Context::flip()
-	{
-		s_renderCtx.flip();
-	}
-
-	void Context::rendererInit()
-	{
-		s_renderCtx.init();
-	}
-
-	void Context::rendererShutdown()
-	{
-		s_renderCtx.shutdown();
-	}
-
-	void Context::rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem)
-	{
-		s_renderCtx.m_indexBuffers[_handle.idx].create(_mem->size, _mem->data);
-	}
-
-	void Context::rendererDestroyIndexBuffer(IndexBufferHandle _handle)
-	{
-		s_renderCtx.m_indexBuffers[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl)
-	{
-		s_renderCtx.m_vertexDecls[_handle.idx].create(_decl);
-	}
-
-	void Context::rendererDestroyVertexDecl(VertexDeclHandle _handle)
-	{
-		s_renderCtx.m_vertexDecls[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle)
-	{
-		s_renderCtx.m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle);
-	}
-
-	void Context::rendererDestroyVertexBuffer(VertexBufferHandle _handle)
-	{
-		s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size)
-	{
-		s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL);
-	}
-
-	void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
-	{
-		s_renderCtx.m_indexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
-	}
-
-	void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle)
-	{
-		s_renderCtx.m_indexBuffers[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size)
-	{
-		VertexDeclHandle decl = BGFX_INVALID_HANDLE;
-		s_renderCtx.m_vertexBuffers[_handle.idx].create(_size, NULL, decl);
-	}
-
-	void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
-	{
-		s_renderCtx.m_vertexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
-	}
-
-	void Context::rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle)
-	{
-		s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem)
-	{
-		s_renderCtx.m_vertexShaders[_handle.idx].create(false, _mem);
-	}
-
-	void Context::rendererDestroyVertexShader(VertexShaderHandle _handle)
-	{
-		s_renderCtx.m_vertexShaders[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateFragmentShader(FragmentShaderHandle _handle, Memory* _mem)
-	{
-		s_renderCtx.m_fragmentShaders[_handle.idx].create(true, _mem);
-	}
-
-	void Context::rendererDestroyFragmentShader(FragmentShaderHandle _handle)
-	{
-		s_renderCtx.m_fragmentShaders[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateMaterial(MaterialHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
-	{
-		s_renderCtx.m_materials[_handle.idx].create(s_renderCtx.m_vertexShaders[_vsh.idx], s_renderCtx.m_fragmentShaders[_fsh.idx]);
-	}
-
-	void Context::rendererDestroyMaterial(FragmentShaderHandle _handle)
-	{
-		s_renderCtx.m_materials[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
-	{
-		s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
-	}
-
-	void Context::rendererDestroyTexture(TextureHandle _handle)
-	{
-		s_renderCtx.m_textures[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
-	{
-		s_renderCtx.m_renderTargets[_handle.idx].create(_width, _height, _flags, _textureFlags);
-	}
-
-	void Context::rendererDestroyRenderTarget(RenderTargetHandle _handle)
-	{
-		s_renderCtx.m_renderTargets[_handle.idx].destroy();
-	}
-
-	void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
-	{
-		uint32_t size = BX_ALIGN_16(g_constantTypeSize[_type]*_num);
-		void* data = g_realloc(NULL, size);
-		s_renderCtx.m_uniforms[_handle.idx] = data;
-		s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
-	}
-
-	void Context::rendererDestroyUniform(UniformHandle _handle)
-	{
-		g_free(s_renderCtx.m_uniforms[_handle.idx]);
-	}
-
-	void Context::rendererSaveScreenShot(Memory* _mem)
-	{
-		s_renderCtx.saveScreenShot(_mem);
-	}
-
-	void Context::rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size)
-	{
-		memcpy(s_renderCtx.m_uniforms[_loc], _data, _size);
-	}
-
-	void Context::rendererSubmit()
-	{
-		IDirect3DDevice9* device = s_renderCtx.m_device;
-
-		PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), "rendererSubmit");
-
-		s_renderCtx.updateResolution(m_render->m_resolution);
-
-		device->BeginScene();
-
-		if (0 < m_render->m_iboffset)
-		{
-			TransientIndexBuffer* ib = m_render->m_transientIb;
-			s_renderCtx.m_indexBuffers[ib->handle.idx].update(0, m_render->m_iboffset, ib->data);
-		}
-
-		if (0 < m_render->m_vboffset)
-		{
-			TransientVertexBuffer* vb = m_render->m_transientVb;
-			s_renderCtx.m_vertexBuffers[vb->handle.idx].update(0, m_render->m_vboffset, vb->data);
-		}
-
-		m_render->sort();
-
-		RenderState currentState;
-		currentState.reset();
-		currentState.m_flags = BGFX_STATE_NONE;
-
-		Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
-		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
-		{
-			matrix_mul(viewProj[ii].val, m_render->m_view[ii].val, m_render->m_proj[ii].val);
-		}
-
-		DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, m_render->m_debug&BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID) );
-		uint16_t materialIdx = invalidHandle;
-		SortKey key;
-		uint8_t view = 0xff;
-		RenderTargetHandle rt = BGFX_INVALID_HANDLE;
-		float alphaRef = 0.0f;
-		D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST;
-		uint32_t primNumVerts = 3;
-
-		uint32_t statsNumPrimsSubmitted = 0;
-		uint32_t statsNumIndices = 0;
-		uint32_t statsNumInstances = 0;
-		uint32_t statsNumPrimsRendered = 0;
-
-		int64_t elapsed = -bx::getHPCounter();
-
-		if (0 == (m_render->m_debug&BGFX_DEBUG_IFH) )
-		{
-			for (uint32_t item = 0, numItems = m_render->m_num; item < numItems; ++item)
-			{
-				key.decode(m_render->m_sortKeys[item]);
-				const RenderState& state = m_render->m_renderState[m_render->m_sortValues[item] ];
-
-				const uint64_t newFlags = state.m_flags;
-				uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
-				currentState.m_flags = newFlags;
-
-				if (key.m_view != view)
-				{
-					currentState.clear();
-					changedFlags = BGFX_STATE_MASK;
-					currentState.m_flags = newFlags;
-
-					PIX_ENDEVENT();
-					PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), "view");
-
-					view = key.m_view;
-
-					materialIdx = invalidHandle;
-
-					if (m_render->m_rt[view].idx != rt.idx)
-					{
-						rt = m_render->m_rt[view];
-						s_renderCtx.setRenderTarget(rt);
-					}
-
-					Rect& rect = m_render->m_rect[view];
-
-					D3DVIEWPORT9 vp;
-					vp.X = rect.m_x;
-					vp.Y = rect.m_y;
-					vp.Width = rect.m_width;
-					vp.Height = rect.m_height;
-					vp.MinZ = 0.0f;
-					vp.MaxZ = 1.0f;
-					DX_CHECK(device->SetViewport(&vp) );
-
-					Clear& clear = m_render->m_clear[view];
-
-					if (BGFX_CLEAR_NONE != clear.m_flags)
-					{
-						D3DCOLOR color = 0;
-						DWORD flags = 0;
-
-						if (BGFX_CLEAR_COLOR_BIT & clear.m_flags)
-						{
-							flags |= D3DCLEAR_TARGET;
-							uint32_t rgba = clear.m_rgba;
-							color = D3DCOLOR_RGBA(rgba>>24, (rgba>>16)&0xff, (rgba>>8)&0xff, rgba&0xff);
-							DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA) );
-						}
-
-						if (BGFX_CLEAR_DEPTH_BIT & clear.m_flags)
-						{
-							flags |= D3DCLEAR_ZBUFFER;
-							DX_CHECK(device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE) );
-						}
-
-						if (BGFX_CLEAR_STENCIL_BIT & clear.m_flags)
-						{
-							flags |= D3DCLEAR_STENCIL;
-						}
-
-						if (0 != flags)
-						{
-							RECT rc;
-							rc.left = rect.m_x;
-							rc.top = rect.m_y;
-							rc.right = rect.m_x + rect.m_width;
-							rc.bottom = rect.m_y + rect.m_height;
-							DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE) );
-							DX_CHECK(device->SetScissorRect(&rc) );
-							DX_CHECK(device->Clear(0, NULL, flags, color, clear.m_depth, clear.m_stencil) );
-							DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE) );
-						}
-					}
-
- 					DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
-					DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS) );
-					DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
-					DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
-					DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
-				}
-
-				if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
-					 |BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
-					 |BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK
-					 |BGFX_STATE_POINT_SIZE_MASK|BGFX_STATE_SRGBWRITE|BGFX_STATE_MSAA) & changedFlags)
-				{
-					if (BGFX_STATE_CULL_MASK & changedFlags)
-					{
-						uint32_t cull = (newFlags&BGFX_STATE_CULL_MASK)>>BGFX_STATE_CULL_SHIFT;
-						DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, s_cullMode[cull]) );
-					}
-
-					if (BGFX_STATE_DEPTH_WRITE & changedFlags)
-					{ 
-						DX_CHECK(device->SetRenderState(D3DRS_ZWRITEENABLE, !!(BGFX_STATE_DEPTH_WRITE & newFlags) ) );
-					}
-
-					if (BGFX_STATE_DEPTH_TEST_MASK & changedFlags)
-					{
-						uint32_t func = (newFlags&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
-						DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, 0 != func) );
-
-						if (0 != func)
-						{
-							DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, s_depthFunc[func]) );
-						}
-					}
-
-					if ( (BGFX_STATE_ALPHA_TEST|BGFX_STATE_ALPHA_REF_MASK) & changedFlags)
-					{
-						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
-						alphaRef = ref/255.0f;
-						DX_CHECK(device->SetRenderState(D3DRS_ALPHAREF, ref) );
-						DX_CHECK(device->SetRenderState(D3DRS_ALPHATESTENABLE, !!(BGFX_STATE_ALPHA_TEST & newFlags) ) );
-					}
-
-					if ( (BGFX_STATE_PT_POINTS|BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
-					{
-						DX_CHECK(device->SetRenderState(D3DRS_POINTSIZE, castfu( (float)( (newFlags&BGFX_STATE_POINT_SIZE_MASK)>>BGFX_STATE_POINT_SIZE_SHIFT) ) ) );
-					}
-
-#if BX_PLATFORM_WINDOWS
-					if (BGFX_STATE_SRGBWRITE & changedFlags)
-					{
-						DX_CHECK(device->SetRenderState(D3DRS_SRGBWRITEENABLE, (newFlags&BGFX_STATE_SRGBWRITE) == BGFX_STATE_SRGBWRITE) );
-					}
-#endif // BX_PLATFORM_WINDOWS
-
-					if (BGFX_STATE_MSAA & changedFlags)
-					{
-						DX_CHECK(device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, (newFlags&BGFX_STATE_MSAA) == BGFX_STATE_MSAA) );
-					}
-
-					if ( (BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags)
-					{
-						uint32_t writeEnable = (newFlags&BGFX_STATE_ALPHA_WRITE) ? D3DCOLORWRITEENABLE_ALPHA : 0;
- 						writeEnable |= (newFlags&BGFX_STATE_RGB_WRITE) ? D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE : 0;
-						DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, writeEnable) );
-					}
-
-					if (BGFX_STATE_BLEND_MASK & changedFlags)
-					{
-						bool alphaBlendEnabled = !!(BGFX_STATE_BLEND_MASK & newFlags);
-						DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlendEnabled) );
-//						DX_CHECK(device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, alphaBlendEnabled) );
-
-						if (alphaBlendEnabled)
-						{
-							uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
-							uint32_t src = blend&0xf;
-							uint32_t dst = (blend>>4)&0xf;
-
- 							DX_CHECK(device->SetRenderState(D3DRS_SRCBLEND, s_blendFactor[src]) );
-							DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dst]) );
-//							DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA) );
-//							DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA) );
-						}
-					}
-
-					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
-					primType = s_primType[primIndex];
-					primNumVerts = s_primNumVerts[primIndex];
-				}
-
-				bool materialChanged = false;
-				bool constantsChanged = state.m_constBegin < state.m_constEnd;
-				rendererUpdateUniforms(m_render->m_constantBuffer, state.m_constBegin, state.m_constEnd);
-
-				if (key.m_material != materialIdx)
-				{
-					materialIdx = key.m_material;
-
-					if (invalidHandle == materialIdx)
-					{
-						device->SetVertexShader(NULL);
-						device->SetPixelShader(NULL);
-					}
-					else
-					{
-						Material& material = s_renderCtx.m_materials[materialIdx];
-						device->SetVertexShader( (IDirect3DVertexShader9*)material.m_vsh->m_ptr);
-						device->SetPixelShader( (IDirect3DPixelShader9*)material.m_fsh->m_ptr);
-					}
-
-					materialChanged = 
-						constantsChanged = true;
-				}
-
-				if (invalidHandle != materialIdx)
-				{
-					Material& material = s_renderCtx.m_materials[materialIdx];
-
-					if (constantsChanged)
-					{
-						Material& material = s_renderCtx.m_materials[materialIdx];
-						material.m_vsh->m_constantBuffer->commit();
-						material.m_fsh->m_constantBuffer->commit();
-					}
-
-					for (uint32_t ii = 0, num = material.m_numPredefined; ii < num; ++ii)
-					{
-						PredefinedUniform& predefined = material.m_predefined[ii];
-						uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
-						switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
-						{
-						case PredefinedUniform::ViewRect:
-							{
-								float rect[4];
-								rect[0] = m_render->m_rect[view].m_x;
-								rect[1] = m_render->m_rect[view].m_y;
-								rect[2] = m_render->m_rect[view].m_width;
-								rect[3] = m_render->m_rect[view].m_height;
-
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, &rect[0], 1);
-							}
-							break;
-
-						case PredefinedUniform::ViewTexel:
-							{
-								float rect[4];
-								rect[0] = 1.0f/float(m_render->m_rect[view].m_width);
-								rect[1] = 1.0f/float(m_render->m_rect[view].m_height);
-
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, &rect[0], 1);
-							}
-							break;
-
-						case PredefinedUniform::View:
-							{
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, m_render->m_view[view].val, uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ViewProj:
-							{
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, viewProj[view].val, uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::Model:
-							{
- 								const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, model.val, uint32_min(state.m_num*4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ModelViewProj:
-							{
-								Matrix4 modelViewProj;
-								const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
-								matrix_mul(modelViewProj.val, model.val, viewProj[view].val);
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, modelViewProj.val, uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ModelViewProjX:
-							{
-								const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
-
-								static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
-								{
-									0.5f, 0.0f, 0.0f, 0.0f,
-									0.0f, 0.5f, 0.0f, 0.0f,
-									0.0f, 0.0f, 0.5f, 0.0f,
-									0.5f, 0.5f, 0.5f, 1.0f,
-								};
-
-								uint8_t other = m_render->m_other[view];
-								Matrix4 viewProjBias;
-								matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
-
-								Matrix4 modelViewProj;
-								matrix_mul(modelViewProj.val, model.val, viewProjBias.val);
-
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, modelViewProj.val, uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::ViewProjX:
-							{
-								static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
-								{
-									0.5f, 0.0f, 0.0f, 0.0f,
-									0.0f, 0.5f, 0.0f, 0.0f,
-									0.0f, 0.0f, 0.5f, 0.0f,
-									0.5f, 0.5f, 0.5f, 1.0f,
-								};
-
-								uint8_t other = m_render->m_other[view];
-								Matrix4 viewProjBias;
-								matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
-
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, viewProjBias.val, uint32_min(4, predefined.m_count) );
-							}
-							break;
-
-						case PredefinedUniform::AlphaRef:
-							{
-								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, &alphaRef, 1);
-							}
-							break;
-
-						default:
-							BX_CHECK(false, "predefined %d not handled", predefined.m_type);
-							break;
-						}
-					}
-				}
-
-//				if (BGFX_STATE_TEX_MASK & changedFlags)
-				{
-					uint64_t flag = BGFX_STATE_TEX0;
-					for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
-					{
-						const Sampler& sampler = state.m_sampler[stage];
-						Sampler& current = currentState.m_sampler[stage];
-						if (current.m_idx != sampler.m_idx
-						||  current.m_flags != sampler.m_flags
-						||  materialChanged)
-						{
-							if (invalidHandle != sampler.m_idx)
-							{
-								switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
-								{
-								case BGFX_SAMPLER_TEXTURE:
-									s_renderCtx.m_textures[sampler.m_idx].commit(stage);
-									break;
-
-								case BGFX_SAMPLER_RENDERTARGET_COLOR:
-									s_renderCtx.m_renderTargets[sampler.m_idx].commit(stage);
-									break;
-
-								case BGFX_SAMPLER_RENDERTARGET_DEPTH:
-//									id = s_renderCtx.m_renderTargets[sampler.m_idx].m_depth.m_id;
-									break;
-								}
-							}
-							else
-							{
-								DX_CHECK(device->SetTexture(stage, NULL) );
-							}
-						}
-
-						current = sampler;
-						flag <<= 1;
-					}
-				}
-
-				if (currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx || materialChanged)
-				{
-					currentState.m_vertexBuffer = state.m_vertexBuffer;
-
-					uint16_t handle = state.m_vertexBuffer.idx;
-					if (invalidHandle != handle)
-					{
-						const VertexBuffer& vb = s_renderCtx.m_vertexBuffers[handle];
-
-						uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
-						const VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[decl];
-						DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) );
-
-						if (invalidHandle != state.m_instanceDataBuffer.idx
-						&&  s_renderCtx.m_instancing)
-						{
-							const VertexBuffer& inst = s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx];
-							DX_CHECK(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA|state.m_numInstances) );
-							DX_CHECK(device->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA|1) );
-							DX_CHECK(device->SetStreamSource(1, inst.m_ptr, state.m_instanceDataOffset, state.m_instanceDataStride) );
-
-							IDirect3DVertexDeclaration9* ptr = createVertexDecl(vertexDecl.m_decl, state.m_instanceDataStride/16);
-							DX_CHECK(device->SetVertexDeclaration(ptr) );
-							DX_RELEASE(ptr, 0);
-						}
-						else
-						{
-							DX_CHECK(device->SetStreamSourceFreq(0, 1) );
-							DX_CHECK(device->SetStreamSource(1, NULL, 0, 0) );
-							DX_CHECK(device->SetVertexDeclaration(vertexDecl.m_ptr) );
-						}
-					}
-					else
-					{
-						DX_CHECK(device->SetStreamSource(0, NULL, 0, 0) );
-						DX_CHECK(device->SetStreamSource(1, NULL, 0, 0) );
-					}
-				}
-
-				if (currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
-				{
-					currentState.m_indexBuffer = state.m_indexBuffer;
-
-					uint16_t handle = state.m_indexBuffer.idx;
-					if (invalidHandle != handle)
-					{
-						IndexBuffer& ib = s_renderCtx.m_indexBuffers[handle];
-						DX_CHECK(device->SetIndices(ib.m_ptr) );
-					}
-					else
-					{
-						DX_CHECK(device->SetIndices(NULL) );
-					}
-				}
-
-				if (invalidHandle != currentState.m_vertexBuffer.idx)
-				{
-					uint32_t numVertices = state.m_numVertices;
-					if (UINT32_C(0xffffffff) == numVertices)
-					{
-						VertexBuffer& vb = s_renderCtx.m_vertexBuffers[currentState.m_vertexBuffer.idx];
-						uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
-						VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[decl];
-						numVertices = vb.m_size/vertexDecl.m_decl.m_stride;
-					}
-
-					uint32_t numIndices = 0;
-					uint32_t numPrimsSubmitted = 0;
-					uint32_t numInstances = 0;
-					uint32_t numPrimsRendered = 0;
-
-					if (invalidHandle != state.m_indexBuffer.idx)
-					{
-						if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
-						{
-							numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
-							numPrimsSubmitted = numIndices/primNumVerts;
-							numInstances = state.m_numInstances;
-							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
-
-							DX_CHECK(device->DrawIndexedPrimitive(primType
-								, state.m_startVertex
-								, 0
-								, numVertices
-								, 0
-								, numPrimsSubmitted
-								) );
-						}
-						else if (primNumVerts <= state.m_numIndices)
-						{
-							numIndices = state.m_numIndices;
-							numPrimsSubmitted = numIndices/primNumVerts;
-							numInstances = state.m_numInstances;
-							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
-
-							DX_CHECK(device->DrawIndexedPrimitive(primType
-								, state.m_startVertex
-								, 0
-								, numVertices
-								, state.m_startIndex
-								, numPrimsSubmitted
-								) );
-						}
-					}
-					else
-					{
-						numPrimsSubmitted = numVertices/primNumVerts;
-						numInstances = state.m_numInstances;
-						numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
-						DX_CHECK(device->DrawPrimitive(primType
-							, state.m_startVertex
-							, numPrimsSubmitted
-							) );
-					}
-
-					statsNumPrimsSubmitted += numPrimsSubmitted;
-					statsNumIndices += numIndices;
-					statsNumInstances += numInstances;
-					statsNumPrimsRendered += numPrimsRendered;
-				}
-			}
-
-			PIX_ENDEVENT();
-		}
-
-		int64_t now = bx::getHPCounter();
-		elapsed += now;
-
-		static int64_t last = now;
-		int64_t frameTime = now - last;
-		last = now;
-
-		if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
-		{
-			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugstats");
-
-			TextVideoMem& tvm = s_renderCtx.m_textVideoMem;
-
-			static int64_t next = now;
-
-			if (now >= next)
-			{
-				next = now + bx::getHPFrequency();
-				double freq = double(bx::getHPFrequency() );
-				double toMs = 1000.0/freq;
-				double elapsedCpuMs = double(elapsed)*toMs;
-
-				tvm.clear();
-				uint16_t pos = 10;
-				tvm.printf(0, 0, 0x8f, " " BGFX_RENDERER_NAME " ");
-				tvm.printf(10, pos++, 0x8e, "      Frame: %3.4f [ms] / %3.2f", frameTime*toMs, freq/frameTime);
-				tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms]"
-					, m_render->m_num
-					, elapsedCpuMs
-					);
-				tvm.printf(10, pos++, 0x8e, "      Prims: %7d (#inst: %5d), submitted: %7d"
-					, statsNumPrimsRendered
-					, statsNumInstances
-					, statsNumPrimsSubmitted
-					);
-				tvm.printf(10, pos++, 0x8e, "    Indices: %7d", statsNumIndices);
-				tvm.printf(10, pos++, 0x8e, "   DVB size: %7d", m_render->m_vboffset);
-				tvm.printf(10, pos++, 0x8e, "   DIB size: %7d", m_render->m_iboffset);
-
-				uint8_t attr[2] = { 0x89, 0x8a };
-				uint8_t attrIndex = m_render->m_waitSubmit < m_render->m_waitRender;
-
-				tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", m_render->m_waitSubmit*toMs);
-				tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", m_render->m_waitRender*toMs);
-			}
-
-			m_textVideoMemBlitter.blit(tvm);
-
-			PIX_ENDEVENT();
-		}
-		else if (m_render->m_debug & BGFX_DEBUG_TEXT)
-		{
-			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugtext");
-
-			m_textVideoMemBlitter.blit(m_render->m_textVideoMem);
-
-			PIX_ENDEVENT();
-		}
-
-		device->EndScene();
-	}
-}
-
-#endif // BGFX_CONFIG_RENDERER_DIRECT3D9
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_p.h"
+
+#if BGFX_CONFIG_RENDERER_DIRECT3D9
+#	include "renderer_d3d9.h"
+
+namespace bgfx
+{
+	static const D3DPRIMITIVETYPE s_primType[] =
+	{
+		D3DPT_TRIANGLELIST,
+		D3DPT_LINELIST,
+		D3DPT_POINTLIST,
+	};
+
+	static const uint32_t s_primNumVerts[] =
+	{
+		3,
+		2,
+		1,
+	};
+
+	static const D3DMULTISAMPLE_TYPE s_checkMsaa[] =
+	{
+		D3DMULTISAMPLE_NONE,
+		D3DMULTISAMPLE_2_SAMPLES,
+		D3DMULTISAMPLE_4_SAMPLES,
+		D3DMULTISAMPLE_8_SAMPLES,
+		D3DMULTISAMPLE_16_SAMPLES,
+	};
+
+	static Msaa s_msaa[] =
+	{
+		{ D3DMULTISAMPLE_NONE,       0 },
+		{ D3DMULTISAMPLE_2_SAMPLES,  0 },
+		{ D3DMULTISAMPLE_4_SAMPLES,  0 },
+		{ D3DMULTISAMPLE_8_SAMPLES,  0 },
+		{ D3DMULTISAMPLE_16_SAMPLES, 0 },
+	};
+
+	static const D3DBLEND s_blendFactor[] =
+	{
+		(D3DBLEND)0, // ignored
+		D3DBLEND_ZERO,
+		D3DBLEND_ONE,
+		D3DBLEND_SRCCOLOR,
+		D3DBLEND_INVSRCCOLOR,
+		D3DBLEND_SRCALPHA,
+		D3DBLEND_INVSRCALPHA,
+		D3DBLEND_DESTALPHA,
+		D3DBLEND_INVDESTALPHA,
+		D3DBLEND_DESTCOLOR,
+		D3DBLEND_INVDESTCOLOR,
+		D3DBLEND_SRCALPHASAT,
+	};
+
+	static const D3DCMPFUNC s_depthFunc[] =
+	{
+		(D3DCMPFUNC)0, // ignored
+		D3DCMP_LESS,
+		D3DCMP_LESSEQUAL,
+		D3DCMP_EQUAL,
+		D3DCMP_GREATEREQUAL,
+		D3DCMP_GREATER,
+		D3DCMP_NOTEQUAL,
+		D3DCMP_NEVER,
+		D3DCMP_ALWAYS,
+	};
+
+	static const D3DCULL s_cullMode[] =
+	{
+		D3DCULL_NONE,
+		D3DCULL_CW,
+		D3DCULL_CCW,
+	};
+
+	static const D3DFORMAT s_checkColorFormats[] =
+	{
+		D3DFMT_UNKNOWN,
+		D3DFMT_A8R8G8B8, D3DFMT_UNKNOWN,
+		D3DFMT_R32F, D3DFMT_R16F, D3DFMT_G16R16, D3DFMT_A8R8G8B8, D3DFMT_UNKNOWN,
+
+		D3DFMT_UNKNOWN, // terminator
+	};
+
+	static D3DFORMAT s_colorFormat[] =
+	{
+		D3DFMT_UNKNOWN, // ignored
+		D3DFMT_A8R8G8B8,
+		D3DFMT_R32F,
+	};
+
+	static const D3DFORMAT s_depthFormat[] =
+	{
+		D3DFMT_UNKNOWN, // ignored
+		D3DFMT_D24S8,
+	};
+
+	static const D3DTEXTUREADDRESS s_textureAddress[] =
+	{
+		D3DTADDRESS_WRAP,
+		D3DTADDRESS_MIRROR,
+		D3DTADDRESS_CLAMP,
+	};
+
+	static const D3DTEXTUREFILTERTYPE s_textureFilter[] =
+	{
+		D3DTEXF_LINEAR,
+		D3DTEXF_POINT,
+		D3DTEXF_ANISOTROPIC,
+	};
+
+	struct TextureFormatInfo
+	{
+		D3DFORMAT m_fmt;
+		uint8_t m_bpp;
+	};
+
+	static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
+	{
+		{ D3DFMT_DXT1,         1 },
+		{ D3DFMT_DXT3,         1 },
+		{ D3DFMT_DXT5,         1 },
+		{ D3DFMT_UNKNOWN,      0 },
+		{ D3DFMT_L8,           1 },
+		{ D3DFMT_X8R8G8B8,     4 },
+		{ D3DFMT_A8R8G8B8,     4 },
+		{ D3DFMT_A16B16G16R16, 8 },
+	};
+
+	static ExtendedFormat s_extendedFormats[ExtendedFormat::Count] =
+	{
+		{ D3DFMT_ATI1, 0,                     D3DRTYPE_TEXTURE, false },
+		{ D3DFMT_ATI2, 0,                     D3DRTYPE_TEXTURE, false },
+		{ D3DFMT_DF16, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
+		{ D3DFMT_DF24, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
+		{ D3DFMT_INST, 0,                     D3DRTYPE_SURFACE, false },
+		{ D3DFMT_INTZ, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
+		{ D3DFMT_NULL, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, false },
+		{ D3DFMT_RESZ, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, false },
+		{ D3DFMT_RAWZ, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, false },
+	};
+
+	struct RendererContext
+	{
+		RendererContext()
+			: m_flags(BGFX_RESET_NONE)
+			, m_initialized(false)
+			, m_amd(false)
+			, m_nvidia(false)
+			, m_instancing(false)
+			, m_rtMsaa(false)
+		{
+			m_rt.idx = invalidHandle;
+		}
+
+		void init()
+		{
+			D3DFORMAT adapterFormat = D3DFMT_X8R8G8B8;
+
+			// http://msdn.microsoft.com/en-us/library/windows/desktop/bb172588%28v=vs.85%29.aspx
+			memset(&m_params, 0, sizeof(m_params) );
+			m_params.BackBufferWidth = BGFX_DEFAULT_WIDTH;
+			m_params.BackBufferHeight = BGFX_DEFAULT_HEIGHT;
+			m_params.BackBufferFormat = adapterFormat;
+			m_params.BackBufferCount = 1;
+			m_params.MultiSampleType = D3DMULTISAMPLE_NONE;
+			m_params.MultiSampleQuality = 0;
+			m_params.EnableAutoDepthStencil = TRUE;
+			m_params.AutoDepthStencilFormat = D3DFMT_D24S8;
+			m_params.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
+#if BX_PLATFORM_WINDOWS
+			m_params.FullScreen_RefreshRateInHz = 0;
+			m_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+			m_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
+			m_params.hDeviceWindow = g_bgfxHwnd;
+			m_params.Windowed = true;
+
+			RECT rect;
+			GetWindowRect(g_bgfxHwnd, &rect);
+			m_params.BackBufferWidth = rect.right-rect.left;
+			m_params.BackBufferHeight = rect.bottom-rect.top;
+
+			m_d3d9dll = LoadLibrary("d3d9.dll");
+			BGFX_FATAL(NULL != m_d3d9dll, Fatal::D3D9_UnableToCreateInterface, "Failed to load d3d9.dll.");
+
+			m_D3DPERF_SetMarker = (D3DPERF_SetMarkerFunc)GetProcAddress(m_d3d9dll, "D3DPERF_SetMarker");
+			m_D3DPERF_BeginEvent = (D3DPERF_BeginEventFunc)GetProcAddress(m_d3d9dll, "D3DPERF_BeginEvent");
+			m_D3DPERF_EndEvent = (D3DPERF_EndEventFunc)GetProcAddress(m_d3d9dll, "D3DPERF_EndEvent");
+
+#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
+			Direct3DCreate9ExFn direct3DCreate9Ex = (Direct3DCreate9ExFn)GetProcAddress(m_d3d9dll, "Direct3DCreate9Ex");
+			BGFX_FATAL(NULL != direct3DCreate9Ex, Fatal::D3D9_UnableToCreateInterface, "Function Direct3DCreate9Ex not found.");
+			direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d9);
+#else
+			Direct3DCreate9Fn direct3DCreate9 = (Direct3DCreate9Fn)GetProcAddress(m_d3d9dll, "Direct3DCreate9");
+			BGFX_FATAL(NULL != direct3DCreate9, Fatal::D3D9_UnableToCreateInterface, "Function Direct3DCreate9 not found.");
+			m_d3d9 = direct3DCreate9(D3D_SDK_VERSION);
+#endif // defined(D3D_DISABLE_9EX)
+
+			BGFX_FATAL(m_d3d9, Fatal::D3D9_UnableToCreateInterface, "Unable to create Direct3D.");
+
+			m_adapter = D3DADAPTER_DEFAULT;
+			m_deviceType = D3DDEVTYPE_HAL;
+
+			uint32_t adapterCount = m_d3d9->GetAdapterCount();
+			for (uint32_t ii = 0; ii < adapterCount; ++ii)
+			{
+				D3DADAPTER_IDENTIFIER9 identifier;
+				DX_CHECK(m_d3d9->GetAdapterIdentifier(ii, 0, &identifier) );
+
+				BX_TRACE("Adapter #%d", ii);
+				BX_TRACE("\tDriver: %s", identifier.Driver);
+				BX_TRACE("\tDescription: %s", identifier.Description);
+				BX_TRACE("\tDeviceName: %s", identifier.DeviceName);
+				BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x"
+						, identifier.VendorId
+						, identifier.DeviceId
+						, identifier.SubSysId
+						, identifier.Revision
+						);
+
+#if BGFX_CONFIG_DEBUG_PERFHUD
+				if (0 != strstr(identifier.Description, "PerfHUD") )
+				{
+					m_adapter = ii;
+					m_deviceType = D3DDEVTYPE_REF;
+				}
+#endif // BGFX_CONFIG_DEBUG_PERFHUD
+			}
+
+			D3DADAPTER_IDENTIFIER9 identifier;
+			DX_CHECK(m_d3d9->GetAdapterIdentifier(m_adapter, 0, &identifier) );
+			m_amd = identifier.VendorId == 0x1002;
+			m_nvidia = identifier.VendorId == 0x10de;
+
+			uint32_t behaviorFlags[] =
+			{
+				D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE,
+				D3DCREATE_MIXED_VERTEXPROCESSING,
+				D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+			};
+
+			for (uint32_t ii = 0; ii < countof(behaviorFlags) && NULL == m_device; ++ii)
+			{
+#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
+				DX_CHECK(m_d3d9->CreateDeviceEx(m_adapter
+						, m_deviceType
+						, g_bgfxHwnd
+						, behaviorFlags[ii]
+						, &m_params
+						, NULL
+						, &m_device
+						) );
+#else
+				DX_CHECK(m_d3d9->CreateDevice(m_adapter
+					, m_deviceType
+					, g_bgfxHwnd
+					, behaviorFlags[ii]
+					, &m_params
+					, &m_device
+					) );
+#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
+			}
+
+			BGFX_FATAL(m_device, Fatal::D3D9_UnableToCreateDevice, "Unable to create Direct3D9 device.");
+
+			DX_CHECK(m_device->GetDeviceCaps(&m_caps) );
+
+			// For shit GPUs that can create DX9 device but can't do simple stuff. GTFO!
+			BGFX_FATAL( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) == 0, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_SQUAREONLY");
+			BGFX_FATAL( (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) == D3DPTEXTURECAPS_MIPMAP, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_MIPMAP");
+			BGFX_FATAL( (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) == D3DPTEXTURECAPS_ALPHA, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_ALPHA");
+			BGFX_FATAL(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1)
+					  , Fatal::MinimumRequiredSpecs
+					  , "Shader Model Version (vs: %x, ps: %x)."
+					  , m_caps.VertexShaderVersion
+					  , m_caps.PixelShaderVersion
+					  );
+			BGFX_FATAL(m_caps.MaxTextureWidth >= 2048 && m_caps.MaxTextureHeight >= 2048
+					  , Fatal::MinimumRequiredSpecs
+					  , "Maximum texture size is below 2048 (w: %d, h: %d)."
+					  , m_caps.MaxTextureWidth
+					  , m_caps.MaxTextureHeight
+					  );
+
+			BX_TRACE("Max vertex shader 3.0 instr. slots: %d", m_caps.MaxVertexShader30InstructionSlots);
+			BX_TRACE("Max vertex shader constants: %d", m_caps.MaxVertexShaderConst);
+			BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots);
+			BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots);
+
+			BX_TRACE("Extended formats:");
+			for (uint32_t ii = 0; ii < ExtendedFormat::Count; ++ii)
+			{
+				ExtendedFormat& fmt = s_extendedFormats[ii];
+				fmt.m_supported = SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter, m_deviceType, adapterFormat, fmt.m_usage, fmt.m_type, fmt.m_fmt) );
+				const char* fourcc = (const char*)&fmt.m_fmt;
+				BX_TRACE("\t%2d: %c%c%c%c %s", ii, fourcc[0], fourcc[1], fourcc[2], fourcc[3], fmt.m_supported ? "supported" : "");
+				BX_UNUSED(fourcc);
+			}
+
+			m_instancing = false
+				|| s_extendedFormats[ExtendedFormat::Inst].m_supported
+				|| (m_caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) )
+				;
+
+			if (m_amd
+			&&  s_extendedFormats[ExtendedFormat::Inst].m_supported)
+			{
+				// ATi only
+				m_device->SetRenderState(D3DRS_POINTSIZE, D3DFMT_INST);
+			}
+
+			uint32_t index = 1;
+			for (const D3DFORMAT* fmt = &s_checkColorFormats[index]; *fmt != D3DFMT_UNKNOWN; ++fmt, ++index)
+			{
+				for (; *fmt != D3DFMT_UNKNOWN; ++fmt)
+				{
+					if (SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter, m_deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, *fmt) ) )
+					{
+						s_colorFormat[index] = *fmt;
+						break;
+					}
+				}
+
+				for (; *fmt != D3DFMT_UNKNOWN; ++fmt);
+			}
+
+			m_fmtDepth = D3DFMT_D24S8;
+
+#elif BX_PLATFORM_XBOX360
+			m_params.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+			m_params.DisableAutoBackBuffer = FALSE;
+			m_params.DisableAutoFrontBuffer = FALSE;
+			m_params.FrontBufferFormat = D3DFMT_X8R8G8B8;
+			m_params.FrontBufferColorSpace = D3DCOLORSPACE_RGB;
+
+			m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+			BX_TRACE("Creating D3D9 %p", m_d3d9);
+
+			XVIDEO_MODE videoMode;
+			XGetVideoMode(&videoMode);
+			if (!videoMode.fIsWideScreen)
+			{
+				m_params.Flags |= D3DPRESENTFLAG_NO_LETTERBOX;
+			}
+
+			BX_TRACE("Creating device");
+			DX_CHECK(m_d3d9->CreateDevice(m_adapter
+					, m_deviceType
+					, NULL
+					, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_BUFFER_2_FRAMES
+					, &m_params
+					, &m_device
+					) );
+
+			BX_TRACE("Device %p", m_device);
+
+			m_fmtDepth = D3DFMT_D24FS8;
+#endif // BX_PLATFORM_WINDOWS
+
+			postReset();
+
+			m_initialized = true;
+		}
+
+		void shutdown()
+		{
+			preReset();
+
+			for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
+			{
+				m_indexBuffers[ii].destroy();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_vertexBuffers); ++ii)
+			{
+				m_vertexBuffers[ii].destroy();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_vertexShaders); ++ii)
+			{
+				m_vertexShaders[ii].destroy();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_fragmentShaders); ++ii)
+			{
+				m_fragmentShaders[ii].destroy();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_textures); ++ii)
+			{
+				m_textures[ii].destroy();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_vertexDecls); ++ii)
+			{
+				m_vertexDecls[ii].destroy();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_renderTargets); ++ii)
+			{
+				m_renderTargets[ii].destroy();
+			}
+
+			DX_RELEASE(m_device, 0);
+			DX_RELEASE(m_d3d9, 0);
+
+#if BX_PLATFORM_WINDOWS
+			FreeLibrary(m_d3d9dll);
+#endif // BX_PLATFORM_WINDOWS
+
+			m_initialized = false;
+		}
+
+		void updateMsaa()
+		{
+			for (uint32_t ii = 1, last = 0; ii < countof(s_checkMsaa); ++ii)
+			{
+				D3DMULTISAMPLE_TYPE msaa = s_checkMsaa[ii];
+				DWORD quality;
+
+				HRESULT hr = m_d3d9->CheckDeviceMultiSampleType(m_adapter
+					, m_deviceType
+					, m_params.BackBufferFormat
+					, m_params.Windowed
+					, msaa
+					, &quality
+					);
+
+				if (SUCCEEDED(hr) )
+				{
+					s_msaa[ii].m_type = msaa;
+					s_msaa[ii].m_quality = uint32_imax(0, quality-1);
+					last = ii;
+				}
+				else
+				{
+					s_msaa[ii] = s_msaa[last];
+				}
+			}
+		}
+
+		void updateResolution(const Resolution& _resolution)
+		{
+			if (m_params.BackBufferWidth != _resolution.m_width
+			||  m_params.BackBufferHeight != _resolution.m_height
+			||  m_flags != _resolution.m_flags)
+			{
+				m_flags = _resolution.m_flags;
+
+				m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
+				m_textVideoMem.clear();
+
+#if BX_PLATFORM_WINDOWS
+				D3DDEVICE_CREATION_PARAMETERS dcp;
+				DX_CHECK(m_device->GetCreationParameters(&dcp) );
+
+				D3DDISPLAYMODE dm;
+				DX_CHECK(m_d3d9->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm) );
+				
+				m_params.BackBufferFormat = dm.Format;
+#endif // BX_PLATFORM_WINDOWS
+
+				m_params.BackBufferWidth = _resolution.m_width;
+				m_params.BackBufferHeight = _resolution.m_height;
+				m_params.FullScreen_RefreshRateInHz = BGFX_RESET_FULLSCREEN == (m_flags&BGFX_RESET_FULLSCREEN_MASK) ? 60 : 0;
+				m_params.PresentationInterval = !!(m_flags&BGFX_RESET_VSYNC) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
+
+				updateMsaa();
+
+				Msaa& msaa = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
+				m_params.MultiSampleType = msaa.m_type;
+				m_params.MultiSampleQuality = msaa.m_quality;
+
+				preReset();
+				DX_CHECK(m_device->Reset(&m_params) );
+				postReset();
+			}
+		}
+
+		void setRenderTarget(RenderTargetHandle _rt, bool _msaa = true)
+		{
+			if (_rt.idx == invalidHandle)
+			{
+				DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
+				DX_CHECK(m_device->SetDepthStencilSurface(m_backBufferDepthStencil) );
+			}
+			else
+			{
+				RenderTarget& renderTarget = m_renderTargets[_rt.idx];
+				if (NULL != renderTarget.m_rt)
+				{
+					DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_rt) );
+				}
+				else
+				{
+					DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_color) );
+				}
+
+				DX_CHECK(m_device->SetDepthStencilSurface(NULL != renderTarget.m_depth ? renderTarget.m_depth : m_backBufferDepthStencil) );
+			}
+
+			if (m_rt.idx != invalidHandle
+			&&  m_rt.idx != _rt.idx
+			&&  m_rtMsaa)
+			{
+				RenderTarget& renderTarget = m_renderTargets[m_rt.idx];
+				if (!renderTarget.m_depthOnly
+				&&  renderTarget.m_rt != NULL)
+				{
+					renderTarget.resolve();
+				}
+			}
+
+			m_rt = _rt;
+			m_rtMsaa = _msaa;
+		}
+
+		void setShaderConstantF(uint8_t _flags, uint16_t _regIndex, const float* _val, uint16_t _numRegs)
+		{
+			if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
+			{
+				DX_CHECK(m_device->SetPixelShaderConstantF(_regIndex, _val, _numRegs) );
+			}
+			else
+			{
+				DX_CHECK(m_device->SetVertexShaderConstantF(_regIndex, _val, _numRegs) );
+			}
+		}
+
+		void reset()
+		{
+			preReset();
+
+			HRESULT hr;
+
+			do 
+			{
+				hr = m_device->Reset(&m_params);
+			} while (FAILED(hr) );
+
+			postReset();
+		}
+
+		bool isLost(HRESULT _hr) const
+		{
+			return D3DERR_DEVICELOST == _hr
+				|| D3DERR_DRIVERINTERNALERROR == _hr
+#if !defined(D3D_DISABLE_9EX)
+				|| D3DERR_DEVICEHUNG == _hr
+				|| D3DERR_DEVICEREMOVED == _hr
+#endif // !defined(D3D_DISABLE_9EX)
+				;
+		}
+
+		void flip()
+		{
+			if (NULL != m_device)
+			{
+#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
+				DX_CHECK(m_device->WaitForVBlank(0) );
+#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
+
+				HRESULT hr;
+				hr = m_device->Present(NULL, NULL, NULL, NULL);
+
+#if BX_PLATFORM_WINDOWS
+				if (isLost(hr) )
+				{
+					do
+					{
+						do 
+						{
+							hr = m_device->TestCooperativeLevel();
+						}
+						while (D3DERR_DEVICENOTRESET != hr);
+
+						reset();
+						hr = m_device->TestCooperativeLevel();
+					}
+					while (FAILED(hr) );
+				}
+				else if (FAILED(hr) )
+				{
+					BX_TRACE("Present failed with err 0x%08x.", hr);
+				}
+#endif // BX_PLATFORM_
+			}
+		}
+
+		void preReset()
+		{
+			for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
+			{
+				DX_CHECK(m_device->SetTexture(stage, NULL) );
+			}
+
+			DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
+			DX_CHECK(m_device->SetDepthStencilSurface(m_backBufferDepthStencil) );
+			DX_CHECK(m_device->SetVertexShader(NULL) );
+			DX_CHECK(m_device->SetPixelShader(NULL) );
+			DX_CHECK(m_device->SetStreamSource(0, NULL, 0, 0) );
+			DX_CHECK(m_device->SetIndices(NULL) );
+
+			DX_RELEASE(m_backBufferColor, 0);
+			DX_RELEASE(m_backBufferDepthStencil, 0);
+
+			for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
+			{
+				m_indexBuffers[ii].preReset();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_vertexBuffers); ++ii)
+			{
+				m_vertexBuffers[ii].preReset();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_renderTargets); ++ii)
+			{
+				m_renderTargets[ii].preReset();
+			}
+		}
+
+		void postReset()
+		{
+			DX_CHECK(m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_backBufferColor) );
+			DX_CHECK(m_device->GetDepthStencilSurface(&m_backBufferDepthStencil) );
+
+			for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
+			{
+				m_indexBuffers[ii].postReset();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_vertexBuffers); ++ii)
+			{
+				m_vertexBuffers[ii].postReset();
+			}
+
+			for (uint32_t ii = 0; ii < countof(m_renderTargets); ++ii)
+			{
+				m_renderTargets[ii].postReset();
+			}
+		}
+
+		void saveScreenShot(Memory* _mem)
+		{
+#if BX_PLATFORM_WINDOWS
+			IDirect3DSurface9* surface;
+			D3DDEVICE_CREATION_PARAMETERS dcp;
+			DX_CHECK(m_device->GetCreationParameters(&dcp) );
+
+			D3DDISPLAYMODE dm;
+			DX_CHECK(m_d3d9->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm) );
+
+			DX_CHECK(m_device->CreateOffscreenPlainSurface(dm.Width
+				, dm.Height
+				, D3DFMT_A8R8G8B8
+				, D3DPOOL_SCRATCH
+				, &surface
+				, NULL
+				) );
+
+			DX_CHECK(m_device->GetFrontBufferData(0, surface) );
+
+			D3DLOCKED_RECT rect;
+			DX_CHECK(surface->LockRect(&rect
+				, NULL
+				, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY
+				) );
+
+			RECT rc;
+			GetClientRect(g_bgfxHwnd, &rc);
+			POINT point;
+			point.x = rc.left;
+			point.y = rc.top;
+			ClientToScreen(g_bgfxHwnd, &point);
+			uint8_t* data = (uint8_t*)rect.pBits;
+			uint32_t bpp = rect.Pitch/dm.Width;
+			saveTga( (const char*)_mem->data, m_params.BackBufferWidth, m_params.BackBufferHeight, rect.Pitch, &data[point.y*rect.Pitch+point.x*bpp]);
+
+			DX_CHECK(surface->UnlockRect() );
+			DX_RELEASE(surface, 0);
+#endif // BX_PLATFORM_WINDOWS
+		}
+
+#if BX_PLATFORM_WINDOWS
+		D3DCAPS9 m_caps;
+
+		D3DPERF_SetMarkerFunc m_D3DPERF_SetMarker;
+		D3DPERF_BeginEventFunc m_D3DPERF_BeginEvent;
+		D3DPERF_EndEventFunc m_D3DPERF_EndEvent;
+#endif // BX_PLATFORM_WINDOWS
+
+#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
+		IDirect3D9Ex* m_d3d9;
+		IDirect3DDevice9Ex* m_device;
+#else
+		IDirect3D9* m_d3d9;
+		IDirect3DDevice9* m_device;
+#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
+
+		IDirect3DSurface9* m_backBufferColor;
+		IDirect3DSurface9* m_backBufferDepthStencil;
+		IDirect3DVertexDeclaration9* m_instanceDataDecls[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
+
+		HMODULE m_d3d9dll;
+		uint32_t m_adapter;
+		D3DDEVTYPE m_deviceType;
+		D3DPRESENT_PARAMETERS m_params;
+		uint32_t m_flags;
+
+		bool m_initialized;
+		bool m_amd;
+		bool m_nvidia;
+		bool m_instancing;
+
+		D3DFORMAT m_fmtDepth;
+
+		IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
+		VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
+		Shader m_vertexShaders[BGFX_CONFIG_MAX_VERTEX_SHADERS];
+		Shader m_fragmentShaders[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
+		Material m_materials[BGFX_CONFIG_MAX_MATERIALS];
+		Texture m_textures[BGFX_CONFIG_MAX_TEXTURES];
+		VertexDeclaration m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
+		RenderTarget m_renderTargets[BGFX_CONFIG_MAX_RENDER_TARGETS];
+		UniformRegistry m_uniformReg;
+		void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
+
+		TextVideoMem m_textVideoMem;
+		RenderTargetHandle m_rt;
+		bool m_rtMsaa;
+	};
+
+	static RendererContext s_renderCtx;
+
+	void IndexBuffer::create(uint32_t _size, void* _data)
+	{
+		m_size = _size;
+		m_dynamic = NULL == _data;
+
+		uint32_t usage = D3DUSAGE_WRITEONLY;
+		D3DPOOL pool = D3DPOOL_MANAGED;
+
+		if (m_dynamic)
+		{
+			usage |= D3DUSAGE_DYNAMIC;
+			pool = D3DPOOL_DEFAULT;
+		}
+
+		DX_CHECK(s_renderCtx.m_device->CreateIndexBuffer(m_size
+			, usage
+			, D3DFMT_INDEX16
+			, pool
+			, &m_ptr
+			, NULL
+			) );
+
+		if (NULL != _data)
+		{
+			update(0, _size, _data);
+		}
+	}
+
+	void IndexBuffer::preReset()
+	{
+		if (m_dynamic)
+		{
+			DX_RELEASE(m_ptr, 0);
+		}
+	}
+
+	void IndexBuffer::postReset()
+	{
+		if (m_dynamic)
+		{
+			DX_CHECK(s_renderCtx.m_device->CreateIndexBuffer(m_size
+				, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC
+				, D3DFMT_INDEX16
+				, D3DPOOL_DEFAULT
+				, &m_ptr
+				, NULL
+				) );
+		}
+	}
+
+	void VertexBuffer::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle)
+	{
+		m_size = _size;
+		m_decl = _declHandle;
+		m_dynamic = NULL == _data;
+
+		uint32_t usage = D3DUSAGE_WRITEONLY;
+		D3DPOOL pool = D3DPOOL_MANAGED;
+
+		if (m_dynamic)
+		{
+			usage |= D3DUSAGE_DYNAMIC;
+			pool = D3DPOOL_DEFAULT;
+		}
+
+		DX_CHECK(s_renderCtx.m_device->CreateVertexBuffer(m_size
+				, usage
+				, 0
+				, pool
+				, &m_ptr
+				, NULL 
+				) );
+
+		if (NULL != _data)
+		{
+			update(0, _size, _data);
+		}
+	}
+
+	void VertexBuffer::preReset()
+	{
+		if (m_dynamic)
+		{
+			DX_RELEASE(m_ptr, 0);
+		}
+	}
+
+	void VertexBuffer::postReset()
+	{
+		if (m_dynamic)
+		{
+			DX_CHECK(s_renderCtx.m_device->CreateVertexBuffer(m_size
+					, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC
+					, 0
+					, D3DPOOL_DEFAULT
+					, &m_ptr
+					, NULL 
+					) );
+		}
+	}
+
+	static const D3DVERTEXELEMENT9 s_attrib[Attrib::Count+1] =
+	{
+		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,     0 },
+		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,       0 },
+		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        0 },
+		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        1 },
+		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
+		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,  0 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     0 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     1 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     2 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     3 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     4 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     5 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     6 },
+		{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     7 },
+		D3DDECL_END()
+	};
+
+	static D3DVERTEXELEMENT9* fillVertexDecl(D3DVERTEXELEMENT9* _out, uint32_t _count, const VertexDecl& _decl)
+	{
+		D3DVERTEXELEMENT9* elem = _out;
+
+		for (uint32_t attr = 0; attr < Attrib::Count; ++attr)
+		{
+			if (0xff != _decl.m_attributes[attr])
+			{
+				uint8_t num;
+				AttribType::Enum type;
+				bool normalized;
+				_decl.decode(Attrib::Enum(attr), num, type, normalized);
+
+				memcpy(elem, &s_attrib[attr], sizeof(D3DVERTEXELEMENT9) );
+
+				D3DDECLTYPE declType = D3DDECLTYPE(elem->Type);
+
+				switch (type)
+				{
+				case AttribType::Uint8:
+					if (normalized)
+					{
+						declType = D3DDECLTYPE_UBYTE4N;
+					}
+					else
+					{
+						declType = D3DDECLTYPE_UBYTE4;
+					}
+					break;
+
+				case AttribType::Uint16:
+					if (normalized)
+					{
+						switch (num)
+						{
+						default:
+						case 2:
+							declType = D3DDECLTYPE_SHORT2N;
+							break;
+
+						case 4:
+							declType = D3DDECLTYPE_SHORT4N;
+							break;
+						}
+					}
+					else
+					{
+						switch (num)
+						{
+						default:
+						case 2:
+							declType = D3DDECLTYPE_SHORT2;
+							break;
+
+						case 4:
+							declType = D3DDECLTYPE_SHORT4;
+							break;
+						}
+					}
+					break;
+
+				case AttribType::Float:
+					switch (num)
+					{
+					case 1:
+						declType = D3DDECLTYPE_FLOAT1;
+						break;
+
+					case 2:
+						declType = D3DDECLTYPE_FLOAT2;
+						break;
+
+					default:
+					case 3:
+						declType = D3DDECLTYPE_FLOAT3;
+						break;
+
+					case 4:
+						declType = D3DDECLTYPE_FLOAT4;
+						break;
+					}
+
+					break;
+
+				default:
+					BX_CHECK(false, "Invalid attrib type.");
+					break;
+				}
+
+				elem->Type = declType;
+				elem->Offset = _decl.m_offset[attr];
+				++elem;
+			}
+		}
+
+		return elem;
+	}
+
+	static IDirect3DVertexDeclaration9* createVertexDecl(const VertexDecl& _decl, uint8_t _numInstanceData)
+	{
+		D3DVERTEXELEMENT9 vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
+		D3DVERTEXELEMENT9* elem = fillVertexDecl(vertexElements, Attrib::Count, _decl);
+
+		const D3DVERTEXELEMENT9 inst = { 1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 };
+
+		for (uint32_t ii = 0; ii < _numInstanceData; ++ii)
+		{
+			memcpy(elem, &inst, sizeof(D3DVERTEXELEMENT9) );
+			elem->UsageIndex = 8-_numInstanceData+ii;
+			elem->Offset = ii*16;
+			++elem;
+		}
+
+		memcpy(elem, &s_attrib[Attrib::Count], sizeof(D3DVERTEXELEMENT9) );
+
+		IDirect3DVertexDeclaration9* ptr;
+		DX_CHECK(s_renderCtx.m_device->CreateVertexDeclaration(vertexElements, &ptr) );
+		return ptr;
+	}
+
+	void VertexDeclaration::create(const VertexDecl& _decl)
+	{
+		memcpy(&m_decl, &_decl, sizeof(VertexDecl) );
+		dump(m_decl);
+		m_ptr = createVertexDecl(_decl, 0);
+	}
+
+	void Shader::create(bool _fragment, const Memory* _mem)
+	{
+		m_constantBuffer = ConstantBuffer::create(1024);
+
+		StreamRead stream(_mem->data, _mem->size);
+		uint16_t count;
+		stream.read(count);
+
+		m_numPredefined = 0;
+
+		BX_TRACE("Shader consts %d", count);
+
+		uint8_t fragmentBit = _fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0;
+
+		for (uint32_t ii = 0; ii < count; ++ii)
+		{
+			uint8_t nameSize;
+			stream.read(nameSize);
+
+			char name[256];
+			stream.read(&name, nameSize);
+			name[nameSize] = '\0';
+
+			uint8_t type;
+			stream.read(type);
+
+			uint8_t num;
+			stream.read(num);
+
+			uint16_t regIndex;
+			stream.read(regIndex);
+
+			uint16_t regCount;
+			stream.read(regCount);
+
+			const char* kind = "invalid";
+
+			const void* data = NULL;
+			PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
+			if (PredefinedUniform::Count != predefined)
+			{
+				kind = "predefined";
+				m_predefined[m_numPredefined].m_loc = regIndex;
+				m_predefined[m_numPredefined].m_count = regCount;
+				m_predefined[m_numPredefined].m_type = predefined|fragmentBit;
+				m_numPredefined++;
+			}
+			else
+			{
+				const UniformInfo* info = s_renderCtx.m_uniformReg.find(name);
+				BX_CHECK(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
+				if (NULL != info)
+				{
+					kind = "user";
+					data = info->m_data;
+					m_constantBuffer->writeUniformRef( (ConstantType::Enum)(type|fragmentBit), regIndex, data, regCount);
+				}
+			}
+
+			BX_TRACE("\t%s: %s, type %2d, num %2d, r.index %3d, r.count %2d"
+				, kind
+				, name
+				, type
+				, num
+				, regIndex
+				, regCount
+				);
+			BX_UNUSED(kind);
+		}
+
+		uint16_t shaderSize;
+		stream.read(shaderSize);
+
+		m_constantBuffer->finish();
+
+		const DWORD* code = (const DWORD*)stream.getDataPtr();
+
+		if (_fragment)
+		{
+			DX_CHECK(s_renderCtx.m_device->CreatePixelShader(code, (IDirect3DPixelShader9**)&m_ptr) );
+		}
+		else
+		{
+			DX_CHECK(s_renderCtx.m_device->CreateVertexShader(code, (IDirect3DVertexShader9**)&m_ptr) );
+		}
+	}
+
+	void Texture::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips, D3DFORMAT _fmt)
+	{
+		m_type = Texture2D;
+
+		DX_CHECK(s_renderCtx.m_device->CreateTexture(_width
+			, _height
+			, _numMips
+			, 0
+			, _fmt
+			, D3DPOOL_MANAGED
+			, (IDirect3DTexture9**)&m_ptr
+			, NULL
+			) );
+
+		BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create texture (size: %dx%d, mips: %d, fmt: 0x%08x)."
+			, _width
+			, _height
+			, _numMips
+			, _fmt
+			);
+	}
+
+	void Texture::createVolumeTexture(uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _numMips, D3DFORMAT _fmt)
+	{
+		m_type = Texture3D;
+
+		DX_CHECK(s_renderCtx.m_device->CreateVolumeTexture(_width
+			, _height
+			, _depth
+			, _numMips
+			, 0
+			, _fmt
+			, D3DPOOL_MANAGED
+			, (IDirect3DVolumeTexture9**)&m_ptr
+			, NULL
+			) );
+
+		BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create volume texture (size: %dx%dx%d, mips: %d, fmt: 0x%08x)."
+			, _width
+			, _height
+			, _depth
+			, _numMips
+			, _fmt
+			);
+	}
+
+	void Texture::createCubeTexture(uint32_t _edge, uint32_t _numMips, D3DFORMAT _fmt)
+	{
+		m_type = TextureCube;
+
+		DX_CHECK(s_renderCtx.m_device->CreateCubeTexture(_edge
+			, _numMips
+			, 0
+			, _fmt
+			, D3DPOOL_MANAGED
+			, (IDirect3DCubeTexture9**)&m_ptr
+			, NULL
+			) );
+
+		BGFX_FATAL(NULL != m_ptr, Fatal::D3D9_UnableToCreateTexture, "Failed to create cube texture (edge: %d, mips: %d, fmt: 0x%08x)."
+			, _edge
+			, _numMips
+			, _fmt
+			);
+	}
+
+	uint8_t* Texture::lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch)
+	{
+		switch (m_type)
+		{
+		case Texture2D:
+			{
+				IDirect3DTexture9* texture = (IDirect3DTexture9*)m_ptr;
+				D3DLOCKED_RECT rect;
+				DX_CHECK(texture->LockRect(_lod, &rect, NULL, 0) );
+				_pitch = rect.Pitch;
+				_slicePitch = 0;
+				return (uint8_t*)rect.pBits;
+			}
+
+		case Texture3D:
+			{
+				IDirect3DVolumeTexture9* texture = (IDirect3DVolumeTexture9*)m_ptr;
+				D3DLOCKED_BOX box;
+				DX_CHECK(texture->LockBox(_lod, &box, NULL, 0) );
+				_pitch = box.RowPitch;
+				_slicePitch = box.SlicePitch;
+				return (uint8_t*)box.pBits;
+			}
+
+		case TextureCube:
+			{
+				IDirect3DCubeTexture9* texture = (IDirect3DCubeTexture9*)m_ptr;
+				D3DLOCKED_RECT rect;
+				DX_CHECK(texture->LockRect(D3DCUBEMAP_FACES(_side), _lod, &rect, NULL, 0) );
+				_pitch = rect.Pitch;
+				_slicePitch = 0;
+				return (uint8_t*)rect.pBits;
+			}
+		}
+
+		BX_CHECK(false, "You should not be here.");
+		return NULL;
+	}
+
+	void Texture::unlock(uint8_t _side, uint8_t _lod)
+	{
+		switch (m_type)
+		{
+		case Texture2D:
+			{
+				IDirect3DTexture9* texture = (IDirect3DTexture9*)m_ptr;
+				DX_CHECK(texture->UnlockRect(_lod) );
+			}
+			return;
+
+		case Texture3D:
+			{
+				IDirect3DVolumeTexture9* texture = (IDirect3DVolumeTexture9*)m_ptr;
+				DX_CHECK(texture->UnlockBox(_lod) );
+			}
+			return;
+
+		case TextureCube:
+			{
+				IDirect3DCubeTexture9* texture = (IDirect3DCubeTexture9*)m_ptr;
+				DX_CHECK(texture->UnlockRect(D3DCUBEMAP_FACES(_side), _lod) );
+			}
+			return;
+		}
+
+		BX_CHECK(false, "You should not be here.");
+	}
+
+	void Texture::create(const Memory* _mem, uint32_t _flags)
+	{
+		m_tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
+		m_tav = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT];
+		m_taw = s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT];
+		m_minFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
+		m_magFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
+		m_mipFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT];
+		m_srgb = (_flags&BGFX_TEXTURE_SRGB) == BGFX_TEXTURE_SRGB;
+
+		Dds dds;
+
+		if (parseDds(dds, _mem) )
+		{
+			uint8_t bpp = dds.m_bpp;
+
+			bool decompress = false;
+
+			if (dds.m_cubeMap)
+			{
+				createCubeTexture(dds.m_width, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
+			}
+			else if (dds.m_depth > 1)
+			{
+				createVolumeTexture(dds.m_width, dds.m_height, dds.m_depth, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
+			}
+			else
+			{
+				createTexture(dds.m_width, dds.m_height, dds.m_numMips, s_textureFormat[dds.m_type].m_fmt);
+			}
+
+			if (decompress
+			||  TextureFormat::Unknown < dds.m_type)
+			{
+				for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
+				{
+					uint32_t width = dds.m_width;
+					uint32_t height = dds.m_height;
+					uint32_t depth = dds.m_depth;
+
+					for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
+					{
+						width = uint32_max(1, width);
+						height = uint32_max(1, height);
+						depth = uint32_max(1, depth);
+
+						Mip mip;
+						if (getRawImageData(dds, side, lod, _mem, mip) )
+						{
+							uint32_t pitch;
+							uint32_t slicePitch;
+							uint8_t* bits = lock(side, lod, pitch, slicePitch);
+
+							if (width != mip.m_width
+							||  height != mip.m_height)
+							{
+								uint32_t srcpitch = mip.m_width*bpp;
+
+								uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
+								mip.decode(temp);
+
+								uint32_t dstpitch = pitch;
+								for (uint32_t yy = 0; yy < height; ++yy)
+								{
+									uint8_t* src = &temp[yy*srcpitch];
+									uint8_t* dst = &bits[yy*dstpitch];
+									memcpy(dst, src, srcpitch);
+								}
+
+								g_free(temp);
+							}
+							else
+							{
+								mip.decode(bits);
+							}
+
+							unlock(side, lod);
+						}
+
+						width >>= 1;
+						height >>= 1;
+						depth >>= 1;
+					}
+				}
+			}
+			else
+			{
+				for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
+				{
+					for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
+					{
+						Mip mip;
+						if (getRawImageData(dds, 0, lod, _mem, mip) )
+						{
+							uint32_t pitch;
+							uint32_t slicePitch;
+							uint8_t* dst = lock(side, lod, pitch, slicePitch);
+
+							memcpy(dst, mip.m_data, mip.m_size);
+
+							unlock(side, lod);
+						}
+					}
+				}
+			}
+		}
+		else
+		{
+			StreamRead stream(_mem->data, _mem->size);
+
+			uint32_t magic;
+			stream.read(magic);
+
+			if (BGFX_MAGIC == magic)
+			{
+				uint16_t width;
+				stream.read(width);
+
+				uint16_t height;
+				stream.read(height);
+
+				uint8_t bpp;
+				stream.read(bpp);
+
+				uint8_t numMips;
+				stream.read(numMips);
+
+				stream.align(16);
+
+				D3DFORMAT fmt = 1 == bpp ? D3DFMT_L8 : D3DFMT_A8R8G8B8;
+
+				createTexture(width, height, numMips, fmt);
+
+				for (uint8_t mip = 0; mip < numMips; ++mip)
+				{
+					width = uint32_max(width, 1);
+					height = uint32_max(height, 1);
+
+					uint32_t pitch;
+					uint32_t slicePitch;
+					uint8_t* dst = lock(0, mip, pitch, slicePitch);
+					stream.read(dst, width*height*bpp);
+					unlock(0, mip);
+
+					width >>= 1;
+					height >>= 1;
+				}
+			}
+			else
+			{
+				//
+			}
+		}
+	}
+
+	void Texture::commit(uint8_t _stage)
+	{
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MINFILTER, m_minFilter) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MAGFILTER, m_magFilter) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, m_mipFilter) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, m_tau) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, m_tav) );
+		if (m_type == Texture3D)
+		{
+			DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSW, m_taw) );
+		}
+#if BX_PLATFORM_WINDOWS
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, m_srgb) );
+#endif // BX_PLATFORM_WINDOWS
+		DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_ptr) );
+	}
+
+	void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
+	{
+		m_width = _width;
+		m_height = _height;
+		m_flags = _flags;
+		m_minFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
+		m_magFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
+
+		createTextures();
+	}
+
+	void RenderTarget::createTextures()
+	{
+		if (0 != m_flags)
+		{
+			m_msaa = s_msaa[(m_flags&BGFX_RENDER_TARGET_MSAA_MASK)>>BGFX_RENDER_TARGET_MSAA_SHIFT];
+			uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
+			uint32_t depthFormat = (m_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT;
+			m_depthOnly = (0 == colorFormat && 0 < depthFormat);
+
+			// CheckDeviceFormat D3DUSAGE_SRGBWRITE
+
+			if (m_depthOnly)
+			{
+				DX_CHECK(s_renderCtx.m_device->CreateRenderTarget(1
+					, 1
+					, D3DFMT_R5G6B5
+					, D3DMULTISAMPLE_NONE
+					, 0
+					, false
+					, &m_rt
+					, NULL
+					) );
+
+				BGFX_FATAL(m_rt, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create 1x1 render target.");
+
+				DX_CHECK(s_renderCtx.m_device->CreateTexture(m_width
+					, m_height
+					, 1
+					, D3DUSAGE_DEPTHSTENCIL
+					, D3DFMT_DF24 //s_depthFormat[depthFormat]
+					, D3DPOOL_DEFAULT
+					, &m_depthTexture
+					, NULL
+					) );
+
+				BGFX_FATAL(m_depthTexture, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create depth texture.");
+
+				DX_CHECK(m_depthTexture->GetSurfaceLevel(0, &m_depth) );
+			}
+			else
+			{
+				if (D3DMULTISAMPLE_NONE != m_msaa.m_type)
+				{
+					DX_CHECK(s_renderCtx.m_device->CreateRenderTarget(m_width
+						, m_height
+						, s_colorFormat[colorFormat]
+						, m_msaa.m_type
+						, m_msaa.m_quality
+						, false
+						, &m_rt
+						, NULL
+						) );
+
+					BGFX_FATAL(m_rt, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create MSAA render target.");
+				}
+
+				if (0 < colorFormat)
+				{
+					DX_CHECK(s_renderCtx.m_device->CreateTexture(m_width
+						, m_height
+						, 1
+						, D3DUSAGE_RENDERTARGET
+						, s_colorFormat[colorFormat]
+						, D3DPOOL_DEFAULT
+						, &m_colorTexture
+						, NULL
+						) );
+
+					BGFX_FATAL(m_colorTexture, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create color render target.");
+
+					DX_CHECK(m_colorTexture->GetSurfaceLevel(0, &m_color) );
+				}
+
+				if (0 < depthFormat)
+				{
+					DX_CHECK(s_renderCtx.m_device->CreateDepthStencilSurface(m_width
+							, m_height
+							, s_depthFormat[depthFormat] // s_renderCtx.m_fmtDepth
+							, m_msaa.m_type
+							, m_msaa.m_quality
+							, FALSE
+							, &m_depth
+							, NULL
+							) );
+
+					BGFX_FATAL(m_depth, Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create depth stencil surface.");
+				}
+			}
+		}
+	}
+
+	void RenderTarget::destroyTextures()
+	{
+		if (0 != m_flags)
+		{
+			if (m_depthOnly)
+			{
+				DX_RELEASE(m_rt, 0);
+
+				DX_RELEASE(m_depth, 1);
+				DX_RELEASE(m_depthTexture, 0);
+			}
+			else
+			{
+				uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
+				uint32_t depthFormat = (m_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT;
+
+				if (D3DMULTISAMPLE_NONE != m_msaa.m_type)
+				{
+					DX_RELEASE(m_rt, 0);
+				}
+
+				if (0 < colorFormat)
+				{
+					DX_RELEASE(m_color, 1);
+					DX_RELEASE(m_colorTexture, 0);
+				}
+
+				if (0 < depthFormat)
+				{
+					DX_RELEASE(m_depth, 0);
+				}
+			}
+		}
+	}
+
+	void RenderTarget::commit(uint8_t _stage)
+	{
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MINFILTER, m_minFilter) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MAGFILTER, m_magFilter) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, D3DTEXF_POINT) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP) );
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP) );
+#if BX_PLATFORM_WINDOWS
+		DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, (m_flags&BGFX_RENDER_TARGET_SRGBWRITE) == BGFX_RENDER_TARGET_SRGBWRITE) );
+#endif // BX_PLATFORM_WINDOWS
+		DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_depthOnly ? m_depthTexture : m_colorTexture) );
+	}
+
+	void RenderTarget::resolve()
+	{
+#if BX_PLATFORM_WINDOWS
+		DX_CHECK(s_renderCtx.m_device->StretchRect(m_rt
+				, NULL
+				, m_color
+				, NULL
+				, D3DTEXF_NONE
+				) );
+#endif // BX_PLATFORM_WINDOWS
+	}
+
+	void ConstantBuffer::commit()
+	{
+		reset();
+
+		do
+		{
+			uint32_t opcode = read();
+
+			if (ConstantType::End == opcode)
+			{
+				break;
+			}
+
+			ConstantType::Enum type;
+			uint16_t loc;
+			uint16_t num;
+			uint16_t copy;
+			decodeOpcode(opcode, type, loc, num, copy);
+
+			const char* data;
+			if (copy)
+			{
+				data = read(g_constantTypeSize[type]*num);
+			}
+			else
+			{
+				memcpy(&data, read(sizeof(void*) ), sizeof(void*) );
+			}
+
+#define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
+		case ConstantType::_uniform: \
+		{ \
+			_type* value = (_type*)data; \
+			s_renderCtx.m_device->SetVertexShaderConstant##_dxsuffix(loc, value, num); \
+		} \
+		break; \
+		\
+		case ConstantType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
+		{ \
+			_type* value = (_type*)data; \
+			s_renderCtx.m_device->SetPixelShaderConstant##_dxsuffix(loc, value, num); \
+		} \
+		break;
+
+			switch ((int32_t)type)
+			{
+			CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
+			CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
+			CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform3x3fv, Matrix3fv, F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, Matrix4fv, F, float);
+
+			case ConstantType::End:
+				break;
+
+			default:
+				BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", m_pos, opcode, type, loc, num, copy);
+				break;
+			}
+
+#undef CASE_IMPLEMENT_UNIFORM
+
+		} while (true);
+	}
+
+	void TextVideoMemBlitter::setup()
+	{
+		uint32_t width = s_renderCtx.m_params.BackBufferWidth;
+		uint32_t height = s_renderCtx.m_params.BackBufferHeight;
+
+		RenderTargetHandle rt = BGFX_INVALID_HANDLE;
+		s_renderCtx.setRenderTarget(rt, false);
+
+		D3DVIEWPORT9 vp;
+		vp.X = 0;
+		vp.Y = 0;
+		vp.Width = width;
+		vp.Height = height;
+		vp.MinZ = 0.0f;
+		vp.MaxZ = 1.0f;
+		DX_CHECK(s_renderCtx.m_device->SetViewport(&vp) );
+
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ZENABLE, FALSE) );
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS) );
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE) );
+		DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID) );
+
+		Material& material = s_renderCtx.m_materials[m_material.idx];
+		s_renderCtx.m_device->SetVertexShader( (IDirect3DVertexShader9*)material.m_vsh->m_ptr);
+		s_renderCtx.m_device->SetPixelShader( (IDirect3DPixelShader9*)material.m_fsh->m_ptr);
+
+		VertexBuffer& vb = s_renderCtx.m_vertexBuffers[m_vb->handle.idx];
+		VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[m_vb->decl.idx];
+		DX_CHECK(s_renderCtx.m_device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) );
+		DX_CHECK(s_renderCtx.m_device->SetVertexDeclaration(vertexDecl.m_ptr) );
+
+		IndexBuffer& ib = s_renderCtx.m_indexBuffers[m_ib->handle.idx];
+		DX_CHECK(s_renderCtx.m_device->SetIndices(ib.m_ptr) );
+
+		float proj[16];
+		matrix_ortho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f);
+
+		PredefinedUniform& predefined = material.m_predefined[0];
+		uint8_t flags = predefined.m_type;
+		s_renderCtx.setShaderConstantF(flags, predefined.m_loc, proj, 4);
+
+		s_renderCtx.m_textures[m_texture.idx].commit(0);
+	}
+
+	void TextVideoMemBlitter::render(uint32_t _numIndices)
+	{
+		uint32_t numVertices = _numIndices*4/6;
+		s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(0, _numIndices*2, m_ib->data);
+		s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(0, numVertices*m_decl.m_stride, m_vb->data);
+
+		DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST
+			, 0
+			, 0
+			, numVertices
+			, 0
+			, _numIndices/3
+			) );
+	}
+
+	void Context::flip()
+	{
+		s_renderCtx.flip();
+	}
+
+	void Context::rendererInit()
+	{
+		s_renderCtx.init();
+	}
+
+	void Context::rendererShutdown()
+	{
+		s_renderCtx.shutdown();
+	}
+
+	void Context::rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem)
+	{
+		s_renderCtx.m_indexBuffers[_handle.idx].create(_mem->size, _mem->data);
+	}
+
+	void Context::rendererDestroyIndexBuffer(IndexBufferHandle _handle)
+	{
+		s_renderCtx.m_indexBuffers[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl)
+	{
+		s_renderCtx.m_vertexDecls[_handle.idx].create(_decl);
+	}
+
+	void Context::rendererDestroyVertexDecl(VertexDeclHandle _handle)
+	{
+		s_renderCtx.m_vertexDecls[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle)
+	{
+		s_renderCtx.m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle);
+	}
+
+	void Context::rendererDestroyVertexBuffer(VertexBufferHandle _handle)
+	{
+		s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size)
+	{
+		s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL);
+	}
+
+	void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
+	{
+		s_renderCtx.m_indexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
+	}
+
+	void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle)
+	{
+		s_renderCtx.m_indexBuffers[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size)
+	{
+		VertexDeclHandle decl = BGFX_INVALID_HANDLE;
+		s_renderCtx.m_vertexBuffers[_handle.idx].create(_size, NULL, decl);
+	}
+
+	void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
+	{
+		s_renderCtx.m_vertexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
+	}
+
+	void Context::rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle)
+	{
+		s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem)
+	{
+		s_renderCtx.m_vertexShaders[_handle.idx].create(false, _mem);
+	}
+
+	void Context::rendererDestroyVertexShader(VertexShaderHandle _handle)
+	{
+		s_renderCtx.m_vertexShaders[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateFragmentShader(FragmentShaderHandle _handle, Memory* _mem)
+	{
+		s_renderCtx.m_fragmentShaders[_handle.idx].create(true, _mem);
+	}
+
+	void Context::rendererDestroyFragmentShader(FragmentShaderHandle _handle)
+	{
+		s_renderCtx.m_fragmentShaders[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateMaterial(MaterialHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
+	{
+		s_renderCtx.m_materials[_handle.idx].create(s_renderCtx.m_vertexShaders[_vsh.idx], s_renderCtx.m_fragmentShaders[_fsh.idx]);
+	}
+
+	void Context::rendererDestroyMaterial(FragmentShaderHandle _handle)
+	{
+		s_renderCtx.m_materials[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
+	{
+		s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
+	}
+
+	void Context::rendererDestroyTexture(TextureHandle _handle)
+	{
+		s_renderCtx.m_textures[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
+	{
+		s_renderCtx.m_renderTargets[_handle.idx].create(_width, _height, _flags, _textureFlags);
+	}
+
+	void Context::rendererDestroyRenderTarget(RenderTargetHandle _handle)
+	{
+		s_renderCtx.m_renderTargets[_handle.idx].destroy();
+	}
+
+	void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
+	{
+		uint32_t size = BX_ALIGN_16(g_constantTypeSize[_type]*_num);
+		void* data = g_realloc(NULL, size);
+		s_renderCtx.m_uniforms[_handle.idx] = data;
+		s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
+	}
+
+	void Context::rendererDestroyUniform(UniformHandle _handle)
+	{
+		g_free(s_renderCtx.m_uniforms[_handle.idx]);
+	}
+
+	void Context::rendererSaveScreenShot(Memory* _mem)
+	{
+		s_renderCtx.saveScreenShot(_mem);
+	}
+
+	void Context::rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size)
+	{
+		memcpy(s_renderCtx.m_uniforms[_loc], _data, _size);
+	}
+
+	void Context::rendererSubmit()
+	{
+		IDirect3DDevice9* device = s_renderCtx.m_device;
+
+		PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), "rendererSubmit");
+
+		s_renderCtx.updateResolution(m_render->m_resolution);
+
+		device->BeginScene();
+
+		if (0 < m_render->m_iboffset)
+		{
+			TransientIndexBuffer* ib = m_render->m_transientIb;
+			s_renderCtx.m_indexBuffers[ib->handle.idx].update(0, m_render->m_iboffset, ib->data);
+		}
+
+		if (0 < m_render->m_vboffset)
+		{
+			TransientVertexBuffer* vb = m_render->m_transientVb;
+			s_renderCtx.m_vertexBuffers[vb->handle.idx].update(0, m_render->m_vboffset, vb->data);
+		}
+
+		m_render->sort();
+
+		RenderState currentState;
+		currentState.reset();
+		currentState.m_flags = BGFX_STATE_NONE;
+
+		Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
+		for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
+		{
+			matrix_mul(viewProj[ii].val, m_render->m_view[ii].val, m_render->m_proj[ii].val);
+		}
+
+		DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, m_render->m_debug&BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID) );
+		uint16_t materialIdx = invalidHandle;
+		SortKey key;
+		uint8_t view = 0xff;
+		RenderTargetHandle rt = BGFX_INVALID_HANDLE;
+		float alphaRef = 0.0f;
+		D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST;
+		uint32_t primNumVerts = 3;
+
+		uint32_t statsNumPrimsSubmitted = 0;
+		uint32_t statsNumIndices = 0;
+		uint32_t statsNumInstances = 0;
+		uint32_t statsNumPrimsRendered = 0;
+
+		int64_t elapsed = -bx::getHPCounter();
+
+		if (0 == (m_render->m_debug&BGFX_DEBUG_IFH) )
+		{
+			for (uint32_t item = 0, numItems = m_render->m_num; item < numItems; ++item)
+			{
+				key.decode(m_render->m_sortKeys[item]);
+				const RenderState& state = m_render->m_renderState[m_render->m_sortValues[item] ];
+
+				const uint64_t newFlags = state.m_flags;
+				uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
+				currentState.m_flags = newFlags;
+
+				if (key.m_view != view)
+				{
+					currentState.clear();
+					changedFlags = BGFX_STATE_MASK;
+					currentState.m_flags = newFlags;
+
+					PIX_ENDEVENT();
+					PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), "view");
+
+					view = key.m_view;
+
+					materialIdx = invalidHandle;
+
+					if (m_render->m_rt[view].idx != rt.idx)
+					{
+						rt = m_render->m_rt[view];
+						s_renderCtx.setRenderTarget(rt);
+					}
+
+					Rect& rect = m_render->m_rect[view];
+
+					D3DVIEWPORT9 vp;
+					vp.X = rect.m_x;
+					vp.Y = rect.m_y;
+					vp.Width = rect.m_width;
+					vp.Height = rect.m_height;
+					vp.MinZ = 0.0f;
+					vp.MaxZ = 1.0f;
+					DX_CHECK(device->SetViewport(&vp) );
+
+					Clear& clear = m_render->m_clear[view];
+
+					if (BGFX_CLEAR_NONE != clear.m_flags)
+					{
+						D3DCOLOR color = 0;
+						DWORD flags = 0;
+
+						if (BGFX_CLEAR_COLOR_BIT & clear.m_flags)
+						{
+							flags |= D3DCLEAR_TARGET;
+							uint32_t rgba = clear.m_rgba;
+							color = D3DCOLOR_RGBA(rgba>>24, (rgba>>16)&0xff, (rgba>>8)&0xff, rgba&0xff);
+							DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA) );
+						}
+
+						if (BGFX_CLEAR_DEPTH_BIT & clear.m_flags)
+						{
+							flags |= D3DCLEAR_ZBUFFER;
+							DX_CHECK(device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE) );
+						}
+
+						if (BGFX_CLEAR_STENCIL_BIT & clear.m_flags)
+						{
+							flags |= D3DCLEAR_STENCIL;
+						}
+
+						if (0 != flags)
+						{
+							RECT rc;
+							rc.left = rect.m_x;
+							rc.top = rect.m_y;
+							rc.right = rect.m_x + rect.m_width;
+							rc.bottom = rect.m_y + rect.m_height;
+							DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE) );
+							DX_CHECK(device->SetScissorRect(&rc) );
+							DX_CHECK(device->Clear(0, NULL, flags, color, clear.m_depth, clear.m_stencil) );
+							DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE) );
+						}
+					}
+
+ 					DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
+					DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS) );
+					DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
+					DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
+					DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
+				}
+
+				if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
+					 |BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
+					 |BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK
+					 |BGFX_STATE_POINT_SIZE_MASK|BGFX_STATE_SRGBWRITE|BGFX_STATE_MSAA) & changedFlags)
+				{
+					if (BGFX_STATE_CULL_MASK & changedFlags)
+					{
+						uint32_t cull = (newFlags&BGFX_STATE_CULL_MASK)>>BGFX_STATE_CULL_SHIFT;
+						DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, s_cullMode[cull]) );
+					}
+
+					if (BGFX_STATE_DEPTH_WRITE & changedFlags)
+					{ 
+						DX_CHECK(device->SetRenderState(D3DRS_ZWRITEENABLE, !!(BGFX_STATE_DEPTH_WRITE & newFlags) ) );
+					}
+
+					if (BGFX_STATE_DEPTH_TEST_MASK & changedFlags)
+					{
+						uint32_t func = (newFlags&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
+						DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, 0 != func) );
+
+						if (0 != func)
+						{
+							DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, s_depthFunc[func]) );
+						}
+					}
+
+					if ( (BGFX_STATE_ALPHA_TEST|BGFX_STATE_ALPHA_REF_MASK) & changedFlags)
+					{
+						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
+						alphaRef = ref/255.0f;
+						DX_CHECK(device->SetRenderState(D3DRS_ALPHAREF, ref) );
+						DX_CHECK(device->SetRenderState(D3DRS_ALPHATESTENABLE, !!(BGFX_STATE_ALPHA_TEST & newFlags) ) );
+					}
+
+					if ( (BGFX_STATE_PT_POINTS|BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
+					{
+						DX_CHECK(device->SetRenderState(D3DRS_POINTSIZE, castfu( (float)( (newFlags&BGFX_STATE_POINT_SIZE_MASK)>>BGFX_STATE_POINT_SIZE_SHIFT) ) ) );
+					}
+
+#if BX_PLATFORM_WINDOWS
+					if (BGFX_STATE_SRGBWRITE & changedFlags)
+					{
+						DX_CHECK(device->SetRenderState(D3DRS_SRGBWRITEENABLE, (newFlags&BGFX_STATE_SRGBWRITE) == BGFX_STATE_SRGBWRITE) );
+					}
+#endif // BX_PLATFORM_WINDOWS
+
+					if (BGFX_STATE_MSAA & changedFlags)
+					{
+						DX_CHECK(device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, (newFlags&BGFX_STATE_MSAA) == BGFX_STATE_MSAA) );
+					}
+
+					if ( (BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags)
+					{
+						uint32_t writeEnable = (newFlags&BGFX_STATE_ALPHA_WRITE) ? D3DCOLORWRITEENABLE_ALPHA : 0;
+ 						writeEnable |= (newFlags&BGFX_STATE_RGB_WRITE) ? D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE : 0;
+						DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, writeEnable) );
+					}
+
+					if (BGFX_STATE_BLEND_MASK & changedFlags)
+					{
+						bool alphaBlendEnabled = !!(BGFX_STATE_BLEND_MASK & newFlags);
+						DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlendEnabled) );
+//						DX_CHECK(device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, alphaBlendEnabled) );
+
+						if (alphaBlendEnabled)
+						{
+							uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
+							uint32_t src = blend&0xf;
+							uint32_t dst = (blend>>4)&0xf;
+
+ 							DX_CHECK(device->SetRenderState(D3DRS_SRCBLEND, s_blendFactor[src]) );
+							DX_CHECK(device->SetRenderState(D3DRS_DESTBLEND, s_blendFactor[dst]) );
+//							DX_CHECK(device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA) );
+//							DX_CHECK(device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA) );
+						}
+					}
+
+					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
+					primType = s_primType[primIndex];
+					primNumVerts = s_primNumVerts[primIndex];
+				}
+
+				bool materialChanged = false;
+				bool constantsChanged = state.m_constBegin < state.m_constEnd;
+				rendererUpdateUniforms(m_render->m_constantBuffer, state.m_constBegin, state.m_constEnd);
+
+				if (key.m_material != materialIdx)
+				{
+					materialIdx = key.m_material;
+
+					if (invalidHandle == materialIdx)
+					{
+						device->SetVertexShader(NULL);
+						device->SetPixelShader(NULL);
+					}
+					else
+					{
+						Material& material = s_renderCtx.m_materials[materialIdx];
+						device->SetVertexShader( (IDirect3DVertexShader9*)material.m_vsh->m_ptr);
+						device->SetPixelShader( (IDirect3DPixelShader9*)material.m_fsh->m_ptr);
+					}
+
+					materialChanged = 
+						constantsChanged = true;
+				}
+
+				if (invalidHandle != materialIdx)
+				{
+					Material& material = s_renderCtx.m_materials[materialIdx];
+
+					if (constantsChanged)
+					{
+						Material& material = s_renderCtx.m_materials[materialIdx];
+						material.m_vsh->m_constantBuffer->commit();
+						material.m_fsh->m_constantBuffer->commit();
+					}
+
+					for (uint32_t ii = 0, num = material.m_numPredefined; ii < num; ++ii)
+					{
+						PredefinedUniform& predefined = material.m_predefined[ii];
+						uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
+						switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
+						{
+						case PredefinedUniform::ViewRect:
+							{
+								float rect[4];
+								rect[0] = m_render->m_rect[view].m_x;
+								rect[1] = m_render->m_rect[view].m_y;
+								rect[2] = m_render->m_rect[view].m_width;
+								rect[3] = m_render->m_rect[view].m_height;
+
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, &rect[0], 1);
+							}
+							break;
+
+						case PredefinedUniform::ViewTexel:
+							{
+								float rect[4];
+								rect[0] = 1.0f/float(m_render->m_rect[view].m_width);
+								rect[1] = 1.0f/float(m_render->m_rect[view].m_height);
+
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, &rect[0], 1);
+							}
+							break;
+
+						case PredefinedUniform::View:
+							{
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, m_render->m_view[view].val, uint32_min(4, predefined.m_count) );
+							}
+							break;
+
+						case PredefinedUniform::ViewProj:
+							{
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, viewProj[view].val, uint32_min(4, predefined.m_count) );
+							}
+							break;
+
+						case PredefinedUniform::Model:
+							{
+ 								const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, model.val, uint32_min(state.m_num*4, predefined.m_count) );
+							}
+							break;
+
+						case PredefinedUniform::ModelViewProj:
+							{
+								Matrix4 modelViewProj;
+								const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
+								matrix_mul(modelViewProj.val, model.val, viewProj[view].val);
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, modelViewProj.val, uint32_min(4, predefined.m_count) );
+							}
+							break;
+
+						case PredefinedUniform::ModelViewProjX:
+							{
+								const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
+
+								static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
+								{
+									0.5f, 0.0f, 0.0f, 0.0f,
+									0.0f, 0.5f, 0.0f, 0.0f,
+									0.0f, 0.0f, 0.5f, 0.0f,
+									0.5f, 0.5f, 0.5f, 1.0f,
+								};
+
+								uint8_t other = m_render->m_other[view];
+								Matrix4 viewProjBias;
+								matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
+
+								Matrix4 modelViewProj;
+								matrix_mul(modelViewProj.val, model.val, viewProjBias.val);
+
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, modelViewProj.val, uint32_min(4, predefined.m_count) );
+							}
+							break;
+
+						case PredefinedUniform::ViewProjX:
+							{
+								static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
+								{
+									0.5f, 0.0f, 0.0f, 0.0f,
+									0.0f, 0.5f, 0.0f, 0.0f,
+									0.0f, 0.0f, 0.5f, 0.0f,
+									0.5f, 0.5f, 0.5f, 1.0f,
+								};
+
+								uint8_t other = m_render->m_other[view];
+								Matrix4 viewProjBias;
+								matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
+
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, viewProjBias.val, uint32_min(4, predefined.m_count) );
+							}
+							break;
+
+						case PredefinedUniform::AlphaRef:
+							{
+								s_renderCtx.setShaderConstantF(flags, predefined.m_loc, &alphaRef, 1);
+							}
+							break;
+
+						default:
+							BX_CHECK(false, "predefined %d not handled", predefined.m_type);
+							break;
+						}
+					}
+				}
+
+//				if (BGFX_STATE_TEX_MASK & changedFlags)
+				{
+					uint64_t flag = BGFX_STATE_TEX0;
+					for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
+					{
+						const Sampler& sampler = state.m_sampler[stage];
+						Sampler& current = currentState.m_sampler[stage];
+						if (current.m_idx != sampler.m_idx
+						||  current.m_flags != sampler.m_flags
+						||  materialChanged)
+						{
+							if (invalidHandle != sampler.m_idx)
+							{
+								switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
+								{
+								case BGFX_SAMPLER_TEXTURE:
+									s_renderCtx.m_textures[sampler.m_idx].commit(stage);
+									break;
+
+								case BGFX_SAMPLER_RENDERTARGET_COLOR:
+									s_renderCtx.m_renderTargets[sampler.m_idx].commit(stage);
+									break;
+
+								case BGFX_SAMPLER_RENDERTARGET_DEPTH:
+//									id = s_renderCtx.m_renderTargets[sampler.m_idx].m_depth.m_id;
+									break;
+								}
+							}
+							else
+							{
+								DX_CHECK(device->SetTexture(stage, NULL) );
+							}
+						}
+
+						current = sampler;
+						flag <<= 1;
+					}
+				}
+
+				if (currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx || materialChanged)
+				{
+					currentState.m_vertexBuffer = state.m_vertexBuffer;
+
+					uint16_t handle = state.m_vertexBuffer.idx;
+					if (invalidHandle != handle)
+					{
+						const VertexBuffer& vb = s_renderCtx.m_vertexBuffers[handle];
+
+						uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
+						const VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[decl];
+						DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) );
+
+						if (invalidHandle != state.m_instanceDataBuffer.idx
+						&&  s_renderCtx.m_instancing)
+						{
+							const VertexBuffer& inst = s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx];
+							DX_CHECK(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA|state.m_numInstances) );
+							DX_CHECK(device->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA|1) );
+							DX_CHECK(device->SetStreamSource(1, inst.m_ptr, state.m_instanceDataOffset, state.m_instanceDataStride) );
+
+							IDirect3DVertexDeclaration9* ptr = createVertexDecl(vertexDecl.m_decl, state.m_instanceDataStride/16);
+							DX_CHECK(device->SetVertexDeclaration(ptr) );
+							DX_RELEASE(ptr, 0);
+						}
+						else
+						{
+							DX_CHECK(device->SetStreamSourceFreq(0, 1) );
+							DX_CHECK(device->SetStreamSource(1, NULL, 0, 0) );
+							DX_CHECK(device->SetVertexDeclaration(vertexDecl.m_ptr) );
+						}
+					}
+					else
+					{
+						DX_CHECK(device->SetStreamSource(0, NULL, 0, 0) );
+						DX_CHECK(device->SetStreamSource(1, NULL, 0, 0) );
+					}
+				}
+
+				if (currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
+				{
+					currentState.m_indexBuffer = state.m_indexBuffer;
+
+					uint16_t handle = state.m_indexBuffer.idx;
+					if (invalidHandle != handle)
+					{
+						IndexBuffer& ib = s_renderCtx.m_indexBuffers[handle];
+						DX_CHECK(device->SetIndices(ib.m_ptr) );
+					}
+					else
+					{
+						DX_CHECK(device->SetIndices(NULL) );
+					}
+				}
+
+				if (invalidHandle != currentState.m_vertexBuffer.idx)
+				{
+					uint32_t numVertices = state.m_numVertices;
+					if (UINT32_C(0xffffffff) == numVertices)
+					{
+						VertexBuffer& vb = s_renderCtx.m_vertexBuffers[currentState.m_vertexBuffer.idx];
+						uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
+						VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[decl];
+						numVertices = vb.m_size/vertexDecl.m_decl.m_stride;
+					}
+
+					uint32_t numIndices = 0;
+					uint32_t numPrimsSubmitted = 0;
+					uint32_t numInstances = 0;
+					uint32_t numPrimsRendered = 0;
+
+					if (invalidHandle != state.m_indexBuffer.idx)
+					{
+						if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
+						{
+							numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
+							numPrimsSubmitted = numIndices/primNumVerts;
+							numInstances = state.m_numInstances;
+							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
+
+							DX_CHECK(device->DrawIndexedPrimitive(primType
+								, state.m_startVertex
+								, 0
+								, numVertices
+								, 0
+								, numPrimsSubmitted
+								) );
+						}
+						else if (primNumVerts <= state.m_numIndices)
+						{
+							numIndices = state.m_numIndices;
+							numPrimsSubmitted = numIndices/primNumVerts;
+							numInstances = state.m_numInstances;
+							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
+
+							DX_CHECK(device->DrawIndexedPrimitive(primType
+								, state.m_startVertex
+								, 0
+								, numVertices
+								, state.m_startIndex
+								, numPrimsSubmitted
+								) );
+						}
+					}
+					else
+					{
+						numPrimsSubmitted = numVertices/primNumVerts;
+						numInstances = state.m_numInstances;
+						numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
+						DX_CHECK(device->DrawPrimitive(primType
+							, state.m_startVertex
+							, numPrimsSubmitted
+							) );
+					}
+
+					statsNumPrimsSubmitted += numPrimsSubmitted;
+					statsNumIndices += numIndices;
+					statsNumInstances += numInstances;
+					statsNumPrimsRendered += numPrimsRendered;
+				}
+			}
+
+			PIX_ENDEVENT();
+		}
+
+		int64_t now = bx::getHPCounter();
+		elapsed += now;
+
+		static int64_t last = now;
+		int64_t frameTime = now - last;
+		last = now;
+
+		static int64_t min = frameTime;
+		static int64_t max = frameTime;
+		min = min > frameTime ? frameTime : min;
+		max = max < frameTime ? frameTime : max;
+
+		if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
+		{
+			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugstats");
+
+			TextVideoMem& tvm = s_renderCtx.m_textVideoMem;
+
+			static int64_t next = now;
+
+			if (now >= next)
+			{
+				next = now + bx::getHPFrequency();
+
+				double freq = double(bx::getHPFrequency() );
+				double toMs = 1000.0/freq;
+				double elapsedCpuMs = double(elapsed)*toMs;
+
+				tvm.clear();
+				uint16_t pos = 10;
+				tvm.printf(0, 0, 0x8f, " " BGFX_RENDERER_NAME " ");
+				tvm.printf(10, pos++, 0x8e, "      Frame: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
+					, double(frameTime)*toMs
+					, double(min)*toMs
+					, double(max)*toMs
+					, freq/frameTime
+					);
+				tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms]"
+					, m_render->m_num
+					, elapsedCpuMs
+					);
+				tvm.printf(10, pos++, 0x8e, "      Prims: %7d (#inst: %5d), submitted: %7d"
+					, statsNumPrimsRendered
+					, statsNumInstances
+					, statsNumPrimsSubmitted
+					);
+				tvm.printf(10, pos++, 0x8e, "    Indices: %7d", statsNumIndices);
+				tvm.printf(10, pos++, 0x8e, "   DVB size: %7d", m_render->m_vboffset);
+				tvm.printf(10, pos++, 0x8e, "   DIB size: %7d", m_render->m_iboffset);
+
+				uint8_t attr[2] = { 0x89, 0x8a };
+				uint8_t attrIndex = m_render->m_waitSubmit < m_render->m_waitRender;
+
+				tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", m_render->m_waitSubmit*toMs);
+				tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", m_render->m_waitRender*toMs);
+
+				min = frameTime;
+				max = frameTime;
+			}
+
+			m_textVideoMemBlitter.blit(tvm);
+
+			PIX_ENDEVENT();
+		}
+		else if (m_render->m_debug & BGFX_DEBUG_TEXT)
+		{
+			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugtext");
+
+			m_textVideoMemBlitter.blit(m_render->m_textVideoMem);
+
+			PIX_ENDEVENT();
+		}
+
+		device->EndScene();
+	}
+}
+
+#endif // BGFX_CONFIG_RENDERER_DIRECT3D9

+ 2 - 2
src/renderer_d3d9.h

@@ -36,8 +36,8 @@ typedef BOOL (WINAPI *D3DPERF_QueryRepeatFrameFunc)();
 typedef void (WINAPI *D3DPERF_SetOptionsFunc)(DWORD dwOptions);
 typedef DWORD (WINAPI *D3DPERF_GetStatusFunc)();
 
-#	define _PIX_SETMARKER(_col, _name) s_renderCtx.m_D3DPERF_SetMarker(_col, KeyL#_name)
-#	define _PIX_BEGINEVENT(_col, _name) s_renderCtx.m_D3DPERF_BeginEvent(_col, KeyL#_name)
+#	define _PIX_SETMARKER(_col, _name) s_renderCtx.m_D3DPERF_SetMarker(_col, L#_name)
+#	define _PIX_BEGINEVENT(_col, _name) s_renderCtx.m_D3DPERF_BeginEvent(_col, L#_name)
 #	define _PIX_ENDEVENT() s_renderCtx.m_D3DPERF_EndEvent()
 
 #elif BX_PLATFORM_XBOX360

+ 14 - 1
src/renderer_gl.cpp

@@ -2469,6 +2469,11 @@ namespace bgfx
 		int64_t frameTime = now - last;
 		last = now;
 
+		static int64_t min = frameTime;
+		static int64_t max = frameTime;
+		min = min > frameTime ? frameTime : min;
+		max = max < frameTime ? frameTime : max;
+
 		if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
 		{
 			double elapsedGpuMs = 0.0;
@@ -2492,7 +2497,12 @@ namespace bgfx
 				tvm.clear();
 				uint16_t pos = 10;
 				tvm.printf(0, 0, 0x8f, " " BGFX_RENDERER_NAME " ");
-				tvm.printf(10, pos++, 0x8e, "  Frame CPU: %3.4f [ms] / %3.2f", double(frameTime)*toMs, freq/frameTime);
+				tvm.printf(10, pos++, 0x8e, "  Frame CPU: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
+					, double(frameTime)*toMs
+					, double(min)*toMs
+					, double(max)*toMs
+					, freq/frameTime
+					);
 				tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms] %c GPU %3.4f [ms]"
 					, m_render->m_num
 					, elapsedCpuMs
@@ -2557,6 +2567,9 @@ namespace bgfx
 				pos++;
 				tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", double(m_render->m_waitSubmit)*toMs);
 				tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", double(m_render->m_waitRender)*toMs);
+
+				min = frameTime;
+				max = frameTime;
 			}
 
 			m_textVideoMemBlitter.blit(tvm);

+ 37 - 36
src/vs_clear_dx11.bin.h

@@ -1,43 +1,44 @@
-static const uint8_t vs_clear_dx11[635] =
+static const uint8_t vs_clear_dx11[653] =
 {
-	0x00, 0x00, 0x00, 0x00, 0x74, 0x02, 0x44, 0x58, 0x42, 0x43, 0x9f, 0x90, 0x55, 0x9a, 0x15, 0xd7, // ....t.DXBC..U...
-	0x4d, 0x46, 0x12, 0x19, 0x32, 0x30, 0xa7, 0xfd, 0x7a, 0x83, 0x01, 0x00, 0x00, 0x00, 0x74, 0x02, // MF..20..z.....t.
-	0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xfc, 0x00, // ......4.........
-	0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x00, // ..P.......RDEFp.
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, // ..............<.
-	0x00, 0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x52, 0x44, // ..........<...RD
-	0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, // 11<....... ...(.
-	0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, // ..$...........Mi
-	0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, // crosoft (R) HLSL
-	0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, //  Shader Compiler
-	0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, //  9.29.952.3111..
-	0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, // ..ISGNH.........
-	0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..8.............
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........A.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, // ................
-	0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, // ..POSITION.COLOR
-	0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, // ..OSGNL.........
-	0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, // ..8.............
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........D.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, // ................
-	0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, // ..SV_POSITION.CO
-	0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x80, 0x00, 0x00, 0x00, 0x50, 0x00, // LOR...SHEX....P.
-	0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, // .. ...j..._...r.
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, // ......_.........
-	0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // ..g.... ........
-	0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, // ..e.... ......6.
-	0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, 0x00, 0x00, // ..r ......F.....
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, // ..6.... .......@
-	0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, // .....?6.... ....
-	0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, // ..F.......>...ST
-	0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // AT..............
-	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, // ................
+	0x02, 0x00, 0x08, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x05, 0x43, 0x4f, 0x4c, // ...POSITION..COL
+	0x4f, 0x52, 0x00, 0x00, 0x00, 0x00, 0x74, 0x02, 0x44, 0x58, 0x42, 0x43, 0x9f, 0x90, 0x55, 0x9a, // OR....t.DXBC..U.
+	0x15, 0xd7, 0x4d, 0x46, 0x12, 0x19, 0x32, 0x30, 0xa7, 0xfd, 0x7a, 0x83, 0x01, 0x00, 0x00, 0x00, // ..MF..20..z.....
+	0x74, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, // t.......4.......
+	0xfc, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, // ....P.......RDEF
+	0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // p...............
+	0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, // <...........<...
+	0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, // RD11<....... ...
+	0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (...$...........
+	0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, // Microsoft (R) HL
+	0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, // SL Shader Compil
+	0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, // er 9.29.952.3111
+	0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // ....ISGNH.......
+	0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....8...........
+	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, // ............A...
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ................
+	0x0f, 0x0f, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, // ....POSITION.COL
+	0x4f, 0x52, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // OR..OSGNL.......
+	0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ....8...........
+	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, // ............D...
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ................
+	0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, // ....SV_POSITION.
+	0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x80, 0x00, 0x00, 0x00, // COLOR...SHEX....
+	0x50, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5f, 0x00, 0x00, 0x03, // P... ...j..._...
+	0x72, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, // r......._.......
+	0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....g.... ......
+	0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ....e.... ......
+	0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, // 6...r ......F...
+	0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....6.... ......
+	0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, // .@.....?6.... ..
+	0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, // ....F.......>...
+	0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // STAT............
+	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, 0x03, 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, 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,                   // .............
 };

+ 173 - 171
src/vs_debugfont_dx11.bin.h

@@ -1,179 +1,181 @@
-static const uint8_t vs_debugfont_dx11[2809] =
+static const uint8_t vs_debugfont_dx11[2844] =
 {
-	0x01, 0x00, 0xc0, 0x0a, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, // .....u_modelView
-	0x50, 0x72, 0x6f, 0x6a, 0x09, 0x00, 0x00, 0x0a, 0x40, 0x00, 0xdc, 0x0a, 0x44, 0x58, 0x42, 0x43, // [email protected]
-	0x49, 0xc3, 0x37, 0x49, 0xa7, 0x55, 0xe6, 0x4d, 0x05, 0x66, 0x2d, 0x74, 0x33, 0xa1, 0xec, 0xf1, // I.7I.U.M.f-t3...
-	0x01, 0x00, 0x00, 0x00, 0xdc, 0x0a, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, // ............4...
-	0xcc, 0x07, 0x00, 0x00, 0x54, 0x08, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x40, 0x0a, 0x00, 0x00, // ....T.......@...
-	0x52, 0x44, 0x45, 0x46, 0x90, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, // RDEF........h...
-	0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, // ....<...........
-	0x5d, 0x07, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, // ]...RD11<.......
-	0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, //  ...(...$.......
-	0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, // ....$Globals....
-	0x5c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x0a, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x18, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ................
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x31, 0x05, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1...............
-	0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x05, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // ........=.......
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x44, 0x05, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // D...............
-	0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x05, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, // ........O.......
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........`.......
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x84, 0x05, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .... ...........
-	0x98, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x05, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, // ............0...
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xf4, 0x05, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....@...........
-	0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, // ............P...
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x10, 0x06, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....`...........
-	0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, // ............p...
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x2e, 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x06, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, // ........>.......
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x49, 0x06, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // I...............
-	0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x53, 0x06, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, // ........S.......
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x5e, 0x06, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^...............
-	0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x06, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, // ........j.......
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x78, 0x06, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // x...............
-	0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x85, 0x06, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, // ................
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x93, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........@.......
-	0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x06, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, // ............@...
-	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xf8, 0x06, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x24, 0x07, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x00, // ........$.......
-	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // @...............
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x30, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // 0.......@.......
-	0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0x00, 0x00, 0x40, 0x0a, 0x00, 0x00, // ........@...@...
-	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // @...............
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0x51, 0x07, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Q.......@.......
-	0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // ................
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x52, // ........u_alphaR
-	0x65, 0x66, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x00, 0xab, 0xab, 0xab, 0x00, 0x00, 0x03, 0x00, // ef.float........
-	0x01, 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, 0xeb, 0x04, 0x00, 0x00, // ................
-	0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x75, 0x5f, 0x72, 0x67, 0x62, 0x64, 0x69, 0x73, 0x70, // u_time.u_rgbdisp
-	0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x75, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, // lacement.u_inter
-	0x6c, 0x61, 0x63, 0x65, 0x00, 0x75, 0x5f, 0x7a, 0x6f, 0x6f, 0x6d, 0x00, 0x75, 0x5f, 0x73, 0x74, // lace.u_zoom.u_st
-	0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x00, 0x75, 0x5f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x00, // rength.u_center.
-	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, // float2..........
+	0x04, 0x00, 0x08, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x05, 0x43, 0x4f, 0x4c, // ...POSITION..COL
+	0x4f, 0x52, 0x01, 0x05, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x08, 0x54, 0x45, 0x58, 0x43, 0x4f, // OR..COLOR..TEXCO
+	0x4f, 0x52, 0x44, 0x01, 0x00, 0xc0, 0x0a, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, // ORD.....u_modelV
+	0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x09, 0x00, 0x00, 0x0a, 0x40, 0x00, 0xdc, 0x0a, 0x44, // [email protected]
+	0x58, 0x42, 0x43, 0x49, 0xc3, 0x37, 0x49, 0xa7, 0x55, 0xe6, 0x4d, 0x05, 0x66, 0x2d, 0x74, 0x33, // XBCI.7I.U.M.f-t3
+	0xa1, 0xec, 0xf1, 0x01, 0x00, 0x00, 0x00, 0xdc, 0x0a, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, // ...............4
+	0x00, 0x00, 0x00, 0xcc, 0x07, 0x00, 0x00, 0x54, 0x08, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x40, // .......T.......@
+	0x0a, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x90, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, // ...RDEF........h
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, // .......<........
+	0x91, 0x00, 0x00, 0x5d, 0x07, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, // ...]...RD11<....
+	0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, // ... ...(...$....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, // .......$Globals.
+	0xab, 0xab, 0xab, 0x5c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, // ................
+	0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x18, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x05, 0x00, 0x00, 0x08, // ................
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x31, 0x05, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, // ...1............
+	0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x05, 0x00, 0x00, 0x10, // ...........=....
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x44, 0x05, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, // ...D............
+	0x00, 0x00, 0x00, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x05, 0x00, 0x00, 0x18, // ...........O....
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x05, 0x00, 0x00, 0x00, // ...........`....
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x84, 0x05, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, // ....... ........
+	0x00, 0x00, 0x00, 0x98, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x05, 0x00, 0x00, 0x30, // ...............0
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xf4, 0x05, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // .......@........
+	0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x50, // ...............P
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // .......`........
+	0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x06, 0x00, 0x00, 0x70, // ...............p
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x2e, 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x06, 0x00, 0x00, 0x90, // ...........>....
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x49, 0x06, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // ...I............
+	0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x53, 0x06, 0x00, 0x00, 0xb0, // ...........S....
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x5e, 0x06, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // ...^............
+	0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x06, 0x00, 0x00, 0xd0, // ...........j....
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x78, 0x06, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // ...x............
+	0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x85, 0x06, 0x00, 0x00, 0xf0, // ................
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x93, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, // ...........@....
+	0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x06, 0x00, 0x00, 0x40, // ...............@
+	0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x06, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xf8, 0x06, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x24, 0x07, 0x00, 0x00, 0xc0, // ...........$....
+	0x09, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, // ...@............
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, // ...0.......@....
+	0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0x00, 0x00, 0x40, // ...........@...@
+	0x0a, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, // ...@............
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0x51, 0x07, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, // ...Q.......@....
+	0x00, 0x00, 0x00, 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x61, 0x6c, 0x70, // ...........u_alp
+	0x68, 0x61, 0x52, 0x65, 0x66, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x00, 0xab, 0xab, 0xab, 0x00, // haRef.float.....
+	0x00, 0x03, 0x00, 0x01, 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, 0xeb, // ................
+	0x04, 0x00, 0x00, 0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x75, 0x5f, 0x72, 0x67, 0x62, 0x64, // ...u_time.u_rgbd
+	0x69, 0x73, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x75, 0x5f, 0x69, 0x6e, // isplacement.u_in
+	0x74, 0x65, 0x72, 0x6c, 0x61, 0x63, 0x65, 0x00, 0x75, 0x5f, 0x7a, 0x6f, 0x6f, 0x6d, 0x00, 0x75, // terlace.u_zoom.u
+	0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x00, 0x75, 0x5f, 0x63, 0x65, 0x6e, 0x74, // _strength.u_cent
+	0x65, 0x72, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, // er.float2.......
+	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, 0x58, 0x05, 0x00, 0x00, 0x75, // ...........X...u
+	0x5f, 0x6d, 0x65, 0x73, 0x68, 0x54, 0x69, 0x6c, 0x65, 0x55, 0x56, 0x00, 0x66, 0x6c, 0x6f, 0x61, // _meshTileUV.floa
+	0x74, 0x33, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // t3..............
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x05, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x65, // ........X...u_me
-	0x73, 0x68, 0x54, 0x69, 0x6c, 0x65, 0x55, 0x56, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x00, // shTileUV.float3.
-	0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x91, 0x05, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x61, 0x74, 0x44, 0x69, 0x66, 0x66, // .......u_matDiff
+	0x75, 0x73, 0x65, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, // use.float4......
+	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, 0xc9, 0x05, 0x00, 0x00, 0x75, // ...............u
+	0x5f, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, // _highlightColor.
+	0x75, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x44, 0x69, 0x72, 0x00, 0x75, 0x5f, 0x6c, 0x69, 0x67, // u_lightDir.u_lig
+	0x68, 0x74, 0x41, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x75, 0x5f, 0x6c, 0x69, 0x67, 0x68, // htAmbient.u_ligh
+	0x74, 0x44, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, 0x00, 0x75, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, // tDiffuse.u_light
+	0x53, 0x70, 0x65, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x00, 0x75, 0x5f, 0x66, 0x6f, 0x67, 0x43, 0x6f, // Specular.u_fogCo
+	0x6c, 0x6f, 0x72, 0x00, 0x75, 0x5f, 0x66, 0x6f, 0x67, 0x41, 0x72, 0x67, 0x73, 0x00, 0x75, 0x5f, // lor.u_fogArgs.u_
+	0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x63, 0x74, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x54, // viewRect.u_viewT
+	0x65, 0x78, 0x65, 0x6c, 0x00, 0x75, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x43, 0x6f, 0x6c, // exel.u_shadowCol
+	0x6f, 0x72, 0x00, 0x75, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x72, 0x67, 0x73, 0x00, // or.u_filterArgs.
+	0x75, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x6f, 0x75, 0x72, 0x41, 0x72, 0x67, 0x73, 0x00, 0x75, 0x5f, // u_contourArgs.u_
+	0x76, 0x69, 0x65, 0x77, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x00, 0xab, 0x03, // view.float4x4...
+	0x00, 0x03, 0x00, 0x04, 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, 0x9a, // ................
+	0x06, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0x03, // ...u_viewProj...
+	0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 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, 0x9a, // ................
+	0x06, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, // ...u_model......
+	0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ... ............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x75, // ...............u
+	0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // _modelView.u_mod
+	0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // elViewProj.u_mod
+	0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x75, 0x5f, 0x76, 0x69, // elViewProjX.u_vi
+	0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, // ewProjX.Microsof
+	0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, // t (R) HLSL Shade
+	0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, // r Compiler 9.29.
+	0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x80, // 952.3111...ISGN.
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, // ...........h....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, // ................
+	0x07, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...q............
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, // ...........q....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, // ................
+	0x0f, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...w............
+	0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, // ...........POSIT
+	0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, // ION.COLOR.TEXCOO
+	0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x84, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, // RD.OSGN.........
+	0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, // ...h............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, // ...........t....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, // ................
+	0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...t............
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, // ...........z....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, // ................
+	0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, // ...SV_POSITION.C
+	0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x53, // OLOR.TEXCOORD..S
+	0x48, 0x45, 0x58, 0x58, 0x01, 0x00, 0x00, 0x50, 0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x6a, // HEXX...P...V...j
+	0x08, 0x00, 0x01, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, // ...Y...F. ......
+	0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, // ..._...r......._
+	0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, // ..........._....
+	0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, // ......._...2....
+	0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ...g.... .......
+	0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, // ...e.... ......e
+	0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x32, // .... ......e...2
+	0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x38, //  ......h.......8
+	0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, // ...........V....
+	0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x32, // ...F. .........2
+	0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // ...........F. ..
+	0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, // ...............F
+	0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, // .......2........
+	0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xa6, // ...F. ..........
+	0x1a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .......F........
+	0x00, 0x00, 0x08, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, // .... ......F....
+	0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x36, // ...F. .........6
+	0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, // .... ......F....
+	0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, // ...6.... ......F
+	0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x03, // .......6...2 ...
+	0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, // ...F.......>...S
+	0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // TAT.............
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 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, // ................
-	0x91, 0x05, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x61, 0x74, 0x44, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, // ....u_matDiffuse
-	0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, // .float4.........
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x05, 0x00, 0x00, 0x75, 0x5f, 0x68, 0x69, // ............u_hi
-	0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x75, 0x5f, 0x6c, // ghlightColor.u_l
-	0x69, 0x67, 0x68, 0x74, 0x44, 0x69, 0x72, 0x00, 0x75, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x41, // ightDir.u_lightA
-	0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x75, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x44, 0x69, // mbient.u_lightDi
-	0x66, 0x66, 0x75, 0x73, 0x65, 0x00, 0x75, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x70, 0x65, // ffuse.u_lightSpe
-	0x63, 0x75, 0x6c, 0x61, 0x72, 0x00, 0x75, 0x5f, 0x66, 0x6f, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // cular.u_fogColor
-	0x00, 0x75, 0x5f, 0x66, 0x6f, 0x67, 0x41, 0x72, 0x67, 0x73, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, // .u_fogArgs.u_vie
-	0x77, 0x52, 0x65, 0x63, 0x74, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x54, 0x65, 0x78, 0x65, // wRect.u_viewTexe
-	0x6c, 0x00, 0x75, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, // l.u_shadowColor.
-	0x75, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x72, 0x67, 0x73, 0x00, 0x75, 0x5f, 0x63, // u_filterArgs.u_c
-	0x6f, 0x6e, 0x74, 0x6f, 0x75, 0x72, 0x41, 0x72, 0x67, 0x73, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, // ontourArgs.u_vie
-	0x77, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x00, 0xab, 0x03, 0x00, 0x03, 0x00, // w.float4x4......
-	0x04, 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, 0x9a, 0x06, 0x00, 0x00, // ................
-	0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0x03, 0x00, 0x03, 0x00, // u_viewProj......
-	0x04, 0x00, 0x04, 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, 0x9a, 0x06, 0x00, 0x00, // ................
-	0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, // u_model.........
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  ...............
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x6f, // ............u_mo
-	0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, // delView.u_modelV
-	0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, // iewProj.u_modelV
-	0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, // iewProjX.u_viewP
-	0x72, 0x6f, 0x6a, 0x58, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, // rojX.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, 0x49, 0x53, 0x47, 0x4e, 0x80, 0x00, 0x00, 0x00, // .3111...ISGN....
-	0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........h.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, // ................
-	0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // q...............
-	0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ........q.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, // ................
-	0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // w...............
-	0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, // ........POSITION
-	0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, // .COLOR.TEXCOORD.
-	0x4f, 0x53, 0x47, 0x4e, 0x84, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // OSGN............
-	0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // h...............
-	0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........t.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, // ................
-	0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // t...............
-	0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........z.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, // ................
-	0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, // SV_POSITION.COLO
-	0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x45, 0x58, // R.TEXCOORD..SHEX
-	0x58, 0x01, 0x00, 0x00, 0x50, 0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, // X...P...V...j...
-	0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, // Y...F. .........
-	0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, // _...r......._...
-	0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, // ........_.......
-	0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, // ...._...2.......
-	0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // g.... ..........
-	0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, // e.... ......e...
-	0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, // . ......e...2 ..
-	0x03, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, // ....h.......8...
-	0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ........V.......
-	0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, // F. .........2...
-	0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // ........F. .....
-	0xa0, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, // ............F...
-	0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....2...........
-	0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xa6, 0x1a, 0x10, 0x00, // F. .............
-	0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, // ....F...........
-	0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // . ......F.......
-	0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, // F. .........6...
-	0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // . ......F.......
-	0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, // 6.... ......F...
-	0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, // ....6...2 ......
-	0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, // F.......>...STAT
-	0x94, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x08, 0x00, 0x00, 0x00, 0x02, 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, 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, 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, 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,                         // ............
 };

+ 71 - 11
tools/shaderc.cpp

@@ -14,8 +14,9 @@
 #include "glsl_optimizer.h"
 
 #define MAX_TAGS 256
-extern "C" {
-#	include <fpp.h>
+extern "C"
+{
+#include <fpp.h>
 } // extern "C"
 
 #if 1
@@ -48,6 +49,54 @@ long int fsize(FILE* _file)
 	return size;
 }
 
+struct Attrib
+{
+	enum Enum
+	{
+		Position = 0,
+		Normal,
+		Color0,
+		Color1,
+		Indices,
+		Weight,
+		TexCoord0,
+		TexCoord1,
+		TexCoord2,
+		TexCoord3,
+		TexCoord4,
+		TexCoord5,
+		TexCoord6,
+		TexCoord7,
+
+		Count,
+	};
+};
+
+struct RemapInputSemantic
+{
+	Attrib::Enum m_attr;
+	const char* m_name;
+	uint8_t m_index;
+};
+
+static const RemapInputSemantic s_remapInputSemantic[Attrib::Count] =
+{
+	{ Attrib::Position,  "POSITION",     0 },
+	{ Attrib::Normal,    "NORMAL",       0 },
+	{ Attrib::Color0,    "COLOR",        0 },
+	{ Attrib::Color1,    "COLOR",        1 },
+	{ Attrib::Indices,   "BLENDINDICES", 0 },
+	{ Attrib::Weight,    "BLENDWEIGHT",  0 },
+	{ Attrib::TexCoord0, "TEXCOORD",     0 },
+	{ Attrib::TexCoord1, "TEXCOORD",     1 },
+	{ Attrib::TexCoord2, "TEXCOORD",     2 },
+	{ Attrib::TexCoord3, "TEXCOORD",     3 },
+	{ Attrib::TexCoord4, "TEXCOORD",     4 },
+	{ Attrib::TexCoord5, "TEXCOORD",     5 },
+	{ Attrib::TexCoord6, "TEXCOORD",     6 },
+	{ Attrib::TexCoord7, "TEXCOORD",     7 },
+};
+
 struct ConstantType
 {
 	enum Enum
@@ -741,18 +790,31 @@ bool compileHLSLShaderDx11(CommandLine& _cmdLine, const std::string& _code, IStr
 
 	BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version);
 	BX_TRACE("Num constant buffers: %d", desc.ConstantBuffers);
-	BX_TRACE("#   cl ty RxC   S  By Name");
-
-// 	bx::HashMurmur2A hash;
-// 	hash.begin();
 
 	BX_TRACE("Input:");
-	for (uint32_t ii = 0; ii < desc.InputParameters; ++ii)
+	uint8_t numAttr = (uint8_t)desc.InputParameters;
+	_stream.write(numAttr);
+
+	for (uint32_t ii = 0; ii < numAttr; ++ii)
 	{
 		D3D11_SIGNATURE_PARAMETER_DESC spd;
 		reflect->GetInputParameterDesc(ii, &spd);
-		BX_TRACE("\t%2d: %s%d, %d, %d", ii, spd.SemanticName, spd.SemanticIndex, spd.SystemValueType, spd.ComponentType);
-//		hash.add(inputSignature->GetBufferPointer(), inputSignature->GetBufferSize() );
+		BX_TRACE("\t%2d: %s%d, %d, %d, %x, %d"
+			, ii
+			, spd.SemanticName
+			, spd.SemanticIndex
+			, spd.SystemValueType
+			, spd.ComponentType
+			, spd.Mask
+			, spd.Register
+			);
+
+		uint8_t semanticIndex = spd.SemanticIndex;
+		_stream.write(semanticIndex);
+
+		uint8_t len = (uint8_t)strlen(spd.SemanticName);
+		_stream.write(len);
+		_stream.write(spd.SemanticName);
 	}
 
 	BX_TRACE("Output:");
@@ -761,9 +823,7 @@ bool compileHLSLShaderDx11(CommandLine& _cmdLine, const std::string& _code, IStr
 		D3D11_SIGNATURE_PARAMETER_DESC spd;
 		reflect->GetOutputParameterDesc(ii, &spd);
 		BX_TRACE("\t%2d: %s%d, %d, %d", ii, spd.SemanticName, spd.SemanticIndex, spd.SystemValueType, spd.ComponentType);
-//		hash.add(inputSignature->GetBufferPointer(), inputSignature->GetBufferSize() );
 	}
-//	uint32_t inputSignatureHash = hash.end();
 
 	uint16_t size = 0;