2012-06-29 20:10:10 -07:00
/*
2014-02-10 22:07:04 -08:00
* Copyright 2011 - 2014 Branimir Karadzic . All rights reserved .
2012-06-29 20:10:10 -07:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include "bgfx_p.h"
namespace bgfx
{
# define BGFX_MAIN_THREAD_MAGIC 0x78666762
2013-07-10 23:18:16 -07:00
# if BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
2013-10-10 18:29:57 -07:00
# define BGFX_CHECK_MAIN_THREAD() \
BX_CHECK ( NULL ! = s_ctx , " Library is not initialized yet. " ) ; \
BX_CHECK ( BGFX_MAIN_THREAD_MAGIC = = s_threadIndex , " Must be called from main thread. " )
2012-11-25 18:24:50 -08:00
# define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.")
2012-06-29 20:10:10 -07:00
# else
2012-11-25 18:24:50 -08:00
# define BGFX_CHECK_MAIN_THREAD()
# define BGFX_CHECK_RENDER_THREAD()
2013-07-10 23:18:16 -07:00
# endif // BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
2012-06-29 20:10:10 -07:00
2013-04-18 21:16:09 -07:00
# if BX_PLATFORM_ANDROID
: : ANativeWindow * g_bgfxAndroidWindow = NULL ;
2013-07-21 14:44:53 -07:00
void androidSetWindow ( : : ANativeWindow * _window )
2013-01-13 15:35:06 -08:00
{
2013-04-18 21:16:09 -07:00
g_bgfxAndroidWindow = _window ;
2013-01-13 15:35:06 -08:00
}
2013-07-21 14:44:53 -07:00
# elif BX_PLATFORM_IOS
void * g_bgfxEaglLayer = NULL ;
2013-07-21 15:38:44 -07:00
void iosSetEaglLayer ( void * _layer )
2013-07-21 14:44:53 -07:00
{
g_bgfxEaglLayer = _layer ;
}
2013-01-15 20:37:07 -08:00
# elif BX_PLATFORM_OSX
void * g_bgfxNSWindow = NULL ;
2014-01-08 22:08:37 -08:00
2013-04-18 23:32:12 -07:00
void osxSetNSWindow ( void * _window )
2013-01-15 20:37:07 -08:00
{
2013-04-18 23:32:12 -07:00
g_bgfxNSWindow = _window ;
2013-01-15 20:37:07 -08:00
}
2013-04-18 21:16:09 -07:00
# elif BX_PLATFORM_WINDOWS
: : HWND g_bgfxHwnd = NULL ;
2013-04-18 23:32:12 -07:00
void winSetHwnd ( : : HWND _window )
2013-04-18 21:16:09 -07:00
{
2013-04-18 23:32:12 -07:00
g_bgfxHwnd = _window ;
2013-04-18 21:16:09 -07:00
}
2013-01-15 20:37:07 -08:00
# endif // BX_PLATFORM_*
2013-01-13 10:47:30 -08:00
2013-09-29 21:33:50 -07:00
# if BGFX_CONFIG_USE_TINYSTL
2013-09-22 21:40:17 -07:00
void * TinyStlAllocator : : static_allocate ( size_t _bytes )
{
2013-09-22 22:38:31 -07:00
return BX_ALLOC ( g_allocator , _bytes ) ;
2013-09-22 21:40:17 -07:00
}
void TinyStlAllocator : : static_deallocate ( void * _ptr , size_t /*_bytes*/ )
{
2013-10-06 19:32:35 -07:00
if ( NULL ! = _ptr )
{
BX_FREE ( g_allocator , _ptr ) ;
}
2013-09-22 21:40:17 -07:00
}
2013-09-29 21:33:50 -07:00
# endif // BGFX_CONFIG_USE_TINYSTL
2013-09-22 21:40:17 -07:00
2012-12-30 20:52:47 -08:00
struct CallbackStub : public CallbackI
2012-06-29 20:10:10 -07:00
{
2012-12-30 20:52:47 -08:00
virtual ~ CallbackStub ( )
{
}
virtual void fatal ( Fatal : : Enum _code , const char * _str ) BX_OVERRIDE
{
2013-04-28 12:27:35 -07:00
if ( Fatal : : DebugCheck = = _code )
{
bx : : debugBreak ( ) ;
}
else
{
BX_TRACE ( " 0x%08x: %s " , _code , _str ) ;
BX_UNUSED ( _code , _str ) ;
abort ( ) ;
}
2012-12-30 20:52:47 -08:00
}
virtual uint32_t cacheReadSize ( uint64_t /*_id*/ ) BX_OVERRIDE
{
return 0 ;
}
virtual bool cacheRead ( uint64_t /*_id*/ , void * /*_data*/ , uint32_t /*_size*/ ) BX_OVERRIDE
{
return false ;
}
virtual void cacheWrite ( uint64_t /*_id*/ , const void * /*_data*/ , uint32_t /*_size*/ ) BX_OVERRIDE
{
}
2014-01-13 20:36:33 -08:00
virtual void screenShot ( const char * _filePath , uint32_t _width , uint32_t _height , uint32_t _pitch , const void * _data , uint32_t _size , bool _yflip ) BX_OVERRIDE
2012-12-30 20:52:47 -08:00
{
2014-01-13 20:36:33 -08:00
BX_UNUSED ( _filePath , _width , _height , _pitch , _data , _size , _yflip ) ;
2014-01-21 20:53:43 -08:00
# if BX_CONFIG_CRT_FILE_READER_WRITER
2014-01-13 20:36:33 -08:00
char * filePath = ( char * ) alloca ( strlen ( _filePath ) + 5 ) ;
strcpy ( filePath , _filePath ) ;
strcat ( filePath , " .tga " ) ;
bx : : CrtFileWriter writer ;
if ( 0 = = writer . open ( filePath ) )
{
imageWriteTga ( & writer , _width , _height , _pitch , _data , false , _yflip ) ;
writer . close ( ) ;
}
2014-01-21 20:53:43 -08:00
# endif // BX_CONFIG_CRT_FILE_READER_WRITER
2012-12-30 20:52:47 -08:00
}
2012-06-29 20:10:10 -07:00
2013-01-04 23:52:37 -08:00
virtual void captureBegin ( uint32_t /*_width*/ , uint32_t /*_height*/ , uint32_t /*_pitch*/ , TextureFormat : : Enum /*_format*/ , bool /*_yflip*/ ) BX_OVERRIDE
2012-12-30 20:52:47 -08:00
{
BX_TRACE ( " Warning: using capture without callback (a.k.a. pointless). " ) ;
}
virtual void captureEnd ( ) BX_OVERRIDE
{
}
virtual void captureFrame ( const void * /*_data*/ , uint32_t /*_size*/ ) BX_OVERRIDE
{
}
} ;
2012-06-29 20:10:10 -07:00
2014-03-16 18:16:08 -07:00
# ifndef BGFX_CONFIG_MEMORY_TRACKING
# define BGFX_CONFIG_MEMORY_TRACKING (BGFX_CONFIG_DEBUG && BX_CONFIG_SUPPORTED_THREADING)
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
class AllocatorStub : public bx : : ReallocatorI
{
public :
AllocatorStub ( )
2014-03-16 18:16:08 -07:00
# if BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
: m_numBlocks ( 0 )
, m_maxBlocks ( 0 )
2014-03-16 18:16:08 -07:00
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
{
}
2014-05-01 10:15:41 -07:00
virtual void * alloc ( size_t _size , size_t _align , const char * _file , uint32_t _line ) BX_OVERRIDE
2013-09-20 22:13:58 -07:00
{
2014-05-01 10:15:41 -07:00
if ( BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT > = _align )
2013-10-06 11:09:55 -07:00
{
2014-05-01 10:15:41 -07:00
# if BGFX_CONFIG_MEMORY_TRACKING
{
bx : : LwMutexScope scope ( m_mutex ) ;
+ + m_numBlocks ;
m_maxBlocks = bx : : uint32_max ( m_maxBlocks , m_numBlocks ) ;
}
2014-03-16 18:16:08 -07:00
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
2014-05-01 10:15:41 -07:00
return : : malloc ( _size ) ;
}
return bx : : alignedAlloc ( this , _size , _align , _file , _line ) ;
2013-09-20 22:13:58 -07:00
}
2014-05-01 10:15:41 -07:00
virtual void free ( void * _ptr , size_t _align , const char * _file , uint32_t _line ) BX_OVERRIDE
2013-09-20 22:13:58 -07:00
{
2013-09-22 21:40:17 -07:00
if ( NULL ! = _ptr )
{
2014-05-01 10:15:41 -07:00
if ( BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT > = _align )
2013-10-06 11:09:55 -07:00
{
2014-05-01 10:15:41 -07:00
# if BGFX_CONFIG_MEMORY_TRACKING
{
bx : : LwMutexScope scope ( m_mutex ) ;
BX_CHECK ( m_numBlocks > 0 , " Number of blocks is 0. Possible alloc/free mismatch? " ) ;
- - m_numBlocks ;
}
2014-03-16 18:16:08 -07:00
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
2014-05-01 10:15:41 -07:00
: : free ( _ptr ) ;
}
else
{
bx : : alignedFree ( this , _ptr , _align , _file , _line ) ;
}
2013-09-22 21:40:17 -07:00
}
2013-09-20 22:13:58 -07:00
}
2014-05-01 10:15:41 -07:00
virtual void * realloc ( void * _ptr , size_t _size , size_t _align , const char * _file , uint32_t _line ) BX_OVERRIDE
2013-09-20 22:13:58 -07:00
{
2014-05-01 10:15:41 -07:00
if ( BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT > = _align )
2013-09-20 22:13:58 -07:00
{
2014-05-01 10:15:41 -07:00
# if BGFX_CONFIG_MEMORY_TRACKING
if ( NULL = = _ptr )
{
bx : : LwMutexScope scope ( m_mutex ) ;
+ + m_numBlocks ;
m_maxBlocks = bx : : uint32_max ( m_maxBlocks , m_numBlocks ) ;
}
2014-03-16 18:16:08 -07:00
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
2014-05-01 10:15:41 -07:00
return : : realloc ( _ptr , _size ) ;
}
return bx : : alignedRealloc ( this , _ptr , _size , _align , _file , _line ) ;
2013-09-20 22:13:58 -07:00
}
2013-10-06 19:32:35 -07:00
void checkLeaks ( )
2013-09-20 22:13:58 -07:00
{
2014-03-16 18:16:08 -07:00
# if BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
BX_WARN ( 0 = = m_numBlocks , " MEMORY LEAK: %d (max: %d) " , m_numBlocks , m_maxBlocks ) ;
2014-03-16 18:16:08 -07:00
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
}
2013-10-06 19:32:35 -07:00
protected :
2014-03-16 18:16:08 -07:00
# if BGFX_CONFIG_MEMORY_TRACKING
2013-10-06 11:09:55 -07:00
bx : : LwMutex m_mutex ;
2013-09-20 22:13:58 -07:00
uint32_t m_numBlocks ;
uint32_t m_maxBlocks ;
2014-03-16 18:16:08 -07:00
# endif // BGFX_CONFIG_MEMORY_TRACKING
2013-09-20 22:13:58 -07:00
} ;
static CallbackStub * s_callbackStub = NULL ;
static AllocatorStub * s_allocatorStub = NULL ;
2013-10-18 22:34:23 -07:00
static bool s_graphicsDebuggerPresent = false ;
2013-09-20 22:13:58 -07:00
CallbackI * g_callback = NULL ;
bx : : ReallocatorI * g_allocator = NULL ;
2012-06-29 20:10:10 -07:00
2013-10-10 18:29:57 -07:00
Caps g_caps ;
2012-06-29 20:10:10 -07:00
static BX_THREAD uint32_t s_threadIndex = 0 ;
2013-09-30 20:09:09 -07:00
static Context * s_ctx = NULL ;
2014-01-19 22:34:58 -08:00
static bool s_renderFrameCalled = false ;
2013-09-30 20:09:09 -07:00
2013-10-18 22:34:23 -07:00
void setGraphicsDebuggerPresent ( bool _present )
{
BX_TRACE ( " Graphics debugger is %spresent. " , _present ? " " : " not " ) ;
s_graphicsDebuggerPresent = _present ;
}
bool isGraphicsDebuggerPresent ( )
{
return s_graphicsDebuggerPresent ;
}
2012-07-29 13:50:23 -07:00
void fatal ( Fatal : : Enum _code , const char * _format , . . . )
2012-06-29 20:10:10 -07:00
{
char temp [ 8192 ] ;
va_list argList ;
va_start ( argList , _format ) ;
2013-04-28 12:27:35 -07:00
bx : : vsnprintf ( temp , sizeof ( temp ) , _format , argList ) ;
2012-06-29 20:10:10 -07:00
va_end ( argList ) ;
temp [ sizeof ( temp ) - 1 ] = ' \0 ' ;
2012-12-30 20:52:47 -08:00
g_callback - > fatal ( _code , temp ) ;
2012-06-29 20:10:10 -07:00
}
2012-10-07 20:41:18 -07:00
void mtxOrtho ( float * _result , float _left , float _right , float _bottom , float _top , float _near , float _far )
2012-06-29 20:10:10 -07:00
{
const float aa = 2.0f / ( _right - _left ) ;
const float bb = 2.0f / ( _top - _bottom ) ;
const float cc = 1.0f / ( _far - _near ) ;
const float dd = ( _left + _right ) / ( _left - _right ) ;
const float ee = ( _top + _bottom ) / ( _bottom - _top ) ;
const float ff = _near / ( _near - _far ) ;
memset ( _result , 0 , sizeof ( float ) * 16 ) ;
_result [ 0 ] = aa ;
_result [ 5 ] = bb ;
_result [ 10 ] = cc ;
_result [ 12 ] = dd ;
_result [ 13 ] = ee ;
_result [ 14 ] = ff ;
_result [ 15 ] = 1.0f ;
}
# include "charset.h"
void charsetFillTexture ( const uint8_t * _charset , uint8_t * _rgba , uint32_t _height , uint32_t _pitch , uint32_t _bpp )
{
for ( uint32_t ii = 0 ; ii < 256 ; + + ii )
{
uint8_t * pix = & _rgba [ ii * 8 * _bpp ] ;
for ( uint32_t yy = 0 ; yy < _height ; + + yy )
{
for ( uint32_t xx = 0 ; xx < 8 ; + + xx )
{
uint8_t bit = 1 < < ( 7 - xx ) ;
memset ( & pix [ xx * _bpp ] , _charset [ ii * _height + yy ] & bit ? 255 : 0 , _bpp ) ;
}
pix + = _pitch ;
}
}
}
static const uint32_t numCharsPerBatch = 1024 ;
static const uint32_t numBatchVertices = numCharsPerBatch * 4 ;
static const uint32_t numBatchIndices = numCharsPerBatch * 6 ;
void TextVideoMemBlitter : : init ( )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-05-10 20:51:44 -07:00
m_decl
. begin ( )
. add ( Attrib : : Position , 3 , AttribType : : Float )
. add ( Attrib : : Color0 , 4 , AttribType : : Uint8 , true )
. add ( Attrib : : Color1 , 4 , AttribType : : Uint8 , true )
. add ( Attrib : : TexCoord0 , 2 , AttribType : : Float )
. end ( ) ;
2012-06-29 20:10:10 -07:00
uint16_t width = 2048 ;
uint16_t height = 24 ;
uint8_t bpp = 1 ;
uint32_t pitch = width * bpp ;
2012-07-29 13:50:23 -07:00
const Memory * mem ;
2012-06-29 20:10:10 -07:00
2012-08-12 21:02:11 -07:00
mem = alloc ( pitch * height ) ;
uint8_t * rgba = mem - > data ;
2012-06-29 20:10:10 -07:00
charsetFillTexture ( vga8x8 , rgba , 8 , pitch , bpp ) ;
charsetFillTexture ( vga8x16 , & rgba [ 8 * pitch ] , 16 , pitch , bpp ) ;
2014-03-25 23:07:51 -07:00
m_texture = createTexture2D ( width , height , 1 , TextureFormat : : R8
2012-10-22 19:39:59 -07:00
, BGFX_TEXTURE_MIN_POINT
| BGFX_TEXTURE_MAG_POINT
| BGFX_TEXTURE_MIP_POINT
| BGFX_TEXTURE_U_CLAMP
| BGFX_TEXTURE_V_CLAMP
, mem
) ;
2012-06-29 20:10:10 -07:00
2014-05-26 14:09:26 -07:00
switch ( g_caps . rendererType )
2014-03-31 20:08:32 -07:00
{
2014-05-26 14:09:26 -07:00
case RendererType : : Direct3D9 :
2014-03-31 20:08:32 -07:00
mem = makeRef ( vs_debugfont_dx9 , sizeof ( vs_debugfont_dx9 ) ) ;
2014-05-26 14:09:26 -07:00
break ;
case RendererType : : Direct3D11 :
2014-03-31 20:08:32 -07:00
mem = makeRef ( vs_debugfont_dx11 , sizeof ( vs_debugfont_dx11 ) ) ;
2014-05-26 14:09:26 -07:00
break ;
default :
2014-03-31 20:08:32 -07:00
mem = makeRef ( vs_debugfont_glsl , sizeof ( vs_debugfont_glsl ) ) ;
2014-05-26 14:09:26 -07:00
break ;
2014-03-31 20:08:32 -07:00
}
2014-03-29 19:42:57 -07:00
ShaderHandle vsh = createShader ( mem ) ;
2012-06-29 20:10:10 -07:00
2014-05-26 14:09:26 -07:00
switch ( g_caps . rendererType )
2014-03-31 20:08:32 -07:00
{
2014-05-26 14:09:26 -07:00
case RendererType : : Direct3D9 :
2014-03-31 20:08:32 -07:00
mem = makeRef ( fs_debugfont_dx9 , sizeof ( fs_debugfont_dx9 ) ) ;
2014-05-26 14:09:26 -07:00
break ;
case RendererType : : Direct3D11 :
2014-03-31 20:08:32 -07:00
mem = makeRef ( fs_debugfont_dx11 , sizeof ( fs_debugfont_dx11 ) ) ;
2014-05-26 14:09:26 -07:00
break ;
default :
2014-03-31 20:08:32 -07:00
mem = makeRef ( fs_debugfont_glsl , sizeof ( fs_debugfont_glsl ) ) ;
2014-05-26 14:09:26 -07:00
break ;
2014-03-31 20:08:32 -07:00
}
2014-03-29 19:42:57 -07:00
ShaderHandle fsh = createShader ( mem ) ;
2012-06-29 20:10:10 -07:00
2014-03-29 19:42:57 -07:00
m_program = createProgram ( vsh , fsh , true ) ;
2012-06-29 20:10:10 -07:00
2013-09-20 22:13:58 -07:00
m_vb = s_ctx - > createTransientVertexBuffer ( numBatchVertices * m_decl . m_stride , & m_decl ) ;
m_ib = s_ctx - > createTransientIndexBuffer ( numBatchIndices * 2 ) ;
2012-06-29 20:10:10 -07:00
}
2013-01-27 21:52:29 -08:00
void TextVideoMemBlitter : : shutdown ( )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
destroyProgram ( m_program ) ;
destroyTexture ( m_texture ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyTransientVertexBuffer ( m_vb ) ;
s_ctx - > destroyTransientIndexBuffer ( m_ib ) ;
2013-01-27 21:52:29 -08:00
}
2014-05-26 14:09:26 -07:00
void blit ( RendererContextI * _renderCtx , TextVideoMemBlitter & _blitter , const TextVideoMem & _mem )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_RENDER_THREAD ( ) ;
2012-07-29 13:50:23 -07:00
struct Vertex
2012-06-29 20:10:10 -07:00
{
float m_x ;
float m_y ;
float m_z ;
uint32_t m_fg ;
uint32_t m_bg ;
float m_u ;
float m_v ;
} ;
static uint32_t palette [ 16 ] =
{
0x0 ,
0xff0000cc ,
0xff069a4e ,
0xff00a0c4 ,
0xffa46534 ,
0xff7b5075 ,
0xff9a9806 ,
0xffcfd7d3 ,
0xff535755 ,
0xff2929ef ,
0xff34e28a ,
0xff4fe9fc ,
0xffcf9f72 ,
0xffa87fad ,
0xffe2e234 ,
0xffeceeee ,
} ;
uint32_t yy = 0 ;
uint32_t xx = 0 ;
const float texelWidth = 1.0f / 2048.0f ;
const float texelWidthHalf = texelWidth * 0.5f ;
const float texelHeight = 1.0f / 24.0f ;
2014-05-26 14:09:26 -07:00
const float texelHeightHalf = RendererType : : Direct3D9 = = g_caps . rendererType ? texelHeight * 0.5f : 0.0f ;
2012-06-29 20:10:10 -07:00
const float utop = ( _mem . m_small ? 0.0f : 8.0f ) * texelHeight + texelHeightHalf ;
const float ubottom = ( _mem . m_small ? 8.0f : 24.0f ) * texelHeight + texelHeightHalf ;
const float fontHeight = ( _mem . m_small ? 8.0f : 16.0f ) ;
2014-05-26 14:09:26 -07:00
_renderCtx - > blitSetup ( _blitter ) ;
2012-06-29 20:10:10 -07:00
for ( ; yy < _mem . m_height ; )
{
2014-05-26 14:09:26 -07:00
Vertex * vertex = ( Vertex * ) _blitter . m_vb - > data ;
uint16_t * indices = ( uint16_t * ) _blitter . m_ib - > data ;
2012-06-29 20:10:10 -07:00
uint32_t startVertex = 0 ;
uint32_t numIndices = 0 ;
for ( ; yy < _mem . m_height & & numIndices < numBatchIndices ; + + yy )
{
xx = xx < _mem . m_width ? xx : 0 ;
const uint8_t * line = & _mem . m_mem [ ( yy * _mem . m_width + xx ) * 2 ] ;
for ( ; xx < _mem . m_width & & numIndices < numBatchIndices ; + + xx )
{
uint8_t ch = line [ 0 ] ;
uint8_t attr = line [ 1 ] ;
if ( 0 ! = ( ch | attr )
& & ( ' ' ! = ch | | 0 ! = ( attr & 0xf0 ) ) )
{
uint32_t fg = palette [ attr & 0xf ] ;
uint32_t bg = palette [ ( attr > > 4 ) & 0xf ] ;
2014-01-08 22:08:37 -08:00
Vertex vert [ 4 ] =
2012-06-29 20:10:10 -07:00
{
{ ( xx ) * 8.0f , ( yy ) * fontHeight , 0.0f , fg , bg , ( ch ) * 8.0f * texelWidth - texelWidthHalf , utop } ,
{ ( xx + 1 ) * 8.0f , ( yy ) * fontHeight , 0.0f , fg , bg , ( ch + 1 ) * 8.0f * texelWidth - texelWidthHalf , utop } ,
{ ( xx + 1 ) * 8.0f , ( yy + 1 ) * fontHeight , 0.0f , fg , bg , ( ch + 1 ) * 8.0f * texelWidth - texelWidthHalf , ubottom } ,
{ ( xx ) * 8.0f , ( yy + 1 ) * fontHeight , 0.0f , fg , bg , ( ch ) * 8.0f * texelWidth - texelWidthHalf , ubottom } ,
} ;
memcpy ( vertex , vert , sizeof ( vert ) ) ;
vertex + = 4 ;
indices [ 0 ] = startVertex + 0 ;
indices [ 1 ] = startVertex + 1 ;
indices [ 2 ] = startVertex + 2 ;
indices [ 3 ] = startVertex + 2 ;
indices [ 4 ] = startVertex + 3 ;
indices [ 5 ] = startVertex + 0 ;
startVertex + = 4 ;
indices + = 6 ;
numIndices + = 6 ;
}
line + = 2 ;
}
if ( numIndices > = numBatchIndices )
{
break ;
}
}
2014-05-26 14:09:26 -07:00
_renderCtx - > blitRender ( _blitter , numIndices ) ;
2012-06-29 20:10:10 -07:00
}
}
2012-07-29 13:50:23 -07:00
void ClearQuad : : init ( )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-07-29 13:50:23 -07:00
2014-05-26 14:09:26 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_CLEAR_QUAD )
& & RendererType : : OpenGLES ! = g_caps . rendererType
& & RendererType : : Direct3D9 ! = g_caps . rendererType
& & RendererType : : Null ! = g_caps . rendererType )
2014-03-31 20:08:32 -07:00
{
2014-05-10 20:51:44 -07:00
m_decl
. begin ( )
. add ( Attrib : : Position , 3 , AttribType : : Float )
. add ( Attrib : : Color0 , 4 , AttribType : : Uint8 , true )
. end ( ) ;
2014-03-31 20:08:32 -07:00
2014-04-07 22:58:30 -07:00
ShaderHandle vsh = BGFX_INVALID_HANDLE ;
2014-03-31 20:08:32 -07:00
const Memory * fragMem [ BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ] ;
2014-05-26 14:09:26 -07:00
if ( RendererType : : Direct3D11 = = g_caps . rendererType )
2014-03-31 20:08:32 -07:00
{
vsh = createShader ( makeRef ( vs_clear_dx11 , sizeof ( vs_clear_dx11 ) ) ) ;
fragMem [ 0 ] = makeRef ( fs_clear0_dx11 , sizeof ( fs_clear0_dx11 ) ) ;
fragMem [ 1 ] = makeRef ( fs_clear1_dx11 , sizeof ( fs_clear1_dx11 ) ) ;
fragMem [ 2 ] = makeRef ( fs_clear2_dx11 , sizeof ( fs_clear2_dx11 ) ) ;
fragMem [ 3 ] = makeRef ( fs_clear3_dx11 , sizeof ( fs_clear3_dx11 ) ) ;
}
2014-05-26 14:09:26 -07:00
else if ( RendererType : : OpenGL = = g_caps . rendererType )
2014-03-31 20:08:32 -07:00
{
vsh = createShader ( makeRef ( vs_clear_glsl , sizeof ( vs_clear_glsl ) ) ) ;
fragMem [ 0 ] = makeRef ( fs_clear0_glsl , sizeof ( fs_clear0_glsl ) ) ;
fragMem [ 1 ] = makeRef ( fs_clear1_glsl , sizeof ( fs_clear1_glsl ) ) ;
fragMem [ 2 ] = makeRef ( fs_clear2_glsl , sizeof ( fs_clear2_glsl ) ) ;
fragMem [ 3 ] = makeRef ( fs_clear3_glsl , sizeof ( fs_clear3_glsl ) ) ;
}
2014-04-19 18:16:26 -07:00
for ( uint32_t ii = 0 , num = g_caps . maxFBAttachments ; ii < num ; + + ii )
2014-03-31 20:08:32 -07:00
{
ShaderHandle fsh = createShader ( fragMem [ ii ] ) ;
m_program [ ii ] = createProgram ( vsh , fsh ) ;
destroyShader ( fsh ) ;
}
destroyShader ( vsh ) ;
m_vb = s_ctx - > createTransientVertexBuffer ( 4 * m_decl . m_stride , & m_decl ) ;
const Memory * mem = alloc ( 6 * sizeof ( uint16_t ) ) ;
uint16_t * indices = ( uint16_t * ) mem - > data ;
indices [ 0 ] = 0 ;
indices [ 1 ] = 1 ;
indices [ 2 ] = 2 ;
indices [ 3 ] = 2 ;
indices [ 4 ] = 3 ;
indices [ 5 ] = 0 ;
m_ib = s_ctx - > createIndexBuffer ( mem ) ;
}
2012-07-29 13:50:23 -07:00
}
2013-01-27 21:52:29 -08:00
void ClearQuad : : shutdown ( )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-03-23 16:02:34 -07:00
2014-05-26 14:09:26 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_CLEAR_QUAD )
& & RendererType : : OpenGLES ! = g_caps . rendererType
& & RendererType : : Direct3D9 ! = g_caps . rendererType
& & RendererType : : Null ! = g_caps . rendererType )
2014-03-25 23:07:51 -07:00
{
2014-03-31 20:08:32 -07:00
for ( uint32_t ii = 0 ; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ; + + ii )
{
2014-04-19 18:16:26 -07:00
if ( isValid ( m_program [ ii ] ) )
{
destroyProgram ( m_program [ ii ] ) ;
m_program [ ii ] . idx = invalidHandle ;
}
2014-03-31 20:08:32 -07:00
}
destroyIndexBuffer ( m_ib ) ;
s_ctx - > destroyTransientVertexBuffer ( m_vb ) ;
2014-03-25 23:07:51 -07:00
}
2013-01-27 21:52:29 -08:00
}
2014-04-15 19:10:56 -07:00
const char * s_uniformTypeName [ UniformType : : Count ] =
{
" int " ,
" float " ,
NULL ,
" int " ,
" float " ,
" vec2 " ,
" vec3 " ,
" vec4 " ,
" mat3 " ,
" mat4 " ,
} ;
const char * getUniformTypeName ( UniformType : : Enum _enum )
{
return s_uniformTypeName [ _enum ] ;
}
UniformType : : Enum nameToUniformTypeEnum ( const char * _name )
{
for ( uint32_t ii = 0 ; ii < UniformType : : Count ; + + ii )
{
if ( NULL ! = s_uniformTypeName [ ii ]
& & 0 = = strcmp ( _name , s_uniformTypeName [ ii ] ) )
{
return UniformType : : Enum ( ii ) ;
}
}
return UniformType : : Count ;
}
2012-06-29 20:10:10 -07:00
static const char * s_predefinedName [ PredefinedUniform : : Count ] =
{
" u_viewRect " ,
" u_viewTexel " ,
" u_view " ,
2014-05-10 20:51:44 -07:00
" u_invView " ,
" u_proj " ,
" u_invProj " ,
2012-06-29 20:10:10 -07:00
" u_viewProj " ,
2014-05-10 20:51:44 -07:00
" u_invViewProj " ,
2012-06-29 20:10:10 -07:00
" u_viewProjX " ,
" u_model " ,
2012-10-07 20:41:18 -07:00
" u_modelView " ,
2012-06-29 20:10:10 -07:00
" u_modelViewProj " ,
" u_modelViewProjX " ,
" u_alphaRef " ,
} ;
2012-07-22 21:08:58 -07:00
const char * getPredefinedUniformName ( PredefinedUniform : : Enum _enum )
{
return s_predefinedName [ _enum ] ;
}
2012-06-29 20:10:10 -07:00
PredefinedUniform : : Enum nameToPredefinedUniformEnum ( const char * _name )
{
for ( uint32_t ii = 0 ; ii < PredefinedUniform : : Count ; + + ii )
{
if ( 0 = = strcmp ( _name , s_predefinedName [ ii ] ) )
{
return PredefinedUniform : : Enum ( ii ) ;
}
}
return PredefinedUniform : : Count ;
}
2013-10-21 20:37:02 -07:00
uint32_t Frame : : submit ( uint8_t _id , int32_t _depth )
2012-06-29 20:10:10 -07:00
{
if ( m_discard )
{
2013-07-29 19:01:29 -07:00
discard ( ) ;
2013-10-21 20:37:02 -07:00
return m_num ;
2012-06-29 20:10:10 -07:00
}
2012-09-16 17:36:08 -07:00
if ( BGFX_CONFIG_MAX_DRAW_CALLS - 1 < = m_num
| | ( 0 = = m_state . m_numVertices & & 0 = = m_state . m_numIndices ) )
2012-06-29 20:10:10 -07:00
{
+ + m_numDropped ;
2013-10-21 20:37:02 -07:00
return m_num ;
2012-06-29 20:10:10 -07:00
}
2013-01-05 22:34:31 -08:00
BX_WARN ( invalidHandle ! = m_key . m_program , " Program with invalid handle " ) ;
if ( invalidHandle ! = m_key . m_program )
{
m_key . m_depth = _depth ;
m_key . m_view = _id ;
2013-09-20 22:13:58 -07:00
m_key . m_seq = s_ctx - > m_seq [ _id ] & s_ctx - > m_seqMask [ _id ] ;
s_ctx - > m_seq [ _id ] + + ;
2013-01-05 22:34:31 -08:00
uint64_t key = m_key . encode ( ) ;
m_sortKeys [ m_num ] = key ;
m_sortValues [ m_num ] = m_numRenderStates ;
+ + m_num ;
m_state . m_constEnd = m_constantBuffer - > getPos ( ) ;
m_state . m_flags | = m_flags ;
m_renderState [ m_numRenderStates ] = m_state ;
+ + m_numRenderStates ;
}
2012-06-29 20:10:10 -07:00
m_state . clear ( ) ;
m_flags = BGFX_STATE_NONE ;
2013-10-21 20:37:02 -07:00
return m_num ;
2012-06-29 20:10:10 -07:00
}
2013-10-21 20:37:02 -07:00
uint32_t Frame : : submitMask ( uint32_t _viewMask , int32_t _depth )
2012-06-29 20:10:10 -07:00
{
if ( m_discard )
{
2013-07-29 19:01:29 -07:00
discard ( ) ;
2013-10-21 20:37:02 -07:00
return m_num ;
2012-06-29 20:10:10 -07:00
}
2012-09-16 17:36:08 -07:00
if ( BGFX_CONFIG_MAX_DRAW_CALLS - 1 < = m_num
| | ( 0 = = m_state . m_numVertices & & 0 = = m_state . m_numIndices ) )
2012-06-29 20:10:10 -07:00
{
2013-08-03 22:15:13 -07:00
m_numDropped + = bx : : uint32_cntbits ( _viewMask ) ;
2013-10-21 20:37:02 -07:00
return m_num ;
2012-06-29 20:10:10 -07:00
}
2013-01-05 22:34:31 -08:00
BX_WARN ( invalidHandle ! = m_key . m_program , " Program with invalid handle " ) ;
if ( invalidHandle ! = m_key . m_program )
2012-06-29 20:10:10 -07:00
{
2013-01-05 22:34:31 -08:00
m_key . m_depth = _depth ;
2012-06-29 20:10:10 -07:00
2013-08-03 22:15:13 -07:00
for ( uint32_t id = 0 , viewMask = _viewMask , ntz = bx : : uint32_cnttz ( _viewMask ) ; 0 ! = viewMask ; viewMask > > = 1 , id + = 1 , ntz = bx : : uint32_cnttz ( viewMask ) )
2013-01-05 22:34:31 -08:00
{
viewMask > > = ntz ;
id + = ntz ;
m_key . m_view = id ;
2013-09-20 22:13:58 -07:00
m_key . m_seq = s_ctx - > m_seq [ id ] & s_ctx - > m_seqMask [ id ] ;
s_ctx - > m_seq [ id ] + + ;
2013-01-05 22:34:31 -08:00
uint64_t key = m_key . encode ( ) ;
m_sortKeys [ m_num ] = key ;
m_sortValues [ m_num ] = m_numRenderStates ;
+ + m_num ;
}
2014-01-08 22:08:37 -08:00
2013-01-05 22:34:31 -08:00
m_state . m_constEnd = m_constantBuffer - > getPos ( ) ;
m_state . m_flags | = m_flags ;
m_renderState [ m_numRenderStates ] = m_state ;
+ + m_numRenderStates ;
2012-06-29 20:10:10 -07:00
}
2013-01-05 22:34:31 -08:00
2012-06-29 20:10:10 -07:00
m_state . clear ( ) ;
m_flags = BGFX_STATE_NONE ;
2013-10-21 20:37:02 -07:00
return m_num ;
2012-06-29 20:10:10 -07:00
}
void Frame : : sort ( )
{
2013-09-20 22:13:58 -07:00
bx : : radixSort64 ( m_sortKeys , s_ctx - > m_tempKeys , m_sortValues , s_ctx - > m_tempValues , m_num ) ;
2012-06-29 20:10:10 -07:00
}
2013-11-18 20:43:17 -08:00
RenderFrame : : Enum renderFrame ( )
2012-06-29 20:10:10 -07:00
{
2013-11-18 20:43:17 -08:00
if ( NULL = = s_ctx )
{
2014-01-19 22:34:58 -08:00
s_renderFrameCalled = true ;
2013-11-18 20:43:17 -08:00
return RenderFrame : : NoContext ;
}
2012-11-25 18:24:50 -08:00
BGFX_CHECK_RENDER_THREAD ( ) ;
2013-11-18 20:43:17 -08:00
if ( s_ctx - > renderFrame ( ) )
{
return RenderFrame : : Exiting ;
}
return RenderFrame : : Render ;
2012-06-29 20:10:10 -07:00
}
2013-06-10 22:41:03 -07:00
const uint32_t g_uniformTypeSize [ UniformType : : Count + 1 ] =
2012-06-29 20:10:10 -07:00
{
sizeof ( int32_t ) ,
sizeof ( float ) ,
0 ,
1 * sizeof ( int32_t ) ,
1 * sizeof ( float ) ,
2 * sizeof ( float ) ,
3 * sizeof ( float ) ,
4 * sizeof ( float ) ,
3 * 3 * sizeof ( float ) ,
4 * 4 * sizeof ( float ) ,
2013-06-10 22:41:03 -07:00
1 ,
2012-06-29 20:10:10 -07:00
} ;
2012-10-27 21:34:41 -07:00
void ConstantBuffer : : writeUniform ( UniformType : : Enum _type , uint16_t _loc , const void * _value , uint16_t _num )
2012-06-29 20:10:10 -07:00
{
uint32_t opcode = encodeOpcode ( _type , _loc , _num , true ) ;
write ( opcode ) ;
2012-10-27 21:34:41 -07:00
write ( _value , g_uniformTypeSize [ _type ] * _num ) ;
2012-06-29 20:10:10 -07:00
}
2014-04-15 19:10:56 -07:00
void ConstantBuffer : : writeUniformHandle ( UniformType : : Enum _type , uint16_t _loc , UniformHandle _handle , uint16_t _num )
2012-06-29 20:10:10 -07:00
{
uint32_t opcode = encodeOpcode ( _type , _loc , _num , false ) ;
write ( opcode ) ;
2014-04-15 19:10:56 -07:00
write ( & _handle , sizeof ( UniformHandle ) ) ;
2012-06-29 20:10:10 -07:00
}
2013-06-10 22:41:03 -07:00
void ConstantBuffer : : writeMarker ( const char * _marker )
{
uint16_t num = ( uint16_t ) strlen ( _marker ) + 1 ;
uint32_t opcode = encodeOpcode ( bgfx : : UniformType : : Count , 0 , num , true ) ;
write ( opcode ) ;
write ( _marker , num ) ;
}
2014-04-19 18:16:26 -07:00
struct CapsFlags
{
uint64_t m_flag ;
const char * m_str ;
} ;
static const CapsFlags s_capsFlags [ ] =
{
# define CAPS_FLAGS(_x) { _x, #_x }
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_BC1 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_BC2 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_BC3 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_BC4 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_BC5 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_ETC1 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_ETC2 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_ETC2A ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_ETC2A1 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_PTC12 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_PTC14 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_PTC14A ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_PTC12A ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_PTC22 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_PTC24 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D16 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D24 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D24S8 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D32 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D16F ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D24F ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D32F ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_FORMAT_D0S8 ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_COMPARE_LEQUAL ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_COMPARE_ALL ) ,
CAPS_FLAGS ( BGFX_CAPS_TEXTURE_3D ) ,
CAPS_FLAGS ( BGFX_CAPS_VERTEX_ATTRIB_HALF ) ,
CAPS_FLAGS ( BGFX_CAPS_INSTANCING ) ,
CAPS_FLAGS ( BGFX_CAPS_RENDERER_MULTITHREADED ) ,
CAPS_FLAGS ( BGFX_CAPS_FRAGMENT_DEPTH ) ,
CAPS_FLAGS ( BGFX_CAPS_BLEND_INDEPENDENT ) ,
# undef CAPS_FLAGS
} ;
static void dumpCaps ( )
{
2014-05-26 14:09:26 -07:00
BX_TRACE ( " Supported capabilities (%s): " , s_ctx - > m_renderCtx - > getRendererName ( ) ) ;
2014-04-19 18:16:26 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( s_capsFlags ) ; + + ii )
{
if ( 0 ! = ( g_caps . supported & s_capsFlags [ ii ] . m_flag ) )
{
BX_TRACE ( " \t %s " , s_capsFlags [ ii ] . m_str ) ;
}
}
BX_TRACE ( " Emulated capabilities: " ) ;
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( s_capsFlags ) ; + + ii )
{
if ( 0 ! = ( g_caps . emulated & s_capsFlags [ ii ] . m_flag ) )
{
BX_TRACE ( " \t %s " , s_capsFlags [ ii ] . m_str ) ;
}
}
BX_TRACE ( " Max FB attachments: %d " , g_caps . maxFBAttachments ) ;
}
2014-05-26 14:09:26 -07:00
void Context : : init ( RendererType : : Enum _type )
2012-06-29 20:10:10 -07:00
{
2013-03-09 14:57:53 -08:00
BX_CHECK ( ! m_rendererInitialized , " Already initialized? " ) ;
2012-06-29 20:10:10 -07:00
2013-03-09 14:57:53 -08:00
m_exit = false ;
m_frames = 0 ;
m_render = & m_frame [ 0 ] ;
m_submit = & m_frame [ 1 ] ;
m_debug = BGFX_DEBUG_NONE ;
2012-06-29 20:10:10 -07:00
m_submit - > create ( ) ;
m_render - > create ( ) ;
# if BGFX_CONFIG_MULTITHREADED
2014-01-19 22:34:58 -08:00
if ( s_renderFrameCalled )
{
// When bgfx::renderFrame is called before init render thread
// should not be created.
BX_TRACE ( " Application called bgfx::renderFrame directly, not creating render thread. " ) ;
}
else
2012-06-29 20:10:10 -07:00
{
2014-01-19 22:34:58 -08:00
BX_TRACE ( " Creating rendering thread. " ) ;
2012-12-04 20:07:14 -08:00
m_thread . init ( renderThread , this ) ;
2012-06-29 20:10:10 -07:00
}
2012-07-02 20:53:12 -07:00
# else
2014-01-19 22:34:58 -08:00
BX_TRACE ( " Multithreaded renderer is disabled. " ) ;
2012-06-29 20:10:10 -07:00
# endif // BGFX_CONFIG_MULTITHREADED
2014-02-05 23:07:11 -08:00
memset ( m_fb , 0xff , sizeof ( m_fb ) ) ;
2012-06-29 20:10:10 -07:00
memset ( m_clear , 0 , sizeof ( m_clear ) ) ;
memset ( m_rect , 0 , sizeof ( m_rect ) ) ;
2013-07-14 14:32:09 -07:00
memset ( m_scissor , 0 , sizeof ( m_scissor ) ) ;
2012-06-29 20:10:10 -07:00
memset ( m_seq , 0 , sizeof ( m_seq ) ) ;
memset ( m_seqMask , 0 , sizeof ( m_seqMask ) ) ;
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_rect ) ; + + ii )
2012-07-29 13:50:23 -07:00
{
m_rect [ ii ] . m_width = 1 ;
m_rect [ ii ] . m_height = 1 ;
}
2013-03-09 14:57:53 -08:00
m_declRef . init ( ) ;
2014-05-26 14:09:26 -07:00
CommandBuffer & cmdbuf = getCommandBuffer ( CommandBuffer : : RendererInit ) ;
cmdbuf . write ( _type ) ;
2013-03-09 14:57:53 -08:00
frameNoRenderWait ( ) ;
2012-06-29 20:10:10 -07:00
2014-04-19 18:16:26 -07:00
// Make sure renderer init is called from render thread.
// g_caps is initialized and available after this point.
frame ( ) ;
const uint64_t emulatedCaps = 0
| BGFX_CAPS_TEXTURE_FORMAT_BC1
| BGFX_CAPS_TEXTURE_FORMAT_BC2
| BGFX_CAPS_TEXTURE_FORMAT_BC3
| BGFX_CAPS_TEXTURE_FORMAT_BC4
| BGFX_CAPS_TEXTURE_FORMAT_BC5
| BGFX_CAPS_TEXTURE_FORMAT_ETC1
| BGFX_CAPS_TEXTURE_FORMAT_ETC2
| BGFX_CAPS_TEXTURE_FORMAT_ETC2A
| BGFX_CAPS_TEXTURE_FORMAT_ETC2A1
;
g_caps . emulated | = emulatedCaps ^ ( g_caps . supported & emulatedCaps ) ;
2014-05-26 14:09:26 -07:00
g_caps . rendererType = m_renderCtx - > getRendererType ( ) ;
initAttribTypeSizeTable ( g_caps . rendererType ) ;
2014-04-19 18:16:26 -07:00
dumpCaps ( ) ;
2012-06-29 20:10:10 -07:00
m_textVideoMemBlitter . init ( ) ;
2012-07-29 13:50:23 -07:00
m_clearQuad . init ( ) ;
2012-06-29 20:10:10 -07:00
m_submit - > m_transientVb = createTransientVertexBuffer ( BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE ) ;
m_submit - > m_transientIb = createTransientIndexBuffer ( BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE ) ;
frame ( ) ;
m_submit - > m_transientVb = createTransientVertexBuffer ( BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE ) ;
m_submit - > m_transientIb = createTransientIndexBuffer ( BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE ) ;
frame ( ) ;
2013-06-09 15:28:25 -07:00
for ( uint8_t ii = 0 ; ii < BGFX_CONFIG_MAX_VIEWS ; + + ii )
{
char name [ 256 ] ;
bx : : snprintf ( name , sizeof ( name ) , " %02d view " , ii ) ;
setViewName ( ii , name ) ;
}
2012-06-29 20:10:10 -07:00
}
void Context : : shutdown ( )
{
2013-01-27 22:43:11 -08:00
getCommandBuffer ( CommandBuffer : : RendererShutdownBegin ) ;
2013-01-27 21:52:29 -08:00
frame ( ) ;
destroyTransientVertexBuffer ( m_submit - > m_transientVb ) ;
destroyTransientIndexBuffer ( m_submit - > m_transientIb ) ;
m_textVideoMemBlitter . shutdown ( ) ;
m_clearQuad . shutdown ( ) ;
frame ( ) ;
destroyTransientVertexBuffer ( m_submit - > m_transientVb ) ;
destroyTransientIndexBuffer ( m_submit - > m_transientIb ) ;
frame ( ) ;
2013-10-03 20:36:40 -07:00
frame ( ) ; // If any VertexDecls needs to be destroyed.
2013-01-27 21:52:29 -08:00
getCommandBuffer ( CommandBuffer : : RendererShutdownEnd ) ;
2012-06-29 20:10:10 -07:00
frame ( ) ;
2013-03-09 14:57:53 -08:00
m_declRef . shutdown ( m_vertexDeclHandle ) ;
2012-06-29 20:10:10 -07:00
# if BGFX_CONFIG_MULTITHREADED
2012-12-02 18:29:28 -08:00
if ( m_thread . isRunning ( ) )
2012-06-29 20:10:10 -07:00
{
2012-12-02 18:29:28 -08:00
m_thread . shutdown ( ) ;
2012-06-29 20:10:10 -07:00
}
# endif // BGFX_CONFIG_MULTITHREADED
2013-11-18 20:43:17 -08:00
s_ctx = NULL ; // Can't be used by renderFrame at this point.
2013-03-09 14:57:53 -08:00
renderSemWait ( ) ;
2012-06-29 20:10:10 -07:00
m_submit - > destroy ( ) ;
m_render - > destroy ( ) ;
2013-01-27 21:52:29 -08:00
2014-03-31 20:08:32 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG ) )
{
# define CHECK_HANDLE_LEAK(_handleAlloc) \
do { \
BX_WARN ( 0 = = _handleAlloc . getNumHandles ( ) \
, " LEAK: " # _handleAlloc " %d (max: %d) " \
, _handleAlloc . getNumHandles ( ) \
, _handleAlloc . getMaxHandles ( ) \
) ; \
} while ( 0 )
CHECK_HANDLE_LEAK ( m_dynamicIndexBufferHandle ) ;
CHECK_HANDLE_LEAK ( m_dynamicVertexBufferHandle ) ;
CHECK_HANDLE_LEAK ( m_indexBufferHandle ) ;
CHECK_HANDLE_LEAK ( m_vertexDeclHandle ) ;
CHECK_HANDLE_LEAK ( m_vertexBufferHandle ) ;
CHECK_HANDLE_LEAK ( m_shaderHandle ) ;
CHECK_HANDLE_LEAK ( m_programHandle ) ;
CHECK_HANDLE_LEAK ( m_textureHandle ) ;
CHECK_HANDLE_LEAK ( m_frameBufferHandle ) ;
CHECK_HANDLE_LEAK ( m_uniformHandle ) ;
# undef CHECK_HANDLE_LEAK
}
2012-06-29 20:10:10 -07:00
}
2013-10-05 18:07:44 -07:00
void Context : : 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 Context : : 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 )
{
destroyVertexBufferInternal ( _frame - > m_freeVertexBufferHandle [ ii ] ) ;
}
2014-03-29 19:42:57 -07:00
for ( uint16_t ii = 0 , num = _frame - > m_numFreeShaderHandles ; ii < num ; + + ii )
2013-10-05 18:07:44 -07:00
{
2014-03-29 19:42:57 -07:00
m_shaderHandle . free ( _frame - > m_freeShaderHandle [ ii ] . idx ) ;
2013-10-05 18:07:44 -07:00
}
for ( uint16_t ii = 0 , num = _frame - > m_numFreeProgramHandles ; ii < num ; + + ii )
{
m_programHandle . free ( _frame - > m_freeProgramHandle [ ii ] . idx ) ;
}
for ( uint16_t ii = 0 , num = _frame - > m_numFreeTextureHandles ; ii < num ; + + ii )
{
m_textureHandle . free ( _frame - > m_freeTextureHandle [ ii ] . idx ) ;
}
2014-02-05 23:07:11 -08:00
for ( uint16_t ii = 0 , num = _frame - > m_numFreeFrameBufferHandles ; ii < num ; + + ii )
2013-10-05 18:07:44 -07:00
{
2014-02-05 23:07:11 -08:00
m_frameBufferHandle . free ( _frame - > m_freeFrameBufferHandle [ ii ] . idx ) ;
2013-10-05 18:07:44 -07:00
}
for ( uint16_t ii = 0 , num = _frame - > m_numFreeUniformHandles ; ii < num ; + + ii )
{
m_uniformHandle . free ( _frame - > m_freeUniformHandle [ ii ] . idx ) ;
}
}
2013-10-21 20:37:02 -07:00
uint32_t Context : : frame ( )
2013-10-05 18:07:44 -07:00
{
2014-01-20 21:49:36 -08:00
BX_CHECK ( 0 = = m_instBufferCount , " Instance buffer allocated, but not used. This is incorrect, and causes memory leak. " ) ;
2013-10-05 18:07:44 -07:00
// wait for render thread to finish
renderSemWait ( ) ;
frameNoRenderWait ( ) ;
2013-10-21 20:37:02 -07:00
return m_frames ;
2013-10-05 18:07:44 -07:00
}
void Context : : frameNoRenderWait ( )
{
swap ( ) ;
// release render thread
gameSemPost ( ) ;
# if !BGFX_CONFIG_MULTITHREADED
renderFrame ( ) ;
# endif // BGFX_CONFIG_MULTITHREADED
}
void Context : : swap ( )
{
freeDynamicBuffers ( ) ;
m_submit - > m_resolution = m_resolution ;
m_submit - > m_debug = m_debug ;
2014-02-05 23:07:11 -08:00
memcpy ( m_submit - > m_fb , m_fb , sizeof ( m_fb ) ) ;
2013-10-05 18:07:44 -07:00
memcpy ( m_submit - > m_clear , m_clear , sizeof ( m_clear ) ) ;
memcpy ( m_submit - > m_rect , m_rect , sizeof ( m_rect ) ) ;
memcpy ( m_submit - > m_scissor , m_scissor , sizeof ( m_scissor ) ) ;
memcpy ( m_submit - > m_view , m_view , sizeof ( m_view ) ) ;
memcpy ( m_submit - > m_proj , m_proj , sizeof ( m_proj ) ) ;
memcpy ( m_submit - > m_other , m_other , sizeof ( m_other ) ) ;
m_submit - > finish ( ) ;
Frame * temp = m_render ;
m_render = m_submit ;
m_submit = temp ;
m_frames + + ;
m_submit - > start ( ) ;
memset ( m_seq , 0 , sizeof ( m_seq ) ) ;
freeAllHandles ( m_submit ) ;
m_submit - > resetFreeHandles ( ) ;
m_submit - > m_textVideoMem - > resize ( m_render - > m_textVideoMem - > m_small , m_resolution . m_width , m_resolution . m_height ) ;
}
bool Context : : renderFrame ( )
{
2014-05-26 14:09:26 -07:00
if ( m_rendererInitialized )
{
m_renderCtx - > flip ( ) ;
}
2013-10-05 18:07:44 -07:00
gameSemWait ( ) ;
rendererExecCommands ( m_render - > m_cmdPre ) ;
if ( m_rendererInitialized )
{
2014-05-26 14:09:26 -07:00
m_renderCtx - > submit ( m_render , m_clearQuad , m_textVideoMemBlitter ) ;
2013-10-05 18:07:44 -07:00
}
rendererExecCommands ( m_render - > m_cmdPost ) ;
renderSemPost ( ) ;
return m_exit ;
}
2014-05-26 14:09:26 -07:00
void rendererUpdateUniforms ( RendererContextI * _renderCtx , ConstantBuffer * _constantBuffer , uint32_t _begin , uint32_t _end )
2013-10-05 18:07:44 -07:00
{
_constantBuffer - > reset ( _begin ) ;
while ( _constantBuffer - > getPos ( ) < _end )
{
uint32_t opcode = _constantBuffer - > read ( ) ;
if ( UniformType : : End = = opcode )
{
break ;
}
UniformType : : Enum type ;
uint16_t loc ;
uint16_t num ;
uint16_t copy ;
ConstantBuffer : : decodeOpcode ( opcode , type , loc , num , copy ) ;
uint32_t size = g_uniformTypeSize [ type ] * num ;
const char * data = _constantBuffer - > read ( size ) ;
if ( UniformType : : Count > type )
{
2014-04-15 19:10:56 -07:00
if ( copy )
{
2014-05-26 14:09:26 -07:00
_renderCtx - > updateUniform ( loc , data , size ) ;
2014-04-15 19:10:56 -07:00
}
else
{
2014-05-26 14:09:26 -07:00
_renderCtx - > updateUniform ( loc , * ( const char * * ) ( data ) , size ) ;
2014-04-15 19:10:56 -07:00
}
2013-10-05 18:07:44 -07:00
}
else
{
2014-05-26 14:09:26 -07:00
_renderCtx - > setMarker ( data , size ) ;
2013-10-05 18:07:44 -07:00
}
}
}
void Context : : flushTextureUpdateBatch ( CommandBuffer & _cmdbuf )
{
if ( m_textureUpdateBatch . sort ( ) )
{
const uint32_t pos = _cmdbuf . m_pos ;
uint32_t currentKey = UINT32_MAX ;
for ( uint32_t ii = 0 , num = m_textureUpdateBatch . m_num ; ii < num ; + + ii )
{
_cmdbuf . m_pos = m_textureUpdateBatch . m_values [ ii ] ;
TextureHandle handle ;
_cmdbuf . read ( handle ) ;
uint8_t side ;
_cmdbuf . read ( side ) ;
uint8_t mip ;
_cmdbuf . read ( mip ) ;
Rect rect ;
_cmdbuf . read ( rect ) ;
uint16_t zz ;
_cmdbuf . read ( zz ) ;
uint16_t depth ;
_cmdbuf . read ( depth ) ;
2013-11-07 22:59:17 -08:00
uint16_t pitch ;
_cmdbuf . read ( pitch ) ;
2013-10-05 18:07:44 -07:00
Memory * mem ;
_cmdbuf . read ( mem ) ;
uint32_t key = m_textureUpdateBatch . m_keys [ ii ] ;
if ( key ! = currentKey )
{
if ( currentKey ! = UINT32_MAX )
{
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateTextureEnd ( ) ;
2013-10-05 18:07:44 -07:00
}
currentKey = key ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateTextureBegin ( handle , side , mip ) ;
2013-10-05 18:07:44 -07:00
}
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateTexture ( handle , side , mip , rect , zz , depth , pitch , mem ) ;
2013-10-05 18:07:44 -07:00
release ( mem ) ;
}
if ( currentKey ! = UINT32_MAX )
{
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateTextureEnd ( ) ;
2013-10-05 18:07:44 -07:00
}
m_textureUpdateBatch . reset ( ) ;
_cmdbuf . m_pos = pos ;
}
}
2014-05-26 14:09:26 -07:00
typedef RendererContextI * ( * RendererCreateFn ) ( ) ;
typedef void ( * RendererDestroyFn ) ( ) ;
extern RendererContextI * rendererCreateNULL ( ) ;
extern void rendererDestroyNULL ( ) ;
extern RendererContextI * rendererCreateGL ( ) ;
extern void rendererDestroyGL ( ) ;
extern RendererContextI * rendererCreateD3D9 ( ) ;
extern void rendererDestroyD3D9 ( ) ;
extern RendererContextI * rendererCreateD3D11 ( ) ;
extern void rendererDestroyD3D11 ( ) ;
struct RendererCreator
{
RendererCreateFn createFn ;
RendererDestroyFn destroyFn ;
2014-05-27 20:05:13 -07:00
const char * name ;
2014-05-26 14:09:26 -07:00
bool supported ;
} ;
static const RendererCreator s_rendererCreator [ RendererType : : Count ] =
{
2014-05-27 20:05:13 -07:00
{ rendererCreateNULL , rendererDestroyNULL , BGFX_RENDERER_NULL_NAME , ! ! BGFX_CONFIG_RENDERER_NULL } , // Null
{ rendererCreateD3D9 , rendererDestroyD3D9 , BGFX_RENDERER_DIRECT3D9_NAME , ! ! BGFX_CONFIG_RENDERER_DIRECT3D9 } , // Direct3D9
{ rendererCreateD3D11 , rendererDestroyD3D11 , BGFX_RENDERER_DIRECT3D11_NAME , ! ! BGFX_CONFIG_RENDERER_DIRECT3D11 } , // Direct3D11
{ rendererCreateGL , rendererDestroyGL , BGFX_RENDERER_OPENGL_NAME , ! ! BGFX_CONFIG_RENDERER_OPENGLES } , // OpenGLES
{ rendererCreateGL , rendererDestroyGL , BGFX_RENDERER_OPENGL_NAME , ! ! BGFX_CONFIG_RENDERER_OPENGL } , // OpenGL
2014-05-26 14:09:26 -07:00
} ;
2014-05-27 20:28:27 -07:00
uint32_t getWindowsVersion ( )
{
# if BX_PLATFORM_WINDOWS
OSVERSIONINFOEXA ovi = { } ;
ovi . dwOSVersionInfoSize = sizeof ( ovi ) ;
if ( ! GetVersionExA ( ( LPOSVERSIONINFOA ) & ovi ) )
{
return 0x0501 ; // _WIN32_WINNT_WINXP
}
// _WIN32_WINNT_WINBLUE 0x0602
// _WIN32_WINNT_WIN8 0x0602
// _WIN32_WINNT_WIN7 0x0601
// _WIN32_WINNT_VISTA 0x0600
return ( ovi . dwMajorVersion < < 8 )
| ovi . dwMinorVersion
;
# else
return 0 ;
# endif // BX_PLATFORM_WINDOWS
}
2014-05-26 14:09:26 -07:00
RendererContextI * rendererCreate ( RendererType : : Enum _type )
{
if ( RendererType : : Count = = _type )
{
again :
if ( BX_ENABLED ( BX_PLATFORM_WINDOWS ) )
{
2014-05-27 20:28:27 -07:00
RendererType : : Enum first = RendererType : : Direct3D9 ;
RendererType : : Enum second = RendererType : : Direct3D11 ;
if ( 0x602 = = getWindowsVersion ( ) )
{
first = RendererType : : Direct3D11 ;
second = RendererType : : Direct3D9 ;
}
if ( s_rendererCreator [ first ] . supported )
2014-05-26 14:09:26 -07:00
{
2014-05-27 20:28:27 -07:00
_type = first ;
2014-05-26 14:09:26 -07:00
}
2014-05-27 20:28:27 -07:00
else if ( s_rendererCreator [ second ] . supported )
2014-05-26 14:09:26 -07:00
{
2014-05-27 20:28:27 -07:00
_type = second ;
2014-05-26 14:09:26 -07:00
}
else if ( s_rendererCreator [ RendererType : : OpenGL ] . supported )
{
_type = RendererType : : OpenGL ;
}
else if ( s_rendererCreator [ RendererType : : OpenGLES ] . supported )
{
_type = RendererType : : OpenGLES ;
}
}
else if ( BX_ENABLED ( 0
| | BX_PLATFORM_ANDROID
| | BX_PLATFORM_EMSCRIPTEN
| | BX_PLATFORM_IOS
| | BX_PLATFORM_NACL
) )
{
_type = RendererType : : OpenGLES ;
}
else
{
_type = RendererType : : OpenGL ;
}
if ( ! s_rendererCreator [ _type ] . supported )
{
_type = RendererType : : Null ;
}
}
RendererContextI * renderCtx = s_rendererCreator [ _type ] . createFn ( ) ;
if ( NULL = = renderCtx )
{
goto again ;
}
return renderCtx ;
}
void rendererDestroy ( )
{
const RendererType : : Enum type = getRendererType ( ) ;
s_rendererCreator [ type ] . destroyFn ( ) ;
}
2013-10-05 18:07:44 -07:00
void Context : : rendererExecCommands ( CommandBuffer & _cmdbuf )
{
_cmdbuf . reset ( ) ;
bool end = false ;
do
{
uint8_t command ;
_cmdbuf . read ( command ) ;
switch ( command )
{
case CommandBuffer : : RendererInit :
{
BX_CHECK ( ! m_rendererInitialized , " This shouldn't happen! Bad synchronization? " ) ;
2014-05-26 14:09:26 -07:00
RendererType : : Enum type ;
_cmdbuf . read ( type ) ;
m_renderCtx = rendererCreate ( type ) ;
2013-10-05 18:07:44 -07:00
m_rendererInitialized = true ;
}
break ;
case CommandBuffer : : RendererShutdownBegin :
{
BX_CHECK ( m_rendererInitialized , " This shouldn't happen! Bad synchronization? " ) ;
m_rendererInitialized = false ;
}
break ;
case CommandBuffer : : RendererShutdownEnd :
{
BX_CHECK ( ! m_rendererInitialized & & ! m_exit , " This shouldn't happen! Bad synchronization? " ) ;
2014-05-26 14:09:26 -07:00
rendererDestroy ( ) ;
m_renderCtx = NULL ;
2013-10-05 18:07:44 -07:00
m_exit = true ;
}
break ;
case CommandBuffer : : CreateIndexBuffer :
{
IndexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
Memory * mem ;
_cmdbuf . read ( mem ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createIndexBuffer ( handle , mem ) ;
2013-10-05 18:07:44 -07:00
release ( mem ) ;
}
break ;
case CommandBuffer : : DestroyIndexBuffer :
{
IndexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyIndexBuffer ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateVertexDecl :
{
VertexDeclHandle handle ;
_cmdbuf . read ( handle ) ;
VertexDecl decl ;
_cmdbuf . read ( decl ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createVertexDecl ( handle , decl ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : DestroyVertexDecl :
{
VertexDeclHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyVertexDecl ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateVertexBuffer :
{
VertexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
Memory * mem ;
_cmdbuf . read ( mem ) ;
VertexDeclHandle declHandle ;
_cmdbuf . read ( declHandle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createVertexBuffer ( handle , mem , declHandle ) ;
2013-10-05 18:07:44 -07:00
release ( mem ) ;
}
break ;
case CommandBuffer : : DestroyVertexBuffer :
{
VertexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyVertexBuffer ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateDynamicIndexBuffer :
{
IndexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
uint32_t size ;
_cmdbuf . read ( size ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createDynamicIndexBuffer ( handle , size ) ;
2013-10-05 18:07:44 -07:00
}
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 ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateDynamicIndexBuffer ( handle , offset , size , mem ) ;
2013-10-05 18:07:44 -07:00
release ( mem ) ;
}
break ;
case CommandBuffer : : DestroyDynamicIndexBuffer :
{
IndexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyDynamicIndexBuffer ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateDynamicVertexBuffer :
{
VertexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
uint32_t size ;
_cmdbuf . read ( size ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createDynamicVertexBuffer ( handle , size ) ;
2013-10-05 18:07:44 -07:00
}
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 ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateDynamicVertexBuffer ( handle , offset , size , mem ) ;
2013-10-05 18:07:44 -07:00
release ( mem ) ;
}
break ;
case CommandBuffer : : DestroyDynamicVertexBuffer :
{
VertexBufferHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyDynamicVertexBuffer ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
2014-03-29 19:42:57 -07:00
case CommandBuffer : : CreateShader :
2013-10-05 18:07:44 -07:00
{
2014-03-29 19:42:57 -07:00
ShaderHandle handle ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( handle ) ;
Memory * mem ;
_cmdbuf . read ( mem ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createShader ( handle , mem ) ;
2013-10-05 18:07:44 -07:00
release ( mem ) ;
}
break ;
2014-03-29 19:42:57 -07:00
case CommandBuffer : : DestroyShader :
2013-10-05 18:07:44 -07:00
{
2014-03-29 19:42:57 -07:00
ShaderHandle handle ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyShader ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateProgram :
{
ProgramHandle handle ;
_cmdbuf . read ( handle ) ;
2014-03-29 19:42:57 -07:00
ShaderHandle vsh ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( vsh ) ;
2014-03-29 19:42:57 -07:00
ShaderHandle fsh ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( fsh ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createProgram ( handle , vsh , fsh ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : DestroyProgram :
{
2014-03-27 22:36:53 -07:00
ProgramHandle handle ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyProgram ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateTexture :
{
TextureHandle handle ;
_cmdbuf . read ( handle ) ;
Memory * mem ;
_cmdbuf . read ( mem ) ;
uint32_t flags ;
_cmdbuf . read ( flags ) ;
2014-02-19 22:34:53 -08:00
uint8_t skip ;
_cmdbuf . read ( skip ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createTexture ( handle , mem , flags , skip ) ;
2013-10-05 18:07:44 -07:00
bx : : MemoryReader reader ( mem - > data , mem - > size ) ;
uint32_t magic ;
bx : : read ( & reader , magic ) ;
if ( BGFX_CHUNK_MAGIC_TEX = = magic )
{
TextureCreate tc ;
bx : : read ( & reader , tc ) ;
if ( NULL ! = tc . m_mem )
{
release ( tc . m_mem ) ;
}
}
release ( mem ) ;
}
break ;
case CommandBuffer : : UpdateTexture :
{
if ( m_textureUpdateBatch . isFull ( ) )
{
flushTextureUpdateBatch ( _cmdbuf ) ;
}
uint32_t value = _cmdbuf . m_pos ;
TextureHandle handle ;
_cmdbuf . read ( handle ) ;
uint8_t side ;
_cmdbuf . read ( side ) ;
uint8_t mip ;
_cmdbuf . read ( mip ) ;
2014-02-05 23:07:11 -08:00
_cmdbuf . skip < Rect > ( ) ;
_cmdbuf . skip < uint16_t > ( ) ;
_cmdbuf . skip < uint16_t > ( ) ;
_cmdbuf . skip < uint16_t > ( ) ;
_cmdbuf . skip < Memory * > ( ) ;
2013-10-05 18:07:44 -07:00
uint32_t key = ( handle . idx < < 16 )
| ( side < < 8 )
| mip
;
m_textureUpdateBatch . add ( key , value ) ;
}
break ;
case CommandBuffer : : DestroyTexture :
{
TextureHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyTexture ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
2014-02-05 23:07:11 -08:00
case CommandBuffer : : CreateFrameBuffer :
2013-10-05 18:07:44 -07:00
{
2014-02-05 23:07:11 -08:00
FrameBufferHandle handle ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( handle ) ;
2014-02-05 23:07:11 -08:00
uint8_t num ;
_cmdbuf . read ( num ) ;
2013-10-05 18:07:44 -07:00
2014-02-05 23:07:11 -08:00
TextureHandle textureHandles [ BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ] ;
for ( uint32_t ii = 0 ; ii < num ; + + ii )
{
_cmdbuf . read ( textureHandles [ ii ] ) ;
}
2013-10-05 18:07:44 -07:00
2014-05-26 14:09:26 -07:00
m_renderCtx - > createFrameBuffer ( handle , num , textureHandles ) ;
2013-10-05 18:07:44 -07:00
}
break ;
2014-02-05 23:07:11 -08:00
case CommandBuffer : : DestroyFrameBuffer :
2013-10-05 18:07:44 -07:00
{
2014-02-05 23:07:11 -08:00
FrameBufferHandle handle ;
2013-10-05 18:07:44 -07:00
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyFrameBuffer ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : CreateUniform :
{
UniformHandle handle ;
_cmdbuf . read ( handle ) ;
UniformType : : Enum type ;
_cmdbuf . read ( type ) ;
uint16_t num ;
_cmdbuf . read ( num ) ;
uint8_t len ;
_cmdbuf . read ( len ) ;
const char * name = ( const char * ) _cmdbuf . skip ( len ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > createUniform ( handle , type , num , name ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : DestroyUniform :
{
UniformHandle handle ;
_cmdbuf . read ( handle ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > destroyUniform ( handle ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : SaveScreenShot :
{
uint16_t len ;
_cmdbuf . read ( len ) ;
const char * filePath = ( const char * ) _cmdbuf . skip ( len ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > saveScreenShot ( filePath ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : UpdateViewName :
{
uint8_t id ;
_cmdbuf . read ( id ) ;
uint16_t len ;
_cmdbuf . read ( len ) ;
const char * name = ( const char * ) _cmdbuf . skip ( len ) ;
2014-05-26 14:09:26 -07:00
m_renderCtx - > updateViewName ( id , name ) ;
2013-10-05 18:07:44 -07:00
}
break ;
case CommandBuffer : : End :
end = true ;
break ;
default :
2014-02-05 23:07:11 -08:00
BX_CHECK ( false , " Invalid command: %d " , command ) ;
2013-10-05 18:07:44 -07:00
break ;
}
} while ( ! end ) ;
flushTextureUpdateBatch ( _cmdbuf ) ;
}
2014-05-26 14:09:26 -07:00
uint8_t getSupportedRenderers ( RendererType : : Enum _enum [ RendererType : : Count ] )
{
uint8_t num = 0 ;
for ( uint8_t ii = 0 ; ii < uint8_t ( RendererType : : Count ) ; + + ii )
{
if ( s_rendererCreator [ ii ] . supported )
{
_enum [ num + + ] = RendererType : : Enum ( ii ) ;
}
}
return num ;
}
2014-05-27 20:05:13 -07:00
const char * getRendererName ( RendererType : : Enum _type )
{
BX_CHECK ( _type < RendererType : : Count , " Invalid renderer type %d. " , _type ) ;
return s_rendererCreator [ _type ] . name ;
}
2014-05-26 14:09:26 -07:00
void init ( RendererType : : Enum _type , CallbackI * _callback , bx : : ReallocatorI * _allocator )
{
BX_TRACE ( " Init... " ) ;
memset ( & g_caps , 0 , sizeof ( g_caps ) ) ;
g_caps . supported = 0
| ( BGFX_CONFIG_MULTITHREADED ? BGFX_CAPS_RENDERER_MULTITHREADED : 0 )
;
g_caps . emulated = 0 ;
g_caps . maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS ;
g_caps . maxFBAttachments = 1 ;
if ( NULL ! = _allocator )
{
g_allocator = _allocator ;
}
else
{
bx : : CrtAllocator allocator ;
g_allocator =
s_allocatorStub = BX_NEW ( & allocator , AllocatorStub ) ;
}
if ( NULL ! = _callback )
{
g_callback = _callback ;
}
else
{
g_callback =
s_callbackStub = BX_NEW ( g_allocator , CallbackStub ) ;
}
s_threadIndex = BGFX_MAIN_THREAD_MAGIC ;
s_ctx = BX_ALIGNED_NEW ( g_allocator , Context , 16 ) ;
s_ctx - > init ( _type ) ;
BX_TRACE ( " Init complete. " ) ;
}
void shutdown ( )
{
BX_TRACE ( " Shutdown... " ) ;
BGFX_CHECK_MAIN_THREAD ( ) ;
Context * ctx = s_ctx ; // it's going to be NULLd inside shutdown.
ctx - > shutdown ( ) ;
BX_ALIGNED_DELETE ( g_allocator , ctx , 16 ) ;
if ( NULL ! = s_callbackStub )
{
BX_DELETE ( g_allocator , s_callbackStub ) ;
s_callbackStub = NULL ;
}
if ( NULL ! = s_allocatorStub )
{
s_allocatorStub - > checkLeaks ( ) ;
bx : : CrtAllocator allocator ;
BX_DELETE ( & allocator , s_allocatorStub ) ;
s_allocatorStub = NULL ;
}
s_threadIndex = 0 ;
g_callback = NULL ;
g_allocator = NULL ;
BX_TRACE ( " Shutdown complete. " ) ;
}
void reset ( uint32_t _width , uint32_t _height , uint32_t _flags )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
s_ctx - > reset ( _width , _height , _flags ) ;
}
uint32_t frame ( )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
return s_ctx - > frame ( ) ;
}
const Caps * getCaps ( )
{
return & g_caps ;
}
RendererType : : Enum getRendererType ( )
{
return g_caps . rendererType ;
}
2012-06-29 20:10:10 -07:00
const Memory * alloc ( uint32_t _size )
{
2013-09-16 21:40:30 -07:00
Memory * mem = ( Memory * ) BX_ALLOC ( g_allocator , sizeof ( Memory ) + _size ) ;
2012-06-29 20:10:10 -07:00
mem - > size = _size ;
mem - > data = ( uint8_t * ) mem + sizeof ( Memory ) ;
return mem ;
}
2014-04-16 22:24:31 -07:00
const Memory * copy ( const void * _data , uint32_t _size )
{
const Memory * mem = alloc ( _size ) ;
memcpy ( mem - > data , _data , _size ) ;
return mem ;
}
2012-09-16 17:36:08 -07:00
const Memory * makeRef ( const void * _data , uint32_t _size )
2012-06-29 20:10:10 -07:00
{
2013-09-16 21:40:30 -07:00
Memory * mem = ( Memory * ) BX_ALLOC ( g_allocator , sizeof ( Memory ) ) ;
2012-06-29 20:10:10 -07:00
mem - > size = _size ;
mem - > data = ( uint8_t * ) _data ;
return mem ;
}
2012-07-22 21:08:58 -07:00
void release ( const Memory * _mem )
2012-06-29 20:10:10 -07:00
{
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-09-16 21:40:30 -07:00
BX_FREE ( g_allocator , const_cast < Memory * > ( _mem ) ) ;
2012-06-29 20:10:10 -07:00
}
void setDebug ( uint32_t _debug )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setDebug ( _debug ) ;
2012-06-29 20:10:10 -07:00
}
void dbgTextClear ( uint8_t _attr , bool _small )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > dbgTextClear ( _attr , _small ) ;
2012-06-29 20:10:10 -07:00
}
void dbgTextPrintf ( uint16_t _x , uint16_t _y , uint8_t _attr , const char * _format , . . . )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-06-29 20:10:10 -07:00
va_list argList ;
va_start ( argList , _format ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > dbgTextPrintfVargs ( _x , _y , _attr , _format , argList ) ;
2012-06-29 20:10:10 -07:00
va_end ( argList ) ;
}
IndexBufferHandle createIndexBuffer ( const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createIndexBuffer ( _mem ) ;
2012-06-29 20:10:10 -07:00
}
void destroyIndexBuffer ( IndexBufferHandle _handle )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyIndexBuffer ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
VertexBufferHandle createVertexBuffer ( const Memory * _mem , const VertexDecl & _decl )
{
2013-08-27 22:02:43 -07:00
BGFX_CHECK_MAIN_THREAD ( ) ;
BX_CHECK ( 0 ! = _decl . m_stride , " Invalid VertexDecl. " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createVertexBuffer ( _mem , _decl ) ;
2012-06-29 20:10:10 -07:00
}
void destroyVertexBuffer ( VertexBufferHandle _handle )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyVertexBuffer ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2013-10-21 22:04:41 -07:00
DynamicIndexBufferHandle createDynamicIndexBuffer ( uint32_t _num )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createDynamicIndexBuffer ( _num ) ;
2012-06-29 20:10:10 -07:00
}
DynamicIndexBufferHandle createDynamicIndexBuffer ( const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createDynamicIndexBuffer ( _mem ) ;
2012-06-29 20:10:10 -07:00
}
void updateDynamicIndexBuffer ( DynamicIndexBufferHandle _handle , const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > updateDynamicIndexBuffer ( _handle , _mem ) ;
2012-06-29 20:10:10 -07:00
}
void destroyDynamicIndexBuffer ( DynamicIndexBufferHandle _handle )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyDynamicIndexBuffer ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
DynamicVertexBufferHandle createDynamicVertexBuffer ( uint16_t _num , const VertexDecl & _decl )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-08-27 22:02:43 -07:00
BX_CHECK ( 0 ! = _decl . m_stride , " Invalid VertexDecl. " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createDynamicVertexBuffer ( _num , _decl ) ;
2012-06-29 20:10:10 -07:00
}
DynamicVertexBufferHandle createDynamicVertexBuffer ( const Memory * _mem , const VertexDecl & _decl )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-08-27 22:02:43 -07:00
BX_CHECK ( 0 ! = _decl . m_stride , " Invalid VertexDecl. " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createDynamicVertexBuffer ( _mem , _decl ) ;
2012-06-29 20:10:10 -07:00
}
void updateDynamicVertexBuffer ( DynamicVertexBufferHandle _handle , const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > updateDynamicVertexBuffer ( _handle , _mem ) ;
2012-06-29 20:10:10 -07:00
}
void destroyDynamicVertexBuffer ( DynamicVertexBufferHandle _handle )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyDynamicVertexBuffer ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2013-05-02 22:16:33 -07:00
bool checkAvailTransientIndexBuffer ( uint32_t _num )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-04-21 23:16:34 -07:00
BX_CHECK ( 0 < _num , " Requesting 0 indices. " ) ;
2013-10-04 23:45:05 -07:00
return s_ctx - > checkAvailTransientIndexBuffer ( _num ) ;
2012-06-29 20:10:10 -07:00
}
2013-05-02 22:16:33 -07:00
bool checkAvailTransientVertexBuffer ( uint32_t _num , const VertexDecl & _decl )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-05-01 20:35:43 -07:00
BX_CHECK ( 0 < _num , " Requesting 0 vertices. " ) ;
2013-08-27 22:02:43 -07:00
BX_CHECK ( 0 ! = _decl . m_stride , " Invalid VertexDecl. " ) ;
2013-10-04 23:45:05 -07:00
return s_ctx - > checkAvailTransientVertexBuffer ( _num , _decl . m_stride ) ;
2012-06-29 20:10:10 -07:00
}
2013-06-03 20:51:06 -07:00
bool checkAvailInstanceDataBuffer ( uint32_t _num , uint16_t _stride )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
BX_CHECK ( 0 < _num , " Requesting 0 instances. " ) ;
2013-10-04 23:45:05 -07:00
return s_ctx - > checkAvailTransientVertexBuffer ( _num , _stride ) ;
2013-06-03 20:51:06 -07:00
}
2013-05-02 22:16:33 -07:00
bool checkAvailTransientBuffers ( uint32_t _numVertices , const VertexDecl & _decl , uint32_t _numIndices )
2013-05-01 20:35:43 -07:00
{
2013-08-27 22:02:43 -07:00
BX_CHECK ( 0 ! = _decl . m_stride , " Invalid VertexDecl. " ) ;
2013-05-01 20:35:43 -07:00
return checkAvailTransientVertexBuffer ( _numVertices , _decl )
& & checkAvailTransientIndexBuffer ( _numIndices )
;
}
2013-05-02 22:16:33 -07:00
void allocTransientIndexBuffer ( TransientIndexBuffer * _tib , uint32_t _num )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-05-01 20:35:43 -07:00
BX_CHECK ( NULL ! = _tib , " _tib can't be NULL " ) ;
BX_CHECK ( 0 < _num , " Requesting 0 indices. " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > allocTransientIndexBuffer ( _tib , _num ) ;
2012-06-29 20:10:10 -07:00
}
2013-05-02 22:16:33 -07:00
void allocTransientVertexBuffer ( TransientVertexBuffer * _tvb , uint32_t _num , const VertexDecl & _decl )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-11-10 19:59:23 -08:00
BX_CHECK ( NULL ! = _tvb , " _tvb can't be NULL " ) ;
2013-04-21 23:16:34 -07:00
BX_CHECK ( 0 < _num , " Requesting 0 vertices. " ) ;
2013-05-02 22:16:33 -07:00
BX_CHECK ( UINT16_MAX > = _num , " Requesting %d vertices (max: %d). " , _num , UINT16_MAX ) ;
2013-08-27 22:02:43 -07:00
BX_CHECK ( 0 ! = _decl . m_stride , " Invalid VertexDecl. " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > allocTransientVertexBuffer ( _tvb , _num , _decl ) ;
2012-06-29 20:10:10 -07:00
}
2014-05-19 22:08:35 -07:00
bool allocTransientBuffers ( bgfx : : TransientVertexBuffer * _tvb , const bgfx : : VertexDecl & _decl , uint16_t _numVertices , bgfx : : TransientIndexBuffer * _tib , uint16_t _numIndices )
{
if ( checkAvailTransientBuffers ( _numVertices , _decl , _numIndices ) )
{
allocTransientVertexBuffer ( _tvb , _numVertices , _decl ) ;
allocTransientIndexBuffer ( _tib , _numIndices ) ;
return true ;
}
return false ;
}
2013-05-02 22:16:33 -07:00
const InstanceDataBuffer * allocInstanceDataBuffer ( uint32_t _num , uint16_t _stride )
2012-07-07 23:22:52 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-10 18:29:57 -07:00
BX_CHECK ( 0 ! = ( g_caps . supported & BGFX_CAPS_INSTANCING ) , " Instancing is not supported! Use bgfx::getCaps to check backend renderer capabilities. " ) ;
2013-04-21 23:16:34 -07:00
BX_CHECK ( 0 < _num , " Requesting 0 instanced data vertices. " ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > allocInstanceDataBuffer ( _num , _stride ) ;
2012-07-07 23:22:52 -07:00
}
2014-03-29 19:42:57 -07:00
ShaderHandle createShader ( const Memory * _mem )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2014-03-29 19:42:57 -07:00
return s_ctx - > createShader ( _mem ) ;
2012-06-29 20:10:10 -07:00
}
2014-04-15 19:10:56 -07:00
uint16_t getShaderUniforms ( ShaderHandle _handle , UniformHandle * _uniforms , uint16_t _max )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
return s_ctx - > getShaderUniforms ( _handle , _uniforms , _max ) ;
}
2014-03-29 19:42:57 -07:00
void destroyShader ( ShaderHandle _handle )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-03-29 19:42:57 -07:00
s_ctx - > destroyShader ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2014-03-29 19:42:57 -07:00
ProgramHandle createProgram ( ShaderHandle _vsh , ShaderHandle _fsh , bool _destroyShaders )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-02-06 20:03:26 -08:00
ProgramHandle handle = s_ctx - > createProgram ( _vsh , _fsh ) ;
if ( _destroyShaders )
{
2014-03-29 19:42:57 -07:00
destroyShader ( _vsh ) ;
destroyShader ( _fsh ) ;
2014-02-06 20:03:26 -08:00
}
return handle ;
2012-06-29 20:10:10 -07:00
}
2012-09-16 17:36:08 -07:00
void destroyProgram ( ProgramHandle _handle )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyProgram ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2013-01-05 14:33:05 -08:00
void calcTextureSize ( TextureInfo & _info , uint16_t _width , uint16_t _height , uint16_t _depth , uint8_t _numMips , TextureFormat : : Enum _format )
2013-01-04 23:52:37 -08:00
{
2013-08-03 22:15:13 -07:00
_width = bx : : uint32_max ( 1 , _width ) ;
_height = bx : : uint32_max ( 1 , _height ) ;
_depth = bx : : uint32_max ( 1 , _depth ) ;
2013-01-06 17:53:45 -08:00
2014-02-05 23:07:11 -08:00
uint32_t width = _width ;
2013-01-04 23:52:37 -08:00
uint32_t height = _height ;
2014-02-05 23:07:11 -08:00
uint32_t depth = _depth ;
2013-01-05 14:33:05 -08:00
2013-09-04 21:42:31 -07:00
uint32_t bpp = getBitsPerPixel ( _format ) ;
2013-01-04 23:52:37 -08:00
uint32_t size = 0 ;
for ( uint32_t lod = 0 ; lod < _numMips ; + + lod )
{
2013-08-03 22:15:13 -07:00
width = bx : : uint32_max ( 1 , width ) ;
height = bx : : uint32_max ( 1 , height ) ;
depth = bx : : uint32_max ( 1 , depth ) ;
2013-01-04 23:52:37 -08:00
2014-05-24 20:16:40 +01:00
size + = width * height * depth * bpp / 8 ;
2013-01-04 23:52:37 -08:00
width > > = 1 ;
height > > = 1 ;
depth > > = 1 ;
}
2013-01-05 14:33:05 -08:00
_info . format = _format ;
_info . storageSize = size ;
_info . width = _width ;
_info . height = _height ;
_info . depth = _depth ;
_info . numMips = _numMips ;
_info . bitsPerPixel = bpp ;
2013-01-04 23:52:37 -08:00
}
2014-02-19 22:34:53 -08:00
TextureHandle createTexture ( const Memory * _mem , uint32_t _flags , uint8_t _skip , TextureInfo * _info )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2014-02-19 22:34:53 -08:00
return s_ctx - > createTexture ( _mem , _flags , _skip , _info ) ;
2012-06-29 20:10:10 -07:00
}
2012-08-12 21:02:11 -07:00
TextureHandle createTexture2D ( uint16_t _width , uint16_t _height , uint8_t _numMips , TextureFormat : : Enum _format , uint32_t _flags , const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-01-06 12:39:18 -08:00
2014-02-05 23:07:11 -08:00
_numMips = bx : : uint32_max ( 1 , _numMips ) ;
2014-03-31 20:08:32 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG )
& & NULL ! = _mem )
2013-01-06 12:39:18 -08:00
{
TextureInfo ti ;
calcTextureSize ( ti , _width , _height , 1 , _numMips , _format ) ;
BX_CHECK ( ti . storageSize = = _mem - > size
, " createTexture2D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d) "
, ti . storageSize
, _mem - > size
) ;
}
2012-11-03 21:36:17 -07:00
uint32_t size = sizeof ( uint32_t ) + sizeof ( TextureCreate ) ;
2013-01-04 23:52:37 -08:00
const Memory * mem = alloc ( size ) ;
2012-08-12 21:02:11 -07:00
2012-11-25 18:24:50 -08:00
bx : : StaticMemoryBlockWriter writer ( mem - > data , mem - > size ) ;
uint32_t magic = BGFX_CHUNK_MAGIC_TEX ;
bx : : write ( & writer , magic ) ;
2012-08-12 21:02:11 -07:00
2012-11-03 21:36:17 -07:00
TextureCreate tc ;
tc . m_flags = _flags ;
tc . m_width = _width ;
tc . m_height = _height ;
2013-01-06 17:53:45 -08:00
tc . m_sides = 0 ;
2012-11-03 21:36:17 -07:00
tc . m_depth = 0 ;
tc . m_numMips = _numMips ;
2012-11-25 18:24:50 -08:00
tc . m_format = uint8_t ( _format ) ;
2012-11-03 21:36:17 -07:00
tc . m_cubeMap = false ;
tc . m_mem = _mem ;
2012-11-25 18:24:50 -08:00
bx : : write ( & writer , tc ) ;
2012-08-12 21:02:11 -07:00
2014-02-19 23:04:19 -08:00
return s_ctx - > createTexture ( mem , _flags , 0 , NULL ) ;
2012-08-12 21:02:11 -07:00
}
TextureHandle createTexture3D ( uint16_t _width , uint16_t _height , uint16_t _depth , uint8_t _numMips , TextureFormat : : Enum _format , uint32_t _flags , const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-10 18:29:57 -07:00
BX_CHECK ( 0 ! = ( g_caps . supported & BGFX_CAPS_TEXTURE_3D ) , " Texture3D is not supported! Use bgfx::getCaps to check backend renderer capabilities. " ) ;
2013-01-06 12:39:18 -08:00
2014-02-05 23:07:11 -08:00
_numMips = bx : : uint32_max ( 1 , _numMips ) ;
2014-03-31 20:08:32 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG )
& & NULL ! = _mem )
2013-01-06 12:39:18 -08:00
{
TextureInfo ti ;
calcTextureSize ( ti , _width , _height , _depth , _numMips , _format ) ;
BX_CHECK ( ti . storageSize = = _mem - > size
, " createTexture3D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d) "
, ti . storageSize
, _mem - > size
) ;
}
2012-11-03 21:36:17 -07:00
uint32_t size = sizeof ( uint32_t ) + sizeof ( TextureCreate ) ;
2013-01-04 23:52:37 -08:00
const Memory * mem = alloc ( size ) ;
2012-08-12 21:02:11 -07:00
2012-11-25 18:24:50 -08:00
bx : : StaticMemoryBlockWriter writer ( mem - > data , mem - > size ) ;
uint32_t magic = BGFX_CHUNK_MAGIC_TEX ;
bx : : write ( & writer , magic ) ;
2012-08-12 21:02:11 -07:00
2012-11-03 21:36:17 -07:00
TextureCreate tc ;
tc . m_flags = _flags ;
tc . m_width = _width ;
tc . m_height = _height ;
2013-01-06 17:53:45 -08:00
tc . m_sides = 0 ;
2012-11-03 21:36:17 -07:00
tc . m_depth = _depth ;
tc . m_numMips = _numMips ;
2012-11-25 18:24:50 -08:00
tc . m_format = uint8_t ( _format ) ;
2012-11-03 21:36:17 -07:00
tc . m_cubeMap = false ;
tc . m_mem = _mem ;
2012-11-25 18:24:50 -08:00
bx : : write ( & writer , tc ) ;
2012-08-12 21:02:11 -07:00
2014-02-19 23:04:19 -08:00
return s_ctx - > createTexture ( mem , _flags , 0 , NULL ) ;
2012-08-12 21:02:11 -07:00
}
2013-01-13 15:35:06 -08:00
2013-11-07 22:59:17 -08:00
TextureHandle createTextureCube ( uint16_t _size , uint8_t _numMips , TextureFormat : : Enum _format , uint32_t _flags , const Memory * _mem )
2012-08-12 21:02:11 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-01-06 12:39:18 -08:00
2014-02-05 23:07:11 -08:00
_numMips = bx : : uint32_max ( 1 , _numMips ) ;
2014-03-31 20:08:32 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG )
& & NULL ! = _mem )
2013-01-06 12:39:18 -08:00
{
TextureInfo ti ;
2013-11-07 22:59:17 -08:00
calcTextureSize ( ti , _size , _size , 1 , _numMips , _format ) ;
2013-11-08 22:10:31 -08:00
BX_CHECK ( ti . storageSize * 6 = = _mem - > size
2013-01-06 12:39:18 -08:00
, " createTextureCube: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d) "
2013-11-08 22:10:31 -08:00
, ti . storageSize * 6
2013-01-06 12:39:18 -08:00
, _mem - > size
) ;
}
2012-11-03 21:36:17 -07:00
uint32_t size = sizeof ( uint32_t ) + sizeof ( TextureCreate ) ;
2013-01-04 23:52:37 -08:00
const Memory * mem = alloc ( size ) ;
2012-08-12 21:02:11 -07:00
2012-11-25 18:24:50 -08:00
bx : : StaticMemoryBlockWriter writer ( mem - > data , mem - > size ) ;
uint32_t magic = BGFX_CHUNK_MAGIC_TEX ;
bx : : write ( & writer , magic ) ;
2012-08-12 21:02:11 -07:00
2012-11-03 21:36:17 -07:00
TextureCreate tc ;
tc . m_flags = _flags ;
2013-11-07 22:59:17 -08:00
tc . m_width = _size ;
tc . m_height = _size ;
tc . m_sides = 6 ;
2012-11-03 21:36:17 -07:00
tc . m_depth = 0 ;
tc . m_numMips = _numMips ;
2012-11-25 18:24:50 -08:00
tc . m_format = uint8_t ( _format ) ;
2012-11-03 21:36:17 -07:00
tc . m_cubeMap = true ;
tc . m_mem = _mem ;
2012-11-25 18:24:50 -08:00
bx : : write ( & writer , tc ) ;
2012-11-03 21:36:17 -07:00
2014-02-19 23:04:19 -08:00
return s_ctx - > createTexture ( mem , _flags , 0 , NULL ) ;
2012-08-12 21:02:11 -07:00
}
2012-06-29 20:10:10 -07:00
void destroyTexture ( TextureHandle _handle )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyTexture ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2013-11-07 22:59:17 -08:00
void updateTexture2D ( TextureHandle _handle , uint8_t _mip , uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height , const Memory * _mem , uint16_t _pitch )
2013-01-13 15:35:06 -08:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-01-13 15:35:06 -08:00
if ( _width = = 0
| | _height = = 0 )
{
release ( _mem ) ;
}
else
{
2013-11-07 22:59:17 -08:00
s_ctx - > updateTexture ( _handle , 0 , _mip , _x , _y , 0 , _width , _height , 1 , _pitch , _mem ) ;
2013-01-13 15:35:06 -08:00
}
}
void updateTexture3D ( TextureHandle _handle , uint8_t _mip , uint16_t _x , uint16_t _y , uint16_t _z , uint16_t _width , uint16_t _height , uint16_t _depth , const Memory * _mem )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-01-13 15:35:06 -08:00
if ( _width = = 0
| | _height = = 0
| | _depth = = 0 )
{
release ( _mem ) ;
}
else
{
2013-11-07 22:59:17 -08:00
s_ctx - > updateTexture ( _handle , 0 , _mip , _x , _y , _z , _width , _height , _depth , UINT16_MAX , _mem ) ;
2013-01-13 15:35:06 -08:00
}
}
2013-11-07 22:59:17 -08:00
void updateTextureCube ( TextureHandle _handle , uint8_t _side , uint8_t _mip , uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height , const Memory * _mem , uint16_t _pitch )
2013-01-13 15:35:06 -08:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-10-07 20:41:18 -07:00
BX_CHECK ( NULL ! = _mem , " _mem can't be NULL " ) ;
2013-07-15 21:48:55 -07:00
BX_CHECK ( _side < = 5 , " Invalid side %d. " , _side ) ;
2013-01-13 15:35:06 -08:00
if ( _width = = 0
| | _height = = 0 )
{
release ( _mem ) ;
}
else
{
2013-11-07 22:59:17 -08:00
s_ctx - > updateTexture ( _handle , _side , _mip , _x , _y , 0 , _width , _height , 1 , _pitch , _mem ) ;
2013-01-13 15:35:06 -08:00
}
}
2012-08-12 21:02:11 -07:00
2014-02-05 23:07:11 -08:00
FrameBufferHandle createFrameBuffer ( uint16_t _width , uint16_t _height , TextureFormat : : Enum _format , uint32_t _textureFlags )
{
_textureFlags | = _textureFlags & BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT ;
TextureHandle th = createTexture2D ( _width , _height , 1 , _format , _textureFlags ) ;
return createFrameBuffer ( 1 , & th , true ) ;
}
FrameBufferHandle createFrameBuffer ( uint8_t _num , TextureHandle * _handles , bool _destroyTextures )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-02-05 23:07:11 -08:00
BX_CHECK ( NULL ! = _handles , " _handles can't be NULL " ) ;
FrameBufferHandle handle = s_ctx - > createFrameBuffer ( _num , _handles ) ;
if ( _destroyTextures )
{
for ( uint32_t ii = 0 ; ii < _num ; + + ii )
{
destroyTexture ( _handles [ ii ] ) ;
}
}
return handle ;
2012-06-29 20:10:10 -07:00
}
2014-02-05 23:07:11 -08:00
void destroyFrameBuffer ( FrameBufferHandle _handle )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-02-05 23:07:11 -08:00
s_ctx - > destroyFrameBuffer ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2012-10-27 21:34:41 -07:00
UniformHandle createUniform ( const char * _name , UniformType : : Enum _type , uint16_t _num )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
return s_ctx - > createUniform ( _name , _type , _num ) ;
2012-06-29 20:10:10 -07:00
}
void destroyUniform ( UniformHandle _handle )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > destroyUniform ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2013-06-09 15:28:25 -07:00
void setViewName ( uint8_t _id , const char * _name )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewName ( _id , _name ) ;
2013-06-09 15:28:25 -07:00
}
2012-06-29 20:10:10 -07:00
void setViewRect ( uint8_t _id , uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewRect ( _id , _x , _y , _width , _height ) ;
2012-06-29 20:10:10 -07:00
}
void setViewRectMask ( uint32_t _viewMask , uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewRectMask ( _viewMask , _x , _y , _width , _height ) ;
2012-06-29 20:10:10 -07:00
}
2013-07-14 14:32:09 -07:00
void setViewScissor ( uint8_t _id , uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewScissor ( _id , _x , _y , _width , _height ) ;
2013-07-14 14:32:09 -07:00
}
void setViewScissorMask ( uint32_t _viewMask , uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewScissorMask ( _viewMask , _x , _y , _width , _height ) ;
2013-07-14 14:32:09 -07:00
}
2012-06-29 20:10:10 -07:00
void setViewClear ( uint8_t _id , uint8_t _flags , uint32_t _rgba , float _depth , uint8_t _stencil )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewClear ( _id , _flags , _rgba , _depth , _stencil ) ;
2012-06-29 20:10:10 -07:00
}
void setViewClearMask ( uint32_t _viewMask , uint8_t _flags , uint32_t _rgba , float _depth , uint8_t _stencil )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewClearMask ( _viewMask , _flags , _rgba , _depth , _stencil ) ;
2012-06-29 20:10:10 -07:00
}
void setViewSeq ( uint8_t _id , bool _enabled )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewSeq ( _id , _enabled ) ;
2012-06-29 20:10:10 -07:00
}
void setViewSeqMask ( uint32_t _viewMask , bool _enabled )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewSeqMask ( _viewMask , _enabled ) ;
2012-06-29 20:10:10 -07:00
}
2014-02-05 23:07:11 -08:00
void setViewFrameBuffer ( uint8_t _id , FrameBufferHandle _handle )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-02-05 23:07:11 -08:00
s_ctx - > setViewFrameBuffer ( _id , _handle ) ;
2012-06-29 20:10:10 -07:00
}
2014-02-05 23:07:11 -08:00
void setViewFrameBufferMask ( uint32_t _mask , FrameBufferHandle _handle )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-02-05 23:07:11 -08:00
s_ctx - > setViewFrameBufferMask ( _mask , _handle ) ;
2012-06-29 20:10:10 -07:00
}
void setViewTransform ( uint8_t _id , const void * _view , const void * _proj , uint8_t _other )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewTransform ( _id , _view , _proj , _other ) ;
2012-06-29 20:10:10 -07:00
}
void setViewTransformMask ( uint32_t _viewMask , const void * _view , const void * _proj , uint8_t _other )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setViewTransformMask ( _viewMask , _view , _proj , _other ) ;
2012-06-29 20:10:10 -07:00
}
2013-06-10 22:41:03 -07:00
void setMarker ( const char * _marker )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setMarker ( _marker ) ;
2013-06-10 22:41:03 -07:00
}
2013-03-29 22:58:50 -07:00
void setState ( uint64_t _state , uint32_t _rgba )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setState ( _state , _rgba ) ;
2012-06-29 20:10:10 -07:00
}
2012-11-10 19:59:23 -08:00
void setStencil ( uint32_t _fstencil , uint32_t _bstencil )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setStencil ( _fstencil , _bstencil ) ;
2012-11-10 19:59:23 -08:00
}
2013-07-14 14:32:09 -07:00
uint16_t setScissor ( uint16_t _x , uint16_t _y , uint16_t _width , uint16_t _height )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
return s_ctx - > setScissor ( _x , _y , _width , _height ) ;
2013-07-14 14:32:09 -07:00
}
void setScissor ( uint16_t _cache )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setScissor ( _cache ) ;
2013-07-14 14:32:09 -07:00
}
2012-06-29 20:10:10 -07:00
uint32_t setTransform ( const void * _mtx , uint16_t _num )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
return s_ctx - > setTransform ( _mtx , _num ) ;
2012-06-29 20:10:10 -07:00
}
void setTransform ( uint32_t _cache , uint16_t _num )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setTransform ( _cache , _num ) ;
2012-06-29 20:10:10 -07:00
}
void setUniform ( UniformHandle _handle , const void * _value , uint16_t _num )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > setUniform ( _handle , _value , _num ) ;
2012-06-29 20:10:10 -07:00
}
void setIndexBuffer ( IndexBufferHandle _handle , uint32_t _firstIndex , uint32_t _numIndices )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setIndexBuffer ( _handle , _firstIndex , _numIndices ) ;
2012-06-29 20:10:10 -07:00
}
void setIndexBuffer ( DynamicIndexBufferHandle _handle , uint32_t _firstIndex , uint32_t _numIndices )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setIndexBuffer ( _handle , _firstIndex , _numIndices ) ;
2012-06-29 20:10:10 -07:00
}
2014-04-26 23:48:41 -07:00
void setIndexBuffer ( const TransientIndexBuffer * _tib )
{
setIndexBuffer ( _tib , 0 , UINT32_MAX ) ;
}
void setIndexBuffer ( const TransientIndexBuffer * _tib , uint32_t _firstIndex , uint32_t _numIndices )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-11-10 19:59:23 -08:00
BX_CHECK ( NULL ! = _tib , " _tib can't be NULL " ) ;
2013-08-03 22:15:13 -07:00
uint32_t numIndices = bx : : uint32_min ( _numIndices , _tib - > size / 2 ) ;
2014-04-26 23:48:41 -07:00
s_ctx - > setIndexBuffer ( _tib , _tib - > startIndex + _firstIndex , numIndices ) ;
2012-06-29 20:10:10 -07:00
}
2014-04-16 22:11:14 -07:00
void setVertexBuffer ( VertexBufferHandle _handle )
{
setVertexBuffer ( _handle , 0 , UINT32_MAX ) ;
}
2014-04-10 22:09:17 -07:00
void setVertexBuffer ( VertexBufferHandle _handle , uint32_t _startVertex , uint32_t _numVertices )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-04-10 22:09:17 -07:00
s_ctx - > setVertexBuffer ( _handle , _startVertex , _numVertices ) ;
2012-06-29 20:10:10 -07:00
}
2012-09-16 17:36:08 -07:00
void setVertexBuffer ( DynamicVertexBufferHandle _handle , uint32_t _numVertices )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setVertexBuffer ( _handle , _numVertices ) ;
2012-06-29 20:10:10 -07:00
}
2014-04-26 23:48:41 -07:00
void setVertexBuffer ( const TransientVertexBuffer * _tvb )
{
setVertexBuffer ( _tvb , 0 , UINT32_MAX ) ;
}
void setVertexBuffer ( const TransientVertexBuffer * _tvb , uint32_t _startVertex , uint32_t _numVertices )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2012-11-10 19:59:23 -08:00
BX_CHECK ( NULL ! = _tvb , " _tvb can't be NULL " ) ;
2014-04-26 23:48:41 -07:00
s_ctx - > setVertexBuffer ( _tvb , _tvb - > startVertex + _startVertex , _numVertices ) ;
2012-06-29 20:10:10 -07:00
}
2012-10-27 21:34:41 -07:00
void setInstanceDataBuffer ( const InstanceDataBuffer * _idb , uint16_t _num )
2012-07-07 23:22:52 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setInstanceDataBuffer ( _idb , _num ) ;
2012-07-07 23:22:52 -07:00
}
2012-09-16 17:36:08 -07:00
void setProgram ( ProgramHandle _handle )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setProgram ( _handle ) ;
2012-06-29 20:10:10 -07:00
}
2013-07-24 21:59:59 -07:00
void setTexture ( uint8_t _stage , UniformHandle _sampler , TextureHandle _handle , uint32_t _flags )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > setTexture ( _stage , _sampler , _handle , _flags ) ;
2012-06-29 20:10:10 -07:00
}
2014-02-05 23:07:11 -08:00
void setTexture ( uint8_t _stage , UniformHandle _sampler , FrameBufferHandle _handle , uint8_t _attachment , uint32_t _flags )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2014-02-05 23:07:11 -08:00
s_ctx - > setTexture ( _stage , _sampler , _handle , _attachment , _flags ) ;
2012-06-29 20:10:10 -07:00
}
2013-10-21 20:37:02 -07:00
uint32_t submit ( uint8_t _id , int32_t _depth )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-21 20:37:02 -07:00
return s_ctx - > submit ( _id , _depth ) ;
2012-06-29 20:10:10 -07:00
}
2013-10-21 20:37:02 -07:00
uint32_t submitMask ( uint32_t _viewMask , int32_t _depth )
2012-06-29 20:10:10 -07:00
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-21 20:37:02 -07:00
return s_ctx - > submitMask ( _viewMask , _depth ) ;
2012-06-29 20:10:10 -07:00
}
2013-07-29 19:01:29 -07:00
void discard ( )
{
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-10-04 23:45:05 -07:00
s_ctx - > discard ( ) ;
2013-07-29 19:01:29 -07:00
}
2012-06-29 20:10:10 -07:00
void saveScreenShot ( const char * _filePath )
{
2012-11-25 18:24:50 -08:00
BGFX_CHECK_MAIN_THREAD ( ) ;
2013-09-20 22:13:58 -07:00
s_ctx - > saveScreenShot ( _filePath ) ;
2012-06-29 20:10:10 -07:00
}
}