diff --git a/3rdparty/dxsdk/include/d3dcommon.h b/3rdparty/dxsdk/include/d3dcommon.h index 16a55572..f1c674c4 100644 --- a/3rdparty/dxsdk/include/d3dcommon.h +++ b/3rdparty/dxsdk/include/d3dcommon.h @@ -37,6 +37,57 @@ #pragma once #endif +#if _MSC_VER <= 1600 +#ifndef VS2008_SAL_COMPAT +#define VS2008_SAL_COMPAT +// BK - SAL compatibility for VS2008 + +#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \ + extern "C++" { \ + inline ENUMTYPE operator | (ENUMTYPE _a, ENUMTYPE _b) { return ENUMTYPE ( ( (int) _a) | ( (int)_b) ); } \ + inline ENUMTYPE operator |= (ENUMTYPE &_a, ENUMTYPE _b) { return (ENUMTYPE &)( ( (int &)_a) |= ( (int)_b) ); } \ + inline ENUMTYPE operator & (ENUMTYPE _a, ENUMTYPE _b) { return ENUMTYPE ( ( (int) _a) & ( (int)_b) ); } \ + inline ENUMTYPE operator &= (ENUMTYPE &_a, ENUMTYPE _b) { return (ENUMTYPE &)( ( (int &)_a) &= ( (int)_b) ); } \ + inline ENUMTYPE operator ~ (ENUMTYPE _a) { return (ENUMTYPE) (~( (int) _a) ); } \ + inline ENUMTYPE operator ^ (ENUMTYPE _a, ENUMTYPE _b) { return ENUMTYPE ( ( (int) _a) ^ ( (int)_b) ); } \ + inline ENUMTYPE operator ^= (ENUMTYPE &_a, ENUMTYPE _b) { return (ENUMTYPE &)( ( (int &)_a) ^= ( (int)_b) ); } \ + } + +#undef _Out_ +#define _Out_ +#undef _In_ +#define _In_ +#undef _Always_ +#define _Always_(annos) +#define _In_reads_(size) +#define _In_reads_opt_(size) +#define _In_reads_bytes_(size) +#define _In_reads_bytes_opt_(size) +#define _Inout_updates_bytes_(size) +#define _Out_writes_(size) +#define _Out_writes_opt_(size) +#define _Out_writes_to_opt_(size,count) +#define _Out_writes_bytes_(size) +#define _Out_writes_bytes_opt_(size) +#define _Out_writes_bytes_to_(size,count) +#define _Outptr_ +#define _Outptr_opt_result_maybenull_ +#define _Outptr_opt_result_bytebuffer_(size) +#define _Outptr_result_maybenull_ +#define _Outptr_result_bytebuffer_(size) +#define _Out_writes_all_opt_(size) +#define _COM_Outptr_ +#define _COM_Outptr_opt_ +#define _COM_Outptr_opt_result_maybenull_ +#define _Field_size_(size) +#define _Field_size_full_(size) +#define _Field_size_opt_(size) +#define _Field_size_bytes_full_(size) +#define nullptr NULL + +#endif // BK - VS2008_SAL_COMPAT +#endif // + /* Forward Declarations */ #ifndef __ID3D10Blob_FWD_DEFINED__ diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index 94f8e4de..773ec5f4 100644 --- a/examples/common/entry/entry.cpp +++ b/examples/common/entry/entry.cpp @@ -464,7 +464,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); case Event::Window: break; - default: + case Event::Suspend: + break; + + default: break; } } diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 373808b6..13b85262 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -62,7 +62,8 @@ namespace entry }; struct Modifier - { enum Enum + { + enum Enum { None = 0, LeftAlt = 0x01, @@ -187,6 +188,19 @@ namespace entry }; }; + struct Suspend + { + enum Enum + { + WillSuspend, + DidSuspend, + WillResume, + DidResume, + + Count + }; + }; + const char* getName(Key::Enum _key); struct MouseState diff --git a/examples/common/entry/entry_android.cpp b/examples/common/entry/entry_android.cpp index 2d7c852c..f16b1e5d 100644 --- a/examples/common/entry/entry_android.cpp +++ b/examples/common/entry/entry_android.cpp @@ -181,14 +181,22 @@ namespace entry break; case APP_CMD_GAINED_FOCUS: + { // Command from main thread: the app's activity window has gained // input focus. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::WillResume); break; + } case APP_CMD_LOST_FOCUS: + { // Command from main thread: the app's activity window has lost // input focus. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::WillSuspend); break; + } case APP_CMD_CONFIG_CHANGED: // Command from main thread: the current device configuration has changed. @@ -204,8 +212,12 @@ namespace entry break; case APP_CMD_RESUME: + { // Command from main thread: the app's activity has been resumed. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::DidResume); break; + } case APP_CMD_SAVE_STATE: // Command from main thread: the app should generate a new saved state @@ -216,8 +228,12 @@ namespace entry break; case APP_CMD_PAUSE: + { // Command from main thread: the app's activity has been paused. + WindowHandle defaultWindow = { 0 }; + m_eventQueue.postSuspendEvent(defaultWindow, Suspend::DidSuspend); break; + } case APP_CMD_STOP: // Command from main thread: the app's activity has been stopped. diff --git a/examples/common/entry/entry_asmjs.cpp b/examples/common/entry/entry_asmjs.cpp index 73e7483c..f5c3dc62 100644 --- a/examples/common/entry/entry_asmjs.cpp +++ b/examples/common/entry/entry_asmjs.cpp @@ -109,15 +109,20 @@ namespace entry emscripten_request_fullscreen_strategy("#canvas", false, &fullscreenStrategy); + emscripten_set_focus_callback(NULL, this, true, focusCb); + emscripten_set_focusin_callback(NULL, this, true, focusCb); + emscripten_set_focusout_callback(NULL, this, true, focusCb); + int32_t result = main(_argc, _argv); return result; } - static EM_BOOL mouseCb(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); - static EM_BOOL wheelCb(int eventType, const EmscriptenWheelEvent* wheelEvent, void* userData); - static EM_BOOL keyCb(int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData); - static EM_BOOL resizeCb(int eventType, const EmscriptenUiEvent* uiEvent, void* userData); - static EM_BOOL canvasResizeCb(int eventType, const void* reserved, void *userData); + static EM_BOOL mouseCb(int eventType, const EmscriptenMouseEvent* event, void* userData); + static EM_BOOL wheelCb(int eventType, const EmscriptenWheelEvent* event, void* userData); + static EM_BOOL keyCb(int eventType, const EmscriptenKeyboardEvent* event, void* userData); + static EM_BOOL resizeCb(int eventType, const EmscriptenUiEvent* event, void* userData); + static EM_BOOL canvasResizeCb(int eventType, const void* reserved, void* userData); + static EM_BOOL focusCb(int eventType, const EmscriptenFocusEvent* event, void* userData); EventQueue m_eventQueue; @@ -284,18 +289,53 @@ namespace entry return false; } - EM_BOOL Context::resizeCb(int eventType, const EmscriptenUiEvent* event, void *userData) + EM_BOOL Context::resizeCb(int eventType, const EmscriptenUiEvent* event, void* userData) { BX_UNUSED(eventType, event, userData); return false; } - EM_BOOL Context::canvasResizeCb(int eventType, const void* reserved, void *userData) + EM_BOOL Context::canvasResizeCb(int eventType, const void* reserved, void* userData) { BX_UNUSED(eventType, reserved, userData); return false; } + EM_BOOL Context::focusCb(int eventType, const EmscriptenFocusEvent* event, void* userData) + { + printf("focusCb %d", eventType); + BX_UNUSED(event, userData); + + if (event) + { + switch (eventType) + { + case EMSCRIPTEN_EVENT_BLUR: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); + return true; + } + case EMSCRIPTEN_EVENT_FOCUS: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); + return true; + } + case EMSCRIPTEN_EVENT_FOCUSIN: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); + return true; + } + case EMSCRIPTEN_EVENT_FOCUSOUT: + { + s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); + return true; + } + } + } + + return false; + } + const Event* poll() { entry_emscripten_yield(); diff --git a/examples/common/entry/entry_ios.mm b/examples/common/entry/entry_ios.mm index f721bfa0..d2392d89 100644 --- a/examples/common/entry/entry_ios.mm +++ b/examples/common/entry/entry_ios.mm @@ -323,22 +323,26 @@ static void* m_device = NULL; - (void)applicationWillResignActive:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); [m_view stop]; } - (void)applicationDidEnterBackground:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); } - (void)applicationWillEnterForeground:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); } - (void)applicationDidBecomeActive:(UIApplication *)application { BX_UNUSED(application); + s_ctx->m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); [m_view start]; } diff --git a/examples/common/entry/entry_osx.mm b/examples/common/entry/entry_osx.mm index a43c47ab..6446e425 100644 --- a/examples/common/entry/entry_osx.mm +++ b/examples/common/entry/entry_osx.mm @@ -39,6 +39,8 @@ - (void)windowWillClose:(NSNotification*)notification; - (BOOL)windowShouldClose:(NSWindow*)window; - (void)windowDidResize:(NSNotification*)notification; +- (void)windowDidBecomeKey:(NSNotification *)notification; +- (void)windowDidResignKey:(NSNotification *)notification; @end @@ -384,6 +386,18 @@ namespace entry m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Right, false); } + void windowDidBecomeKey() + { + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); + } + + void windowDidResignKey() + { + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); + m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); + } + int32_t run(int _argc, char** _argv) { [NSApplication sharedApplication]; @@ -723,6 +737,20 @@ namespace entry s_ctx.windowDidResize(); } +- (void)windowDidBecomeKey:(NSNotification*)notification +{ + BX_UNUSED(notification); + using namespace entry; + s_ctx.windowDidBecomeKey(); +} + +- (void)windowDidResignKey:(NSNotification*)notification +{ + BX_UNUSED(notification); + using namespace entry; + s_ctx.windowDidResignKey(); +} + @end int main(int _argc, char** _argv) diff --git a/examples/common/entry/entry_p.h b/examples/common/entry/entry_p.h index d0ba7331..e1a1a514 100644 --- a/examples/common/entry/entry_p.h +++ b/examples/common/entry/entry_p.h @@ -75,6 +75,7 @@ namespace entry Mouse, Size, Window, + Suspend, }; Event(Enum _type) @@ -154,6 +155,13 @@ namespace entry void* m_nwh; }; + struct SuspendEvent : public Event + { + ENTRY_IMPLEMENT_EVENT(SuspendEvent, Event::Suspend); + + Suspend::Enum m_state; + }; + const Event* poll(); const Event* poll(WindowHandle _handle); void release(const Event* _event); @@ -248,6 +256,13 @@ namespace entry m_queue.push(ev); } + void postSuspendEvent(WindowHandle _handle, Suspend::Enum _state) + { + SuspendEvent* ev = new SuspendEvent(_handle); + ev->m_state = _state; + m_queue.push(ev); + } + const Event* poll() { return m_queue.pop(); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 1d75ef87..87f54127 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -2733,6 +2733,15 @@ namespace bgfx return invalid; } + ProgramHashMap::const_iterator it = m_programHashMap.find(uint32_t(_fsh.idx<<16)|_vsh.idx); + if (it != m_programHashMap.end() ) + { + ProgramHandle handle = it->second; + ProgramRef& pr = m_programRef[handle.idx]; + ++pr.m_refCount; + return handle; + } + const ShaderRef& vsr = m_shaderRef[_vsh.idx]; const ShaderRef& fsr = m_shaderRef[_fsh.idx]; if (vsr.m_hash != fsr.m_hash) @@ -2753,6 +2762,9 @@ namespace bgfx ProgramRef& pr = m_programRef[handle.idx]; pr.m_vsh = _vsh; pr.m_fsh = _fsh; + pr.m_refCount = 1; + + m_programHashMap.insert(stl::make_pair(uint32_t(_fsh.idx<<16)|_vsh.idx, handle) ); CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateProgram); cmdbuf.write(handle); @@ -2778,6 +2790,15 @@ namespace bgfx return invalid; } + ProgramHashMap::const_iterator it = m_programHashMap.find(_vsh.idx); + if (it != m_programHashMap.end() ) + { + ProgramHandle handle = it->second; + ProgramRef& pr = m_programRef[handle.idx]; + ++pr.m_refCount; + return handle; + } + ProgramHandle handle; handle.idx = m_programHandle.alloc(); @@ -2789,6 +2810,9 @@ namespace bgfx pr.m_vsh = _vsh; ShaderHandle fsh = BGFX_INVALID_HANDLE; pr.m_fsh = fsh; + pr.m_refCount = 1; + + m_programHashMap.insert(stl::make_pair(uint32_t(_vsh.idx), handle) ); CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateProgram); cmdbuf.write(handle); @@ -2808,16 +2832,24 @@ namespace bgfx { BGFX_CHECK_HANDLE("destroyProgram", m_programHandle, _handle); - CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyProgram); - cmdbuf.write(_handle); - m_submit->free(_handle); - - const ProgramRef& pr = m_programRef[_handle.idx]; - shaderDecRef(pr.m_vsh); - - if (isValid(pr.m_fsh) ) + ProgramRef& pr = m_programRef[_handle.idx]; + int32_t refs = --pr.m_refCount; + if (0 == refs) { - shaderDecRef(pr.m_fsh); + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyProgram); + cmdbuf.write(_handle); + m_submit->free(_handle); + + shaderDecRef(pr.m_vsh); + uint32_t hash = pr.m_vsh.idx; + + if (isValid(pr.m_fsh) ) + { + shaderDecRef(pr.m_fsh); + hash |= pr.m_fsh.idx << 16; + } + + m_programHashMap.erase(m_programHashMap.find(hash) ); } } @@ -3593,6 +3625,7 @@ namespace bgfx { ShaderHandle m_vsh; ShaderHandle m_fsh; + int16_t m_refCount; }; struct UniformRef @@ -3623,8 +3656,13 @@ namespace bgfx typedef stl::unordered_map UniformHashMap; UniformHashMap m_uniformHashMap; UniformRef m_uniformRef[BGFX_CONFIG_MAX_UNIFORMS]; + ShaderRef m_shaderRef[BGFX_CONFIG_MAX_SHADERS]; + + typedef stl::unordered_map ProgramHashMap; + ProgramHashMap m_programHashMap; ProgramRef m_programRef[BGFX_CONFIG_MAX_PROGRAMS]; + TextureRef m_textureRef[BGFX_CONFIG_MAX_TEXTURES]; FrameBufferRef m_frameBufferRef[BGFX_CONFIG_MAX_FRAME_BUFFERS]; VertexDeclRef m_declRef; diff --git a/src/image.cpp b/src/image.cpp index fe1d361b..e48d2cfc 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -12,13 +12,15 @@ namespace bgfx { static const ImageBlockInfo s_imageBlockInfo[] = { - // +------------------ bits per pixel - // | +--------------- block width - // | | +------------ block height - // | | | +-------- block size - // | | | | +----- min blocks x - // | | | | | +-- min blocks y - // | | | | | | + // +--------------------------- bits per pixel + // | +------------------------ block width + // | | +--------------------- block height + // | | | +----------------- block size + // | | | | +-------------- min blocks x + // | | | | | +----------- min blocks y + // | | | | | | +------- depth bits + // | | | | | | | +---- stencil bits + // | | | | | | | | { 4, 4, 4, 8, 1, 1, 0, 0 }, // BC1 { 8, 4, 4, 16, 1, 1, 0, 0 }, // BC2 { 8, 4, 4, 16, 1, 1, 0, 0 }, // BC3 diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 90bf82a3..e5722d71 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -4186,7 +4186,7 @@ data.NumQualityLevels = 0; ScratchBufferD3D12& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; scratchBuffer.reset(gpuHandle); - D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = {}; + D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = UINT64_C(0); StateCacheLru bindLru; setResourceBarrier(m_commandList diff --git a/src/vertexdecl.cpp b/src/vertexdecl.cpp index f26c5f86..470cb567 100644 --- a/src/vertexdecl.cpp +++ b/src/vertexdecl.cpp @@ -111,10 +111,10 @@ namespace bgfx VertexDecl& VertexDecl::add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized, bool _asInt) { - const uint8_t encodedNorm = (_normalized&1)<<7; - const uint8_t encodedType = (_type&7)<<3; - const uint8_t encodedNum = (_num-1)&3; - const uint8_t encodeAsInt = (_asInt&(!!"\x1\x1\x0\x0"[_type]) )<<8; + const uint16_t encodedNorm = (_normalized&1)<<7; + const uint16_t encodedType = (_type&7)<<3; + const uint16_t encodedNum = (_num-1)&3; + const uint16_t encodeAsInt = (_asInt&(!!"\x1\x1\x1\x0\x0"[_type]) )<<8; m_attributes[_attrib] = encodedNorm|encodedType|encodedNum|encodeAsInt; m_offset[_attrib] = m_stride;