예제 #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();

        SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer, true);
#else
        SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer);

        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;
      }
    }
예제 #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.

        SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer, true);
#else
        SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surface9.NativePointer);


        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;
      }
    }