diff --git a/Dotnet/Overlay/Cef/OffScreenBrowser.cs b/Dotnet/Overlay/Cef/OffScreenBrowser.cs index 92386d9a..1d886111 100644 --- a/Dotnet/Overlay/Cef/OffScreenBrowser.cs +++ b/Dotnet/Overlay/Cef/OffScreenBrowser.cs @@ -8,23 +8,21 @@ using CefSharp; using CefSharp.Enums; using CefSharp.OffScreen; using CefSharp.Structs; -using SharpDX.Direct3D11; using System; using System.Threading; using NLog; -using SharpDX.Direct3D; -using SharpDX.Mathematics.Interop; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D11; using Range = CefSharp.Structs.Range; namespace VRCX { public class OffScreenBrowser : ChromiumWebBrowser, IRenderHandler { - private Device _device; - private Device1 _device1; - private DeviceMultithread _deviceMultithread; - private Query _query; - private Texture2D _renderTarget; + private ComPtr _device1; + private ComPtr _deviceContext; + private ComPtr _query; + private ComPtr _renderTarget; private static readonly Logger logger = LogManager.GetCurrentClassLogger(); @@ -52,23 +50,19 @@ namespace VRCX JavascriptBindings.ApplyVrJavascriptBindings(JavascriptObjectRepository); } - public void UpdateRender(Device device, Texture2D renderTarget) + public void UpdateRender(ComPtr device, ComPtr deviceContext, ComPtr renderTarget) { - _device = device; - _device1 = _device.QueryInterface(); - - _deviceMultithread?.Dispose(); - _deviceMultithread = _device.QueryInterfaceOrNull(); - _deviceMultithread?.SetMultithreadProtected(true); - + _device1.Dispose(); + _device1 = device.QueryInterface(); + _deviceContext = deviceContext; _renderTarget = renderTarget; - _query?.Dispose(); - _query = new Query(_device, new QueryDescription + _query.Dispose(); + device.CreateQuery(new QueryDesc { - Type = QueryType.Event, - Flags = QueryFlags.None - }); + Query = Query.Event, + MiscFlags = 0 + }, ref _query); } public new void Dispose() @@ -102,29 +96,31 @@ namespace VRCX if (type != PaintElementType.View) return; - if (_device == null) - return; - - try + unsafe { - using Texture2D cefTexture = _device1.OpenSharedResource1(paintInfo.SharedTextureHandle); - _device.ImmediateContext.CopyResource(cefTexture, _renderTarget); - _device.ImmediateContext.End(_query); - _device.ImmediateContext.Flush(); - } - catch (Exception e) - { - logger.Error(e); - _device = null; - return; - } - - RawBool q = _device.ImmediateContext.GetData(_query, AsynchronousFlags.DoNotFlush); - - while (!q) - { - Thread.Yield(); - q = _device.ImmediateContext.GetData(_query, AsynchronousFlags.DoNotFlush); + if ((IntPtr)_device1.Handle == IntPtr.Zero) + return; + + if ((IntPtr)_deviceContext.Handle == IntPtr.Zero) + return; + + if ((IntPtr)_query.Handle == IntPtr.Zero) + return; + + if ((IntPtr)_renderTarget.Handle == IntPtr.Zero) + return; + + _deviceContext.Begin(_query); + using ComPtr cefTexture = + _device1.OpenSharedResource1(paintInfo.SharedTextureHandle.ToPointer()); + _deviceContext.CopyResource(_renderTarget, cefTexture); + _deviceContext.End(_query); + _deviceContext.Flush(); + + while (_deviceContext.GetData(_query, IntPtr.Zero.ToPointer(), 0, 0) == 1) + { + Thread.Yield(); + } } } diff --git a/Dotnet/Overlay/Cef/OffScreenBrowserLegacy.cs b/Dotnet/Overlay/Cef/OffScreenBrowserLegacy.cs index 2b408b86..fcada112 100644 --- a/Dotnet/Overlay/Cef/OffScreenBrowserLegacy.cs +++ b/Dotnet/Overlay/Cef/OffScreenBrowserLegacy.cs @@ -8,10 +8,11 @@ using CefSharp; using CefSharp.Enums; using CefSharp.OffScreen; using CefSharp.Structs; -using SharpDX.Direct3D11; using System; using System.Runtime.InteropServices; using System.Threading; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D11; using Range = CefSharp.Structs.Range; namespace VRCX @@ -61,11 +62,14 @@ namespace VRCX _paintBufferLock.Dispose(); } - public void RenderToTexture(Texture2D texture) + public void RenderToTexture(ComPtr deviceContext, ComPtr texture) { // Safeguard against uninitialized texture - if (texture == null) - return; + unsafe + { + if ((IntPtr)texture.Handle == IntPtr.Zero) + return; + } _paintBufferLock.EnterReadLock(); try @@ -73,42 +77,41 @@ namespace VRCX if (_width > 0 && _height > 0) { - var context = texture.Device.ImmediateContext; - var dataBox = context.MapSubresource( - texture, - 0, - MapMode.WriteDiscard, - MapFlags.None - ); - if (dataBox.IsEmpty == false) + MappedSubresource mappedSubresource = default; + deviceContext.Map(texture, 0, Map.WriteDiscard, 0, ref mappedSubresource); + unsafe { - var sourcePtr = _paintBuffer.AddrOfPinnedObject(); - var destinationPtr = dataBox.DataPointer; - var pitch = _width * 4; - var rowPitch = dataBox.RowPitch; - if (pitch == rowPitch) + if ((IntPtr)mappedSubresource.PData != IntPtr.Zero) { - WinApi.RtlCopyMemory( - destinationPtr, - sourcePtr, - (uint)(_width * _height * 4) - ); - } - else - { - for (var y = _height; y > 0; --y) + var sourcePtr = _paintBuffer.AddrOfPinnedObject(); + var destinationPtr = (IntPtr)mappedSubresource.PData; + var pitch = _width * 4; + var rowPitch = mappedSubresource.RowPitch; + if (pitch == rowPitch) { WinApi.RtlCopyMemory( destinationPtr, sourcePtr, - (uint)pitch + (uint)(_width * _height * 4) ); - sourcePtr += pitch; - destinationPtr += rowPitch; + } + else + { + for (var y = _height; y > 0; --y) + { + WinApi.RtlCopyMemory( + destinationPtr, + sourcePtr, + (uint)pitch + ); + sourcePtr += pitch; + destinationPtr += (IntPtr)rowPitch; + } } } + + deviceContext.Unmap(texture, 0); } - context.UnmapSubresource(texture, 0); } } finally diff --git a/Dotnet/Overlay/Cef/VRCXVRCef.cs b/Dotnet/Overlay/Cef/VRCXVRCef.cs index ceb61c89..fed90b47 100644 --- a/Dotnet/Overlay/Cef/VRCXVRCef.cs +++ b/Dotnet/Overlay/Cef/VRCXVRCef.cs @@ -8,20 +8,16 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; +using System.Numerics; using System.Runtime.InteropServices; using System.Text; using System.Threading; using CefSharp; using NLog; -using SharpDX; -using SharpDX.Direct3D11; -using SharpDX.DXGI; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D11; +using Silk.NET.DXGI; using Valve.VR; -using Device = SharpDX.Direct3D11.Device; -using Device1 = SharpDX.Direct3D11.Device1; -using Device2 = SharpDX.Direct3D11.Device2; -using Device3 = SharpDX.Direct3D11.Device3; -using Device4 = SharpDX.Direct3D11.Device4; namespace VRCX { @@ -40,12 +36,8 @@ namespace VRCX private readonly List _deviceList; private readonly ReaderWriterLockSlim _deviceListLock; private bool _active; - private Device _device; private bool _menuButton; private int _overlayHand; - private Factory _factory; - private Texture2D _texture1; - private Texture2D _texture2; private Thread _thread; private DateTime _nextOverlayUpdate; @@ -57,6 +49,16 @@ namespace VRCX private bool _wristOverlayActive; private bool _wristOverlayWasActive; + private DXGI _dxgi; + private D3D11 _d3d11; + private ComPtr _factory; + private ComPtr _adapter; + private ComPtr _device; + private ComPtr _multithread; + private ComPtr _deviceContext; + + private ComPtr _texture1; + private ComPtr _texture2; static VRCXVRCef() { @@ -99,81 +101,76 @@ namespace VRCX private void SetupTextures() { - _factory ??= new Factory1(); + unsafe + { + _dxgi?.Dispose(); + _dxgi = DXGI.GetApi(null); + _d3d11?.Dispose(); + _d3d11 = D3D11.GetApi(null); - _device?.Dispose(); - _device = new Device(_factory.GetAdapter(OpenVR.System.GetD3D9AdapterIndex()), - DeviceCreationFlags.BgraSupport); - UpgradeDevice(); + _factory.Dispose(); + SilkMarshal.ThrowHResult(_dxgi.CreateDXGIFactory(out _factory)); + _adapter.Dispose(); + SilkMarshal.ThrowHResult(_factory.EnumAdapters((uint)OpenVR.System.GetD3D9AdapterIndex(), + ref _adapter)); - _texture1?.Dispose(); - _texture1 = new Texture2D( - _device, - new Texture2DDescription + _device.Dispose(); + _deviceContext.Dispose(); + SilkMarshal.ThrowHResult + ( + _d3d11.CreateDevice + ( + _adapter, + D3DDriverType.Unknown, + Software: default, + (uint)(CreateDeviceFlag.BgraSupport | CreateDeviceFlag.Debug), + null, + 0, + D3D11.SdkVersion, + ref _device, + null, + ref _deviceContext + ) + ); + + _multithread = _device.QueryInterface(); + _multithread.SetMultithreadProtected(true); + + _device.SetInfoQueueCallback(msg => logger.Info(SilkMarshal.PtrToString((nint)msg.PDescription)!)); + + _texture1.Dispose(); + _device.CreateTexture2D(new Texture2DDesc { Width = 512, Height = 512, MipLevels = 1, ArraySize = 1, - Format = Format.B8G8R8A8_UNorm, - SampleDescription = new SampleDescription(1, 0), - BindFlags = BindFlags.ShaderResource - } - ); - _wristOverlay?.UpdateRender(_device, _texture1); + Format = Format.FormatB8G8R8A8Unorm, + SampleDesc = new SampleDesc + { + Count = 1, + Quality = 0 + }, + BindFlags = (uint)BindFlag.ShaderResource + }, null, ref _texture1); + _wristOverlay?.UpdateRender(_device, _deviceContext, _texture1); - _texture2?.Dispose(); - _texture2 = new Texture2D( - _device, - new Texture2DDescription + _texture2.Dispose(); + _device.CreateTexture2D(new Texture2DDesc { Width = 1024, Height = 1024, MipLevels = 1, ArraySize = 1, - Format = Format.B8G8R8A8_UNorm, - SampleDescription = new SampleDescription(1, 0), - BindFlags = BindFlags.ShaderResource - } - ); - _hmdOverlay?.UpdateRender(_device, _texture2); - } - - private void UpgradeDevice() - { - Device5 device5 = _device.QueryInterfaceOrNull(); - if (device5 != null) - { - _device.Dispose(); - _device = device5; - return; - } - Device4 device4 = _device.QueryInterfaceOrNull(); - if (device4 != null) - { - _device.Dispose(); - _device = device4; - return; - } - Device3 device3 = _device.QueryInterfaceOrNull(); - if (device3 != null) - { - _device.Dispose(); - _device = device3; - return; - } - Device2 device2 = _device.QueryInterfaceOrNull(); - if (device2 != null) - { - _device.Dispose(); - _device = device2; - return; - } - Device1 device1 = _device.QueryInterfaceOrNull(); - if (device1 != null) - { - _device.Dispose(); - _device = device1; + Format = Format.FormatB8G8R8A8Unorm, + SampleDesc = new SampleDesc + { + Count = 1, + Quality = 0 + }, + BindFlags = (uint)BindFlag.ShaderResource + }, null, ref _texture2); + _hmdOverlay?.UpdateRender(_device, _deviceContext, _texture2); } } @@ -324,9 +321,11 @@ namespace VRCX _hmdOverlay?.Dispose(); _wristOverlay?.Dispose(); - _texture2?.Dispose(); - _texture1?.Dispose(); - _device?.Dispose(); + _texture2.Dispose(); + _texture1.Dispose(); + _device.Dispose(); + _adapter.Dispose(); + _factory.Dispose(); } public override void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand) @@ -581,6 +580,12 @@ namespace VRCX { return err; } + + err = overlay.SetOverlayFlag(dashboardHandle, VROverlayFlags.NoDashboardTab, true); + if (err != EVROverlayError.None) + { + return err; + } } } @@ -611,14 +616,17 @@ namespace VRCX if (dashboardVisible) { - var texture = new Texture_t + unsafe { - handle = _texture1.NativePointer - }; - err = overlay.SetOverlayTexture(dashboardHandle, ref texture); - if (err != EVROverlayError.None) - { - return err; + var texture = new Texture_t + { + handle = (IntPtr)_texture1.Handle + }; + err = overlay.SetOverlayTexture(dashboardHandle, ref texture); + if (err != EVROverlayError.None) + { + return err; + } } } @@ -670,11 +678,11 @@ namespace VRCX { // http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices // Scaling-Rotation-Translation - var m = Matrix.Scaling(0.25f); - m *= Matrix.RotationX(_rotation[0]); - m *= Matrix.RotationY(_rotation[1]); - m *= Matrix.RotationZ(_rotation[2]); - m *= Matrix.Translation(_translation[0], _translation[1], _translation[2]); + var m = Matrix4x4.CreateScale(0.25f); + m *= Matrix4x4.CreateRotationX(_rotation[0]); + m *= Matrix4x4.CreateRotationY(_rotation[1]); + m *= Matrix4x4.CreateRotationZ(_rotation[2]); + m *= Matrix4x4.CreateTranslation(new Vector3(_translation[0], _translation[1], _translation[2])); var hm34 = new HmdMatrix34_t { m0 = m.M11, @@ -700,14 +708,17 @@ namespace VRCX if (!dashboardVisible && DateTime.UtcNow.CompareTo(_nextOverlayUpdate) <= 0) { - var texture = new Texture_t + unsafe { - handle = _texture1.NativePointer - }; - err = overlay.SetOverlayTexture(overlayHandle, ref texture); - if (err != EVROverlayError.None) - { - return err; + var texture = new Texture_t + { + handle = (IntPtr)_texture1.Handle + }; + err = overlay.SetOverlayTexture(overlayHandle, ref texture); + if (err != EVROverlayError.None) + { + return err; + } } if (!overlayVisible) @@ -774,8 +785,8 @@ namespace VRCX return err; } - var m = Matrix.Scaling(1f); - m *= Matrix.Translation(0, -0.3f, -1.5f); + var m = Matrix4x4.CreateScale(1f); + m *= Matrix4x4.CreateTranslation(0, -0.3f, -1.5f); var hm34 = new HmdMatrix34_t { m0 = m.M11, @@ -801,14 +812,17 @@ namespace VRCX if (!dashboardVisible) { - var texture = new Texture_t + unsafe { - handle = _texture2.NativePointer - }; - err = overlay.SetOverlayTexture(overlayHandle, ref texture); - if (err != EVROverlayError.None) - { - return err; + var texture = new Texture_t + { + handle = (IntPtr)_texture2.Handle + }; + err = overlay.SetOverlayTexture(overlayHandle, ref texture); + if (err != EVROverlayError.None) + { + return err; + } } if (!overlayVisible) diff --git a/Dotnet/Overlay/Cef/VRCXVRLegacy.cs b/Dotnet/Overlay/Cef/VRCXVRLegacy.cs index e79a6305..cdbdbb56 100644 --- a/Dotnet/Overlay/Cef/VRCXVRLegacy.cs +++ b/Dotnet/Overlay/Cef/VRCXVRLegacy.cs @@ -8,16 +8,16 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; +using System.Numerics; using System.Runtime.InteropServices; using System.Text; using System.Threading; using CefSharp; using NLog; -using SharpDX; -using SharpDX.Direct3D11; -using SharpDX.DXGI; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D11; +using Silk.NET.DXGI; using Valve.VR; -using Device = SharpDX.Direct3D11.Device; namespace VRCX { @@ -36,15 +36,23 @@ namespace VRCX private readonly List _deviceList; private readonly ReaderWriterLockSlim _deviceListLock; private bool _active; - private Device _device; private bool _hmdOverlayActive; private bool _menuButton; private int _overlayHand; - private Texture2D _texture1; - private Texture2D _texture2; private Thread _thread; private bool _wristOverlayActive; private DateTime _nextOverlayUpdate; + + private DXGI _dxgi; + private D3D11 _d3d11; + private ComPtr _factory; + private ComPtr _adapter; + private ComPtr _device; + private ComPtr _multithread; + private ComPtr _deviceContext; + + private ComPtr _texture1; + private ComPtr _texture2; static VRCXVRLegacy() { @@ -87,43 +95,75 @@ namespace VRCX private void SetupTextures() { - Factory f = new Factory1(); - _device = new Device(f.GetAdapter(OpenVR.System.GetD3D9AdapterIndex()), - DeviceCreationFlags.SingleThreaded | DeviceCreationFlags.BgraSupport); + unsafe + { + _dxgi?.Dispose(); + _dxgi = DXGI.GetApi(null); + _d3d11?.Dispose(); + _d3d11 = D3D11.GetApi(null); - _texture1?.Dispose(); - _texture1 = new Texture2D( - _device, - new Texture2DDescription + _factory.Dispose(); + SilkMarshal.ThrowHResult(_dxgi.CreateDXGIFactory(out _factory)); + _adapter.Dispose(); + SilkMarshal.ThrowHResult(_factory.EnumAdapters((uint)OpenVR.System.GetD3D9AdapterIndex(), + ref _adapter)); + + _device.Dispose(); + _deviceContext.Dispose(); + SilkMarshal.ThrowHResult + ( + _d3d11.CreateDevice + ( + _adapter, + D3DDriverType.Unknown, + Software: default, + (uint)(CreateDeviceFlag.BgraSupport | CreateDeviceFlag.Debug), + null, + 0, + D3D11.SdkVersion, + ref _device, + null, + ref _deviceContext + ) + ); + + _multithread = _device.QueryInterface(); + _multithread.SetMultithreadProtected(true); + + _device.SetInfoQueueCallback(msg => logger.Info(SilkMarshal.PtrToString((nint)msg.PDescription)!)); + + _texture1.Dispose(); + _device.CreateTexture2D(new Texture2DDesc { Width = 512, Height = 512, MipLevels = 1, ArraySize = 1, - Format = Format.B8G8R8A8_UNorm, - SampleDescription = new SampleDescription(1, 0), - Usage = ResourceUsage.Dynamic, - BindFlags = BindFlags.ShaderResource, - CpuAccessFlags = CpuAccessFlags.Write - } - ); + Format = Format.FormatB8G8R8A8Unorm, + SampleDesc = new SampleDesc + { + Count = 1, + Quality = 0 + }, + BindFlags = (uint)BindFlag.ShaderResource + }, null, ref _texture1); - _texture2?.Dispose(); - _texture2 = new Texture2D( - _device, - new Texture2DDescription + _texture2.Dispose(); + _device.CreateTexture2D(new Texture2DDesc { Width = 1024, Height = 1024, MipLevels = 1, ArraySize = 1, - Format = Format.B8G8R8A8_UNorm, - SampleDescription = new SampleDescription(1, 0), - Usage = ResourceUsage.Dynamic, - BindFlags = BindFlags.ShaderResource, - CpuAccessFlags = CpuAccessFlags.Write - } - ); + Format = Format.FormatB8G8R8A8Unorm, + SampleDesc = new SampleDesc + { + Count = 1, + Quality = 0 + }, + BindFlags = (uint)BindFlag.ShaderResource + }, null, ref _texture2); + } } private void ThreadLoop() @@ -155,9 +195,9 @@ namespace VRCX while (_thread != null) { if (_wristOverlayActive) - _wristOverlay.RenderToTexture(_texture1); + _wristOverlay.RenderToTexture(_deviceContext, _texture1); if (_hmdOverlayActive) - _hmdOverlay.RenderToTexture(_texture2); + _hmdOverlay.RenderToTexture(_deviceContext, _texture2); try { Thread.Sleep(32); @@ -268,9 +308,11 @@ namespace VRCX _hmdOverlay?.Dispose(); _wristOverlay?.Dispose(); - _texture2?.Dispose(); - _texture1?.Dispose(); - _device?.Dispose(); + _texture2.Dispose(); + _texture1.Dispose(); + _device.Dispose(); + _adapter.Dispose(); + _factory.Dispose(); } public override void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand) @@ -509,6 +551,12 @@ namespace VRCX { return err; } + + err = overlay.SetOverlayFlag(dashboardHandle, VROverlayFlags.NoDashboardTab, true); + if (err != EVROverlayError.None) + { + return err; + } } } @@ -539,14 +587,17 @@ namespace VRCX if (dashboardVisible) { - var texture = new Texture_t + unsafe { - handle = _texture1.NativePointer - }; - err = overlay.SetOverlayTexture(dashboardHandle, ref texture); - if (err != EVROverlayError.None) - { - return err; + var texture = new Texture_t + { + handle = (IntPtr)_texture1.Handle + }; + err = overlay.SetOverlayTexture(dashboardHandle, ref texture); + if (err != EVROverlayError.None) + { + return err; + } } } @@ -598,11 +649,11 @@ namespace VRCX { // http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices // Scaling-Rotation-Translation - var m = Matrix.Scaling(0.25f); - m *= Matrix.RotationX(_rotation[0]); - m *= Matrix.RotationY(_rotation[1]); - m *= Matrix.RotationZ(_rotation[2]); - m *= Matrix.Translation(_translation[0], _translation[1], _translation[2]); + var m = Matrix4x4.CreateScale(0.25f); + m *= Matrix4x4.CreateRotationX(_rotation[0]); + m *= Matrix4x4.CreateRotationY(_rotation[1]); + m *= Matrix4x4.CreateRotationZ(_rotation[2]); + m *= Matrix4x4.CreateTranslation(new Vector3(_translation[0], _translation[1], _translation[2])); var hm34 = new HmdMatrix34_t { m0 = m.M11, @@ -628,14 +679,17 @@ namespace VRCX if (!dashboardVisible && DateTime.UtcNow.CompareTo(_nextOverlayUpdate) <= 0) { - var texture = new Texture_t + unsafe { - handle = _texture1.NativePointer - }; - err = overlay.SetOverlayTexture(overlayHandle, ref texture); - if (err != EVROverlayError.None) - { - return err; + var texture = new Texture_t + { + handle = (IntPtr)_texture1.Handle + }; + err = overlay.SetOverlayTexture(overlayHandle, ref texture); + if (err != EVROverlayError.None) + { + return err; + } } if (!overlayVisible) @@ -702,8 +756,8 @@ namespace VRCX return err; } - var m = Matrix.Scaling(1f); - m *= Matrix.Translation(0, -0.3f, -1.5f); + var m = Matrix4x4.CreateScale(1f); + m *= Matrix4x4.CreateTranslation(0, -0.3f, -1.5f); var hm34 = new HmdMatrix34_t { m0 = m.M11, @@ -729,14 +783,17 @@ namespace VRCX if (!dashboardVisible) { - var texture = new Texture_t + unsafe { - handle = _texture2.NativePointer - }; - err = overlay.SetOverlayTexture(overlayHandle, ref texture); - if (err != EVROverlayError.None) - { - return err; + var texture = new Texture_t + { + handle = (IntPtr)_texture2.Handle + }; + err = overlay.SetOverlayTexture(overlayHandle, ref texture); + if (err != EVROverlayError.None) + { + return err; + } } if (!overlayVisible) diff --git a/Dotnet/VRCX-Cef.csproj b/Dotnet/VRCX-Cef.csproj index fab46707..d1c5ba2b 100644 --- a/Dotnet/VRCX-Cef.csproj +++ b/Dotnet/VRCX-Cef.csproj @@ -1,6 +1,7 @@ ..\build\Cef\ + true WinExe @@ -95,8 +96,10 @@ - - + + + +