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.BgraSuuport 和 DeviceCreationFlags.Debug。级别设置为 FeatureLevel.Level_11_1 到 FeatureLevel.Level_9_1.
using (var device = new Device(DriverType.Hardware, flags, levels))
{
_device = device.QueryInterface<Device1>();
_context = _device.ImmediateContext1;
}
此问题的解决方案是术语 WinRT Core 和 WinRT XAML 具有误导性。由于 UWP 基于 CoreWindow
并且都支持和使用它们,因此不清楚在哪里使用什么。
DirectX 公开了两种用于 WinRT 的方法和一种用于 Desktop 的方法。一个是 Factory2.CreateSwapChainForCoreWindow(...)
,一个是 Factory2.CreateSwapChainForComposition(...)
。不同之处在于,一个以 CoreWindow
作为参数,一个不接受。这就是我掉入的陷阱。
Core 代表 design-scheme 仅使用 IFrameworkView
和 IFrameworkViewSource
(示例见 here使用 SharpDX),而 XAML 代表传统方案,其中您有 Windows.UI.Xaml.Application
class.
使用 Core-model 时,您必须调用 ...ForCoreWindow(...)
方法才能创建交换链。使用基于 XAML 的方法时,您需要一个合成交换链。我自己已经尝试过,但失败了,因为我忘记启用(提示:如果尚未启用,请执行此操作)本机调试,因此 DirectX 调试层实际上向我展示了基本信息,如果不是几天的反复试验,这些信息本可以为我节省数小时。
这里的问题是组合链和 CoreWindow 交换链都需要在 SwapChainDescription1
中进行特殊设置。我会把 MSDN documentation 留给你。此外,如果启用了本机调试和调试层,DirectX 会准确告诉您哪些设置无效。
我目前正在尝试使用最新的 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.BgraSuuport 和 DeviceCreationFlags.Debug。级别设置为 FeatureLevel.Level_11_1 到 FeatureLevel.Level_9_1.
using (var device = new Device(DriverType.Hardware, flags, levels))
{
_device = device.QueryInterface<Device1>();
_context = _device.ImmediateContext1;
}
此问题的解决方案是术语 WinRT Core 和 WinRT XAML 具有误导性。由于 UWP 基于 CoreWindow
并且都支持和使用它们,因此不清楚在哪里使用什么。
DirectX 公开了两种用于 WinRT 的方法和一种用于 Desktop 的方法。一个是 Factory2.CreateSwapChainForCoreWindow(...)
,一个是 Factory2.CreateSwapChainForComposition(...)
。不同之处在于,一个以 CoreWindow
作为参数,一个不接受。这就是我掉入的陷阱。
Core 代表 design-scheme 仅使用 IFrameworkView
和 IFrameworkViewSource
(示例见 here使用 SharpDX),而 XAML 代表传统方案,其中您有 Windows.UI.Xaml.Application
class.
使用 Core-model 时,您必须调用 ...ForCoreWindow(...)
方法才能创建交换链。使用基于 XAML 的方法时,您需要一个合成交换链。我自己已经尝试过,但失败了,因为我忘记启用(提示:如果尚未启用,请执行此操作)本机调试,因此 DirectX 调试层实际上向我展示了基本信息,如果不是几天的反复试验,这些信息本可以为我节省数小时。
这里的问题是组合链和 CoreWindow 交换链都需要在 SwapChainDescription1
中进行特殊设置。我会把 MSDN documentation 留给你。此外,如果启用了本机调试和调试层,DirectX 会准确告诉您哪些设置无效。