DirectX - 为 CoreWindow 创建交换链时访问被拒绝

DirectX - Access denied when creating swap chain for CoreWindow

我目前正在尝试使用最新的 SharpDX 作为 DirectX 包装器并使用 UWP 作为项目基础框架为 CoreWindow 创建交换链。

关于它的文档太少了,令人难以置信。尽管如此,我还是能找到一个看起来很有希望的片段。最初我总是收到 E_INVALIDCALL 错误消息。现在是 "only" E_ACCESSDENIED.

到目前为止,我已经完成了设置链的操作:

var description = new SwapChainDescription1
{
    BufferCount = 2,
    Flags = SwapChainFlags.None,
    SampleDescription = new SampleDescription(1, 0),
    SwapEffect = SwapEffect.FlipSequential,
    Usage = Usage.RenderTargetOutput,
    Width = 0,
    Height = 0,
    Scaling = Scaling.None,
    Format = Format.B8G8R8A8_UNorm,
    Stereo = false
};

CoreWindow window = CoreWindow.GetForCurrentThread();
if (window == null)
{
    Logging.Error("Could not retrieve core window for swap chain.");
    throw new Exception("Invalid core window.");
}

using (var device = _device.QueryInterface<SharpDX.DXGI.Device2>())
{
    device.MaximumFrameLatency = 1;
    using (Adapter adapter = device.Adapter)
    {
        using (ComObject coreWindow = new ComObject(window))
        {
            using (Factory2 factory = adapter.GetParent<Factory2>())
                _swapChain = new SwapChain1(factory, _device, coreWindow, ref description);
        }
    }
}

SwapChain1的构造函数抛出SharpDX异常:

SharpDX.Result.CheckError() SharpDX.DXGI.Factory2.CreateSwapChainForCoreWindow(ComObject deviceRef, ComObject windowRef, SwapChainDescription1& descRef, Output restrictToOutputRef, SwapChain1 swapChainOut) SharpDX.DXGI.SwapChain1..ctor(Factory2 factory, ComObject device, ComObject coreWindow, SwapChainDescription1& description, Output restrictToOutput) RobInspect.Visualizer.Rendering.RenderingPanel.InitializeSizeDependentResources() RobInspect.Visualizer.Rendering.RenderingPanel.InitializeDevice()

"HRESULT: [0x80070005], Module: [General], ApiCode: [E_ACCESSDENIED/General access denied error], Message: Access is denied. "

谁能解释一下为什么? "Access denied" 是一个相当宽泛的陈述,我对 DirectX 的内部结构不是很了解。

更多信息:代码在主 (UI) 线程上执行。所以我想我可以排除无法访问 CoreWindow 引用。由于这是第一次初始化,我还排除了在创建交换链之前 DirectX 对象未被正确释放的可能性。

编辑: 这是创建设备的代码。而标志设置为 DeviceCreationFlags.BgraSuuportDeviceCreationFlags.Debug。级别设置为 FeatureLevel.Level_11_1FeatureLevel.Level_9_1.

using (var device = new Device(DriverType.Hardware, flags, levels))
{
    _device = device.QueryInterface<Device1>();
    _context = _device.ImmediateContext1;
}

此问题的解决方案是术语 WinRT CoreWinRT XAML 具有误导性。由于 UWP 基于 CoreWindow 并且都支持和使用它们,因此不清楚在哪里使用什么。

DirectX 公开了两种用于 WinRT 的方法和一种用于 Desktop 的方法。一个是 Factory2.CreateSwapChainForCoreWindow(...),一个是 Factory2.CreateSwapChainForComposition(...)。不同之处在于,一个以 CoreWindow 作为参数,一个不接受。这就是我掉入的陷阱。

Core 代表 design-scheme 仅使用 IFrameworkViewIFrameworkViewSource(示例见 here使用 SharpDX),而 XAML 代表传统方案,其中您有 Windows.UI.Xaml.Application class.

使用 Core-model 时,您必须调用 ...ForCoreWindow(...) 方法才能创建交换链。使用基于 XAML 的方法时,您需要一个合成交换链。我自己已经尝试过,但失败了,因为我忘记启用(提示:如果尚未启用,请执行此操作)本机调试,因此 DirectX 调试层实际上向我展示了基本信息,如果不是几天的反复试验,这些信息本可以为我节省数小时。

这里的问题是组合链和 CoreWindow 交换链都需要在 SwapChainDescription1 中进行特殊设置。我会把 MSDN documentation 留给你。此外,如果启用了本机调试和调试层,DirectX 会准确告诉您哪些设置无效。