Beispiel #1
0
        private void InitializeResources(GraphicsDevice graphicsDevice, int width, int height)
        {
            try
            {
                Debug.Assert(_renderTarget == null, "Dispose previous back buffer before creating a new back buffer.");

                // MonoGame
                var format = _enableAlpha ? SurfaceFormat.Bgra32 : SurfaceFormat.Bgr32;
                _renderTarget = new RenderTarget2D(graphicsDevice, width, height, false, format, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);

                // Direct3D 11
                var device11   = (SharpDX.Direct3D11.Device)graphicsDevice.Handle;
                var formatDXGI = D3D11Helper.ToD3D11(format);
                _texture11         = D3D11Helper.CreateSharedResource(device11, width, height, formatDXGI);
                _stagingResource11 = D3D11Helper.CreateStagingResource(device11, _texture11);

                // Direct3D 9
                _texture9         = _d3D9.CreateSharedTexture(_texture11);
                _surface9         = _texture9.GetSurfaceLevel(0);
                _stagingResource9 = _d3D9.CreateStagingResource(_texture11);

                // Direct3D 11 event query.
                Debug.Assert(_isFrameReady, "_isFrameReady should be true when uninitialized.");
                var queryDescription = new SharpDX.Direct3D11.QueryDescription
                {
                    Flags = SharpDX.Direct3D11.QueryFlags.None,
                    Type  = SharpDX.Direct3D11.QueryType.Event
                };
                _query = new SharpDX.Direct3D11.Query(device11, queryDescription);

                // Assign back buffer to D3DImage.
                // The back buffer is still empty, however we need to set a valid back buffer
                // for the layout logic. Otherwise, the size of the D3D11Image is (0, 0).
                Lock();
#if NET45
                SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer, true);
#else
                SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer);
#endif
                Unlock();

                if (IsSynchronized)
                {
                    // Issue a copy of the surface into the staging resource to see when the
                    // resource is no longer used by Direct3D 9.
                    _d3D9.Copy(_surface9, _stagingResource9);
                    _isAvailable9 = _d3D9.TryAccess(_stagingResource9);
                }
            }
            catch
            {
                // GPU may run out of memory.
                UninitializeResources();
                throw;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Unlocks the back buffer and disables render operations.
        /// </summary>
        /// <param name="graphicsDevice">The graphics device.</param>
        public void EndRender(GraphicsDevice graphicsDevice)
        {
            if (!_isLocked) // May appear due to WPF bug (see above).
            {
                return;
            }

            ThrowIfDisposed();

            var device11 = (SharpDX.Direct3D11.Device)graphicsDevice.Handle;

            try
            {
                if (_renderTarget == null)
                {
                    // BeginRender was unsuccessful. (GPU out-of-memory exception.)
                    return;
                }

                // Double-buffering: Copy MonoGame render target into shared resource.
                D3D11Helper.Copy(device11, (SharpDX.Direct3D11.Texture2D)_renderTarget.Handle, _texture11);

                // Place Direct3D 11 event query.
                device11.ImmediateContext.End(_query);
                SharpDX.Bool result;
                _isFrameReady = device11.ImmediateContext.GetData(_query, out result) && result;

                if (IsSynchronized)
                {
                    // Issue a copy of the surface into the staging resource to see when the
                    // resource is no longer used by Direct3D 11.
                    D3D11Helper.Copy(device11, _texture11, _stagingResource11);

                    // Block until the surface is no longer used by Direct3D 11.
                    D3D11Helper.Access(device11, _stagingResource11);
                }
                else
                {
                    // For optimal performance, explicitly flush command buffers.
                    graphicsDevice.Flush();
                }

                // Note: Redundant calls to SetBackBuffer() are a no-op.
#if NET45
                SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer, true);
#else
                SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer);
#endif

                if (IsSynchronized)
                {
                    // Issue a copy of the surface into the staging resource to see when the
                    // resource is no longer used by Direct3D 9.
                    _d3D9.Copy(_surface9, _stagingResource9);
                    _isAvailable9 = _d3D9.TryAccess(_stagingResource9);
                }

                AddDirtyRect(new Int32Rect(0, 0, PixelWidth, PixelHeight));
            }
            finally
            {
                Unlock();
                _isLocked = false;
            }
        }