Browse Source

Merge pull request #180 from MikePopoloski/master

Adding WinRT Support
Branimir Karadžić 11 years ago
parent
commit
1abff576ac

+ 188 - 0
examples/common/entry/entry_winrt.cpp

@@ -0,0 +1,188 @@
+/*
+ * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "entry_p.h"
+
+#if BX_PLATFORM_WINRT
+
+#include <bgfxplatform.h>
+#include <bx/thread.h>
+
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+using namespace Windows::System;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+using namespace Platform;
+
+static char* g_emptyArgs[] = { "" };
+static entry::WindowHandle g_defaultWindow = { 0 };
+static entry::EventQueue g_eventQueue;
+
+ref class App sealed : public IFrameworkView
+{
+public:
+    App() :
+        m_windowVisible(true),
+        m_windowClosed(false)
+    {
+    }
+
+    // IFrameworkView Methods.
+	virtual void Initialize(CoreApplicationView^ applicationView)
+    {
+        applicationView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
+    }
+
+	virtual void SetWindow(CoreWindow^ window)
+    {
+        window->VisibilityChanged += ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
+	    window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
+
+        bgfx::winrtSetWindow(reinterpret_cast<IUnknown*>(window));
+    }
+
+	virtual void Load(String^ entryPoint)
+    {
+    }
+
+	virtual void Run()
+    {
+		bx::Thread thread;
+		thread.init(MainThreadFunc, nullptr);
+
+        CoreWindow^ window = CoreWindow::GetForCurrentThread();
+        if (window == nullptr) {
+            int i = 4;
+            i++;
+        }
+
+        //auto bounds = window->Bounds;
+        //g_eventQueue.postSizeEvent(g_defaultWindow, bounds.Width, bounds.Height);
+
+        while (!m_windowClosed)
+	    {
+		    if (m_windowVisible)
+			    window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
+		    else
+			    window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
+	    }
+
+        g_eventQueue.postExitEvent();
+
+        thread.shutdown();
+    }
+
+	virtual void Uninitialize()
+    {
+    }
+
+private:
+    bool m_windowVisible;
+    bool m_windowClosed;
+
+    void OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+    {
+        CoreWindow^ window = CoreWindow::GetForCurrentThread();
+        if (window == nullptr) {
+            int i = 4;
+            i++;
+        }
+
+        CoreWindow::GetForCurrentThread()->Activate();
+    }
+
+    void OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+    {
+        m_windowVisible = args->Visible;
+    }
+
+	void OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+    {
+        m_windowClosed = true;
+    }
+
+    static int32_t MainThreadFunc(void*)
+    {
+        return entry::main(0, g_emptyArgs);
+    }
+};
+
+ref class AppSource sealed : IFrameworkViewSource
+{
+public:
+	virtual IFrameworkView^ CreateView()
+    {
+        return ref new App();
+    }
+};
+
+namespace entry
+{
+    const Event* poll()
+	{
+		return g_eventQueue.poll();
+	}
+
+	const Event* poll(WindowHandle _handle)
+	{
+		return g_eventQueue.poll(_handle);
+	}
+
+	void release(const Event* _event)
+	{
+		g_eventQueue.release(_event);
+	}
+
+    WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
+	{
+		BX_UNUSED(_x, _y, _width, _height, _flags, _title);
+		WindowHandle handle = { UINT16_MAX };
+		return handle;
+	}
+
+	void destroyWindow(WindowHandle _handle)
+	{
+		BX_UNUSED(_handle);
+	}
+
+	void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
+	{
+		BX_UNUSED(_handle, _x, _y);
+	}
+
+	void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
+	{
+		BX_UNUSED(_handle, _width, _height);
+	}
+
+	void setWindowTitle(WindowHandle _handle, const char* _title)
+	{
+		BX_UNUSED(_handle, _title);
+	}
+
+	void toggleWindowFrame(WindowHandle _handle)
+	{
+		BX_UNUSED(_handle);
+	}
+
+	void setMouseLock(WindowHandle _handle, bool _lock)
+	{
+		BX_UNUSED(_handle, _lock);
+	}
+}
+
+[MTAThread]
+int main(Array<String^>^)
+{
+    auto appSource = ref new AppSource();
+    CoreApplication::Run(appSource);
+    return 0;
+}
+
+#endif

+ 11 - 0
examples/common/font/font_manager.cpp

@@ -5,7 +5,18 @@
 
 #define USE_EDTAA3 0
 
+#include "bx/platform.h"
+
+#if BX_COMPILER_MSVC
+#define generic GenericFromFreeType     // WinRT language extensions see "generic" as a keyword... this is stupid
+#define interface InterfaceFromFreeType
+#pragma warning(push)
+#pragma warning(disable : 4245)         // conversion from 'int' to 'FT_UInt', signed/unsigned mismatch
+#include <freetype/freetype.h>
+#pragma warning(pop)
+#else
 #include <freetype/freetype.h>
+#endif
 
 #include "../common.h"
 

+ 10 - 0
include/bgfxplatform.h

@@ -91,6 +91,16 @@ namespace bgfx
 
 } // namespace bgfx
 
+#elif BX_PLATFORM_WINRT
+#   include <Unknwn.h>
+
+namespace bgfx
+{
+    ///
+    void winrtSetWindow(IUnknown* _window);
+
+} // namespace bgfx
+
 #endif // BX_PLATFORM_
 
 #if defined(_SDL_H)

+ 5 - 0
scripts/bgfx.lua

@@ -49,6 +49,11 @@ function bgfxProject(_name, _kind, _defines)
 				"$(DXSDK_DIR)/include",
 			}
 
+		configuration { "winphone8*"}
+			linkoptions {
+				"/ignore:4264" -- LNK4264: archiving object file compiled with /ZW into a static library; note that when authoring Windows Runtime types it is not recommended to link with a static library that contains Windows Runtime metadata
+			}
+
 		configuration { "xcode4 or osx or ios*" }
 			files {
 				BGFX_DIR .. "src/**.mm",

+ 5 - 0
scripts/example-common.lua

@@ -31,3 +31,8 @@ project ("example-common")
 		includedirs {
 			BX_DIR .. "include/compat/osx",
 		}
+
+	configuration { "winphone8*"}
+		linkoptions {
+			"/ignore:4264" -- LNK4264: archiving object file compiled with /ZW into a static library; note that when authoring Windows Runtime types it is not recommended to link with a static library that contains Windows Runtime metadata
+		}

+ 21 - 1
scripts/genie.lua

@@ -70,7 +70,10 @@ function exampleProject(_name)
 
 	configuration {}
 
-	debugdir (BGFX_DIR .. "examples/runtime/")
+	-- don't output debugdir for winphone builds
+	if "winphone81" ~= _OPTIONS["vs"] then
+		debugdir (BGFX_DIR .. "examples/runtime/")
+	end
 
 	includedirs {
 		BX_DIR .. "include",
@@ -149,6 +152,23 @@ function exampleProject(_name)
 			"psapi",
 		}
 
+	configuration { "winphone8*"}
+		removelinks {
+			"DelayImp",
+			"gdi32",
+			"psapi"
+		}
+		links {
+			"d3d11",
+			"dxgi"
+		}
+		linkoptions {
+			"/ignore:4264" -- LNK4264: archiving object file compiled with /ZW into a static library; note that when authoring Windows Runtime types it is not recommended to link with a static library that contains Windows Runtime metadata
+		}
+		-- WinRT targets need their own output directories are build files stomp over each other
+		targetdir (BGFX_BUILD_DIR .. "arm_" .. _ACTION .. "/bin/" .. _name)
+		objdir (BGFX_BUILD_DIR .. "arm_" .. _ACTION .. "/obj/" .. _name)
+
 	configuration { "mingw*" }
 		links {
 			"dxguid",

+ 11 - 0
src/bgfx.cpp

@@ -46,6 +46,13 @@ namespace bgfx
 	{
 		g_bgfxHwnd = _window;
 	}
+#elif BX_PLATFORM_WINRT
+    ::IUnknown* g_bgfxCoreWindow = NULL;
+
+    void winrtSetWindow(::IUnknown* _window)
+    {
+        g_bgfxCoreWindow = _window;
+    }
 #endif // BX_PLATFORM_*
 
 #if BGFX_CONFIG_USE_TINYSTL
@@ -1386,6 +1393,10 @@ again:
 			{
 				_type = RendererType::OpenGLES;
 			}
+            else if (BX_ENABLED(BX_PLATFORM_WINRT))
+            {
+                _type = RendererType::Direct3D11;
+            }
 			else
 			{
 				_type = RendererType::OpenGL;

+ 2 - 0
src/bgfx_p.h

@@ -198,6 +198,8 @@ namespace bgfx
 	extern void* g_bgfxNSWindow;
 #elif BX_PLATFORM_WINDOWS
 	extern ::HWND g_bgfxHwnd;
+#elif BX_PLATFORM_WINRT
+    extern ::IUnknown* g_bgfxCoreWindow;
 #endif // BX_PLATFORM_*
 
 	struct Clear

+ 2 - 0
src/config.h

@@ -29,6 +29,7 @@
 #	ifndef BGFX_CONFIG_RENDERER_DIRECT3D11
 #		define BGFX_CONFIG_RENDERER_DIRECT3D11 (0 \
 					|| (BX_PLATFORM_WINDOWS && BX_PLATFORM_WINDOWS >= 0x0601 /*_WIN32_WINNT_WIN7*/) \
+                    || BX_PLATFORM_WINRT \
 					? 1 : 0)
 #	endif // BGFX_CONFIG_RENDERER_DIRECT3D11
 
@@ -149,6 +150,7 @@
 						|| BX_PLATFORM_RPI \
 						|| BX_PLATFORM_WINDOWS \
 						|| BX_PLATFORM_XBOX360 \
+                        || BX_PLATFORM_WINRT \
 						? 1 : 0) )
 #endif // BGFX_CONFIG_MULTITHREADED
 

+ 108 - 19
src/renderer_d3d11.cpp

@@ -613,8 +613,14 @@ RENDERDOC_IMPORT
 			HRESULT hr;
 
 			IDXGIFactory* factory;
+#if BX_PLATFORM_WINRT
+            // WinRT requires the IDXGIFactory2 interface, which isn't supported on older platforms
+			hr = CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&factory);
+			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory.");
+#else
 			hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
 			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory.");
+#endif // BX_PLATFORM_WINRT
 
 			m_adapter = NULL;
 			m_driverType = D3D_DRIVER_TYPE_HARDWARE;
@@ -699,6 +705,31 @@ RENDERDOC_IMPORT
 			hr = adapter->GetDesc(&m_adapterDesc);
 			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
 
+#if BX_PLATFORM_WINRT
+            hr = adapter->GetParent(__uuidof(IDXGIFactory2), (void**)&m_factory);
+			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
+			DX_RELEASE(adapter, 2);
+            
+			memset(&m_scd, 0, sizeof(m_scd) );
+			m_scd.Width  = BGFX_DEFAULT_WIDTH;
+			m_scd.Height = BGFX_DEFAULT_HEIGHT;
+			m_scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+            m_scd.Stereo = false;
+			m_scd.SampleDesc.Count = 1;
+			m_scd.SampleDesc.Quality = 0;
+			m_scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+			m_scd.BufferCount = 2;
+            m_scd.Scaling = DXGI_SCALING_NONE;
+            m_scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+            m_scd.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+
+            hr = m_factory->CreateSwapChainForCoreWindow(m_device
+                                                        , g_bgfxCoreWindow
+                                                        , &m_scd
+                                                        , NULL
+                                                        , &m_swapChain
+                                                        );
+#else
 			hr = adapter->GetParent(__uuidof(IDXGIFactory), (void**)&m_factory);
 			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
 			DX_RELEASE(adapter, 2);
@@ -720,6 +751,7 @@ RENDERDOC_IMPORT
 										, &m_scd
 										, &m_swapChain
 										);
+#endif // BX_PLATFORM_WINRT
 			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
 
 			m_numWindows = 1;
@@ -1085,8 +1117,8 @@ RENDERDOC_IMPORT
 		{
 			ID3D11DeviceContext* deviceCtx = m_deviceCtx;
 
-			uint32_t width  = m_scd.BufferDesc.Width;
-			uint32_t height = m_scd.BufferDesc.Height;
+			uint32_t width  = getBufferWidth();
+			uint32_t height = getBufferHeight();
 			if (m_ovr.isEnabled() )
 			{
 				m_ovr.getSize(width, height);
@@ -1175,8 +1207,8 @@ RENDERDOC_IMPORT
 			DX_RELEASE(color, 0);
 
 			D3D11_TEXTURE2D_DESC dsd;
-			dsd.Width  = m_scd.BufferDesc.Width;
-			dsd.Height = m_scd.BufferDesc.Height;
+			dsd.Width  = getBufferWidth();
+			dsd.Height = getBufferHeight();
 			dsd.MipLevels = 1;
 			dsd.ArraySize = 1;
 			dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
@@ -1262,7 +1294,7 @@ RENDERDOC_IMPORT
 			{
 				uint32_t msaa = s_checkMsaa[ii];
 				uint32_t quality = 0;
-				HRESULT hr = m_device->CheckMultisampleQualityLevels(m_scd.BufferDesc.Format, msaa, &quality);
+				HRESULT hr = m_device->CheckMultisampleQualityLevels(getBufferFormat(), msaa, &quality);
 
 				if (SUCCEEDED(hr)
 				&&  0 < quality)
@@ -1283,11 +1315,14 @@ RENDERDOC_IMPORT
 			bool recenter  = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER);
 			uint32_t flags = _resolution.m_flags & ~BGFX_RESET_HMD_RECENTER;
 
-			if ( (uint32_t)m_scd.BufferDesc.Width  != _resolution.m_width
-			||   (uint32_t)m_scd.BufferDesc.Height != _resolution.m_height
+			if ( getBufferWidth()  != _resolution.m_width
+			||   getBufferHeight() != _resolution.m_height
 			||   m_flags != flags)
 			{
 				bool resize = (m_flags&BGFX_RESET_MSAA_MASK) == (flags&BGFX_RESET_MSAA_MASK);
+#if BX_PLATFORM_WINRT
+                resize = false;     // can't use ResizeBuffers on Windows Phone
+#endif
 				m_flags = flags;
 
 				m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
@@ -1296,17 +1331,16 @@ RENDERDOC_IMPORT
 				m_resolution = _resolution;
 				m_resolution.m_flags = flags;
 
-				m_scd.BufferDesc.Width  = _resolution.m_width;
-				m_scd.BufferDesc.Height = _resolution.m_height;
+                setBufferSize(_resolution.m_width, _resolution.m_height);
 
 				preReset();
 
 				if (resize)
 				{
 					DX_CHECK(m_swapChain->ResizeBuffers(2
-						, m_scd.BufferDesc.Width
-						, m_scd.BufferDesc.Height
-						, m_scd.BufferDesc.Format
+						, getBufferWidth()
+						, getBufferHeight()
+						, getBufferFormat()
 						, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
 						) );
 				}
@@ -1317,11 +1351,21 @@ RENDERDOC_IMPORT
 
 					DX_RELEASE(m_swapChain, 0);
 
+#if BX_PLATFORM_WINRT
+                    HRESULT hr;
+					hr = m_factory->CreateSwapChainForCoreWindow(m_device
+                        , g_bgfxCoreWindow
+						, &m_scd
+                        , NULL
+						, &m_swapChain
+						);
+#else
 					HRESULT hr;
 					hr = m_factory->CreateSwapChain(m_device
 						, &m_scd
 						, &m_swapChain
 						);
+#endif
 					BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain.");
 				}
 
@@ -1745,6 +1789,44 @@ RENDERDOC_IMPORT
 			return sampler;
 		}
 
+        DXGI_FORMAT getBufferFormat()
+        {
+#if BX_PLATFORM_WINRT
+            return m_scd.Format;
+#else
+            return m_scd.BufferDesc.Format;
+#endif
+        }
+
+        uint32_t getBufferWidth()
+        {
+#if BX_PLATFORM_WINRT
+            return m_scd.Width;
+#else
+            return m_scd.BufferDesc.Width;
+#endif
+        }
+
+        uint32_t getBufferHeight()
+        {
+#if BX_PLATFORM_WINRT
+            return m_scd.Height;
+#else
+            return m_scd.BufferDesc.Height;
+#endif
+        }
+
+        void setBufferSize(uint32_t _width, uint32_t _height)
+        {
+#if BX_PLATFORM_WINRT
+            m_scd.Width = _width;
+            m_scd.Height = _height;
+#else
+            m_scd.BufferDesc.Width = _width;
+            m_scd.BufferDesc.Height = _height;
+#endif
+        }
+
 		void commitTextureStage()
 		{
 			m_deviceCtx->PSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_srv);
@@ -1900,22 +1982,20 @@ RENDERDOC_IMPORT
 				ID3D11Texture2D* backBuffer;
 				DX_CHECK(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer) );
 
-				DXGI_MODE_DESC& desc = m_scd.BufferDesc;
-
 				if (NULL == m_captureResolve)
 				{
 					m_deviceCtx->CopyResource(m_captureTexture, backBuffer);
 				}
 				else
 				{
-					m_deviceCtx->ResolveSubresource(m_captureResolve, 0, backBuffer, 0, desc.Format);
+					m_deviceCtx->ResolveSubresource(m_captureResolve, 0, backBuffer, 0, getBufferFormat());
 					m_deviceCtx->CopyResource(m_captureTexture, m_captureResolve);
 				}
 
 				D3D11_MAPPED_SUBRESOURCE mapped;
 				DX_CHECK(m_deviceCtx->Map(m_captureTexture, 0, D3D11_MAP_READ, 0, &mapped) );
 
-				g_callback->captureFrame(mapped.pData, desc.Height*mapped.RowPitch);
+				g_callback->captureFrame(mapped.pData, getBufferHeight()*mapped.RowPitch);
 
 				m_deviceCtx->Unmap(m_captureTexture, 0);
 
@@ -2012,8 +2092,8 @@ RENDERDOC_IMPORT
 
 		void clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4])
 		{
-			uint32_t width  = m_scd.BufferDesc.Width;
-			uint32_t height = m_scd.BufferDesc.Height;
+			uint32_t width  = getBufferWidth();
+			uint32_t height = getBufferHeight();
 
 			if (0      == _rect.m_x
 			&&  0      == _rect.m_y
@@ -2146,9 +2226,14 @@ RENDERDOC_IMPORT
 		D3D_DRIVER_TYPE m_driverType;
 		IDXGIAdapter* m_adapter;
 		DXGI_ADAPTER_DESC m_adapterDesc;
+#if BX_PLATFORM_WINRT
+        IDXGIFactory2* m_factory;
+        IDXGISwapChain1* m_swapChain;
+#else
 		IDXGIFactory* m_factory;
+        IDXGISwapChain* m_swapChain;
+#endif
 
-		IDXGISwapChain* m_swapChain;
 		uint16_t m_lost;
 		uint16_t m_numWindows;
 		FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
@@ -2166,7 +2251,11 @@ RENDERDOC_IMPORT
 		Resolution m_resolution;
 		bool m_wireframe;
 
+#if BX_PLATFORM_WINRT
+        DXGI_SWAP_CHAIN_DESC1 m_scd;
+#else
 		DXGI_SWAP_CHAIN_DESC m_scd;
+#endif
 		uint32_t m_flags;
 
 		IndexBufferD3D11 m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];

+ 4 - 0
src/renderer_d3d11.h

@@ -18,7 +18,11 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunknown-pragmas" );
 BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC("-Wpragmas");
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4005) // warning C4005: '' : macro redefinition
 #define D3D11_NO_HELPERS
+#if BX_PLATFORM_WINRT
+#include <d3d11_2.h>
+#else
 #include <d3d11.h>
+#endif
 BX_PRAGMA_DIAGNOSTIC_POP()
 
 #include "renderer_d3d.h"

+ 13 - 0
src/renderer_d3d12.cpp

@@ -6,6 +6,19 @@
 #include "bgfx_p.h"
 
 #if BGFX_CONFIG_RENDERER_DIRECT3D12
+
+namespace bgfx
+{
+	RendererContextI* rendererCreateD3D12()
+	{
+		return NULL;
+	}
+
+	void rendererDestroyD3D12()
+	{
+	}
+} // namespace bgfx
+
 #else
 
 namespace bgfx