3

私は非常に単純なモデリング ソフトウェアを作成していますが、何よりも挑戦的なものです。約 3 週間前までは、SwapChain.ResizeBuffers() 関数に問題はありませんでした。

PC を変更し、(Pro 9 から) Visual Studio Express 2012 に切り替え、対応する SlimDX.dll を使用してソリューションを x64 に切り替えました。

それでも問題なく動作しますが、ビューポートをホストしているウィンドウのサイズを変更すると、DXGI_ERROR_INVALID_CALL (-2005270527) になります。

Google で簡単に検索すると、Battlefield 3 にも特定のドライバーで問題が発生する可能性があることがわかります。出来ますか?

私はその機能について見つけることができるすべてを読みましたが、どういうわけか、現在混乱している変更を見つけることができません。うまくいけば、誰かが私が間違っていることを理解できるでしょう。

    // Form we are attached to.
    private Dockable dock;

    // Rendering stuff.
    private Device device;
    private Viewport viewport;
    private SwapChain swapChain;
    private RenderTargetView renderView;
    private DepthStencilView depthView;

    public Renderer(Dockable form)
    {
        if (form == null)
            return;

        dock = form;

        CreateSwapchain();
        Resize();
    }

    private void CreateSwapchain()
    {
        // Swap Chain & Device
        SwapChainDescription description = new SwapChainDescription()
        {
            BufferCount = 1,
            Usage = Usage.RenderTargetOutput,
            OutputHandle = dock.Handle,
            IsWindowed = true,
            ModeDescription = new ModeDescription(dock.ClientSize.Width, dock.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
            SampleDescription = new SampleDescription(1, 0),
            Flags = SwapChainFlags.AllowModeSwitch,
            SwapEffect = SwapEffect.Discard
        };

        Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, description, out device, out swapChain);
    }

    private void CreateRenderView()
    {
        // Dispose before resizing.
        if (renderView != null)
            renderView.Dispose();

        if (depthView != null)
            depthView.Dispose();

        swapChain.ResizeBuffers(0, 0, 0, Format.Unknown, 0); // ERROR : DXGI_ERROR_INVALID_CALL when resizing the window, but not when creating it.
        renderView = new RenderTargetView(device, Resource.FromSwapChain<Texture2D>(swapChain, 0));

        Texture2DDescription depthBufferDesc = new Texture2DDescription()
        {
            ArraySize = 1,
            BindFlags = BindFlags.DepthStencil,
            CpuAccessFlags = CpuAccessFlags.None,
            Format = Format.D16_UNorm,
            Height = dock.ClientSize.Height,
            Width = dock.ClientSize.Width,
            MipLevels = 1,
            OptionFlags = ResourceOptionFlags.None,
            SampleDescription = new SampleDescription(1, 0),
            Usage = ResourceUsage.Default
        };

        depthView = new DepthStencilView(device, new Texture2D(device, depthBufferDesc));
    }

    public void Resize()
    {
        CreateRenderView();

        viewport = new Viewport(0.0f, 0.0f, dock.ClientSize.Width, dock.ClientSize.Height);
        device.ImmediateContext.Rasterizer.SetViewports(viewport);
        device.ImmediateContext.OutputMerger.SetTargets(depthView, renderView);
    }
4

1 に答える 1

4

サイズを変更する前に、スワップ チェーンに関連付けられているすべてのリソースを解放する必要があります。

これにはレンダー ビュー (ユーザーが行う) が含まれますが、レンダー ターゲット ビューを作成するときに、リソースに対して addref を実行します。

Resource.FromSwapChain<Texture2D>(swapChain, 0)

テクスチャに参照カウンターを追加します。キャッシュしないため、解放できません。

したがって、次のことを行う必要があります。

Texture2D resource = Texture2D.FromSwapChain<Texture2D>(swapChain, 0);
renderView = new RenderTargetView(device, resource);

次に、サイズ変更を呼び出す前に:

if (resource != null) { resource.Dispose(); }

私のエンジンでテストしたところ、動作しました(また、0で正しかったので、動作します)。

于 2012-10-16T20:37:28.760 に答える