From 45a85d438c8efd3bcd35069cbefed68d1e26f476 Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Sun, 5 Aug 2012 14:51:49 -0700 Subject: [PATCH] DX11 wip. --- src/bgfx_p.h | 6190 +++++++++++++++++------------------ src/fs_clear_dx11.bin.h | 61 +- src/fs_debugfont_dx11.bin.h | 107 +- src/renderer_d3d11.cpp | 317 +- src/renderer_d3d11.h | 16 +- src/renderer_d3d9.cpp | 4848 +++++++++++++-------------- src/renderer_d3d9.h | 4 +- src/renderer_gl.cpp | 15 +- src/vs_clear_dx11.bin.h | 73 +- src/vs_debugfont_dx11.bin.h | 344 +- tools/shaderc.cpp | 82 +- 11 files changed, 6141 insertions(+), 5916 deletions(-) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 29d84ef5..64f66a92 100644 --- a/src/bgfx_p.h +++ b/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 -#include // va_list -#include -#include -#include -#include - -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 -#include -#include -#include +/* + * 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 +#include // va_list +#include +#include +#include +#include + +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 +#include +#include +#include #include -#include -#include -#include -#include -#include - -#if BX_PLATFORM_WINDOWS -# include -extern HWND g_bgfxHwnd; -#elif BX_PLATFORM_XBOX360 -# include -# include -#elif BX_PLATFORM_POSIX -# include -#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 -# include -namespace stl = tinystl; -#else -namespace std { namespace tr1 {} using namespace tr1; } // namespace std -# include -# include -namespace stl = std; -#endif // BGFX_CONFIG_USE_TINYSTL -#include - -#include "config.h" - -#if BGFX_CONFIG_MULTITHREADED -# include -#endif // BGFX_CONFIG_MULTITHREADED - -#include -#include - -#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 +#include +#include +#include +#include + +#if BX_PLATFORM_WINDOWS +# include +extern HWND g_bgfxHwnd; +#elif BX_PLATFORM_XBOX360 +# include +# include +#elif BX_PLATFORM_POSIX +# include +#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 +# include +namespace stl = tinystl; +#else +namespace std { namespace tr1 {} using namespace tr1; } // namespace std +# include +# include +namespace stl = std; +#endif // BGFX_CONFIG_USE_TINYSTL +#include + +#include "config.h" + +#if BGFX_CONFIG_MULTITHREADED +# include +#endif // BGFX_CONFIG_MULTITHREADED + +#include +#include + +#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 - 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 - 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 - void write(const Type& _in) - { - write(reinterpret_cast(&_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 - void read(Type& _in) - { - read(reinterpret_cast(&_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 result = m_uniforms.insert(UniformHashMap::value_type(_name, info) ); - return result.first->second; - } - - return it->second; - } - - private: - typedef stl::unordered_map 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(_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(_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(_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 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 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 FreeList; - FreeList m_free; - - typedef stl::unordered_map 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(_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(_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 + 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 + 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 + void write(const Type& _in) + { + write(reinterpret_cast(&_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 + void read(Type& _in) + { + read(reinterpret_cast(&_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 result = m_uniforms.insert(UniformHashMap::value_type(_name, info) ); + return result.first->second; + } + + return it->second; + } + + private: + typedef stl::unordered_map 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(_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(_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(_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 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 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 FreeList; + FreeList m_free; + + typedef stl::unordered_map 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(_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(_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__ diff --git a/src/fs_clear_dx11.bin.h b/src/fs_clear_dx11.bin.h index e0710705..c9519342 100644 --- a/src/fs_clear_dx11.bin.h +++ b/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, // ........... }; diff --git a/src/fs_debugfont_dx11.bin.h b/src/fs_debugfont_dx11.bin.h index b4ba412a..1006ef19 100644 --- a/src/fs_debugfont_dx11.bin.h +++ b/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, // ..... }; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 17f83613..3cfcc77d 100644 --- a/src/renderer_d3d11.cpp +++ b/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; - - 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; + m_scd.BufferDesc.Width = _resolution.m_width; + m_scd.BufferDesc.Height = _resolution.m_height; preReset(); - DX_CHECK(m_device->Reset(&m_params) ); + + 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 + ) ); + 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); diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index 5df36123..c85b4d56 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -9,8 +9,6 @@ #include #include "renderer_d3d.h" -typedef HRESULT (WINAPI *CreateDXGIFactoryFn)(REFIID, void**); - namespace bgfx { template @@ -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; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index a2bd4321..0f0dc678 100644 --- a/src/renderer_d3d9.cpp +++ b/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 diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index 46edb5a9..48b15f3c 100644 --- a/src/renderer_d3d9.h +++ b/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 diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 638e0d62..b3624ea0 100644 --- a/src/renderer_gl.cpp +++ b/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); diff --git a/src/vs_clear_dx11.bin.h b/src/vs_clear_dx11.bin.h index cc44e039..e36846f3 100644 --- a/src/vs_clear_dx11.bin.h +++ b/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, // ............. }; diff --git a/src/vs_debugfont_dx11.bin.h b/src/vs_debugfont_dx11.bin.h index f79b8e74..48ad8039 100644 --- a/src/vs_debugfont_dx11.bin.h +++ b/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, // Proj....@...DXBC - 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, // iewProj....@...D + 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, 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, 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, // ................ 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, 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, // ............ }; diff --git a/tools/shaderc.cpp b/tools/shaderc.cpp index 50b57a5b..5abdea67 100644 --- a/tools/shaderc.cpp +++ b/tools/shaderc.cpp @@ -14,8 +14,9 @@ #include "glsl_optimizer.h" #define MAX_TAGS 256 -extern "C" { -# include +extern "C" +{ +#include } // 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;