Procházet zdrojové kódy

Merge branch 'master' of github.com:bkaradzic/bgfx

Branimir Karadžić před 10 roky
rodič
revize
b0116cfd30

+ 51 - 0
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__

+ 4 - 1
examples/common/entry/entry.cpp

@@ -464,7 +464,10 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 				case Event::Window:
 					break;
 
-				default:
+                case Event::Suspend:
+                    break;
+
+                    default:
 					break;
 				}
 			}

+ 15 - 1
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

+ 16 - 0
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.

+ 47 - 7
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();

+ 4 - 0
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];
 }
 

+ 28 - 0
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)

+ 15 - 0
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();

+ 46 - 8
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);
+			ProgramRef& pr = m_programRef[_handle.idx];
+			int32_t refs = --pr.m_refCount;
+			if (0 == refs)
+			{
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyProgram);
+				cmdbuf.write(_handle);
+				m_submit->free(_handle);
 
-			const ProgramRef& pr = m_programRef[_handle.idx];
-			shaderDecRef(pr.m_vsh);
+				shaderDecRef(pr.m_vsh);
+				uint32_t hash = pr.m_vsh.idx;
 
-			if (isValid(pr.m_fsh) )
-			{
-				shaderDecRef(pr.m_fsh);
+				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<stl::string, UniformHandle> UniformHashMap;
 		UniformHashMap m_uniformHashMap;
 		UniformRef m_uniformRef[BGFX_CONFIG_MAX_UNIFORMS];
+
 		ShaderRef m_shaderRef[BGFX_CONFIG_MAX_SHADERS];
+
+		typedef stl::unordered_map<uint32_t, ProgramHandle> 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;

+ 9 - 7
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

+ 1 - 1
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<D3D12_GPU_DESCRIPTOR_HANDLE, 64> bindLru;
 
 		setResourceBarrier(m_commandList

+ 4 - 4
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;