windows system d3d bit stream media renderer
第一步:创建ID3D11Texture2D
ID3D11Texture2D是DirectX11中的一个纹理对象用于存储和处理图像数据,它允许开发者在GPU上直接操作和处理二维图像数据,从而实现高效的图形渲染和纹理映射。ID3D11Texture2D不仅可以用于存储静态的图像数据,还支持动态地更新纹理数据,这在实时图形处理中尤为重要。通过调整ID3D11Texture2D的大小可以实现图像的缩放和纹理重建以及动态纹理更新等操作,从而满足不同的图形处理需求。
public Renderer(VideoDecoder videoDecoder, IntPtr handle = new IntPtr(), int uniqueId = -1)
{
UniqueId = uniqueId == -1 ? Utils.GetUniqueId() : uniqueId;
VideoDecoder= videoDecoder;
Config = videoDecoder.Config;
singleStageDesc = new Texture2DDescription()
{
Usage = ResourceUsage.Staging,
Format = Format.B8G8R8A8_UNorm,
ArraySize = 1,
MipLevels = 1,
BindFlags = BindFlags.None,
CPUAccessFlags = CpuAccessFlags.Read,
SampleDescription = new SampleDescription(1, 0),
Width = -1,
Height = -1
};
singleGpuDesc = new Texture2DDescription()
{
Usage = ResourceUsage.Default,
Format = Format.B8G8R8A8_UNorm,
ArraySize = 1,
MipLevels = 1,
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
SampleDescription = new SampleDescription(1, 0)
};
wndProcDelegate = new(WndProc);
wndProcDelegatePtr = Marshal.GetFunctionPointerForDelegate(wndProcDelegate);
ControlHandle = handle;
Initialize();
}
第二步:创建D3D11CreateDevice
D3D11CreateDevice函数在Direct3D11编程中扮演着至关重要的角色,它用于创建设备Device和设备上下文DeviceContext。这个函数是Direct3D11初始化阶段的关键部分,通过它开发者可以指定硬件加速HAL或软件模拟REF作为驱动器类型,从而选择使用硬件加速功能还是参考光栅化器进行渲染。此外D3D11CreateDevice还允许开发者指定特定的显示器适配器,通常是主要的显示器适配器,以及选择设备的功能级别,这包括了对所有功能级别的支持或者特定功能级别的选择。设备Device在Direct3D11中是一个核心概念,它提供了创建资源、着色器对象、状态对象、查询对象等功能,并且能够检查硬件功能、进行调试等,可以将其视为资源的提供者,通过ID3D11Device接口实现。设备上下文DeviceContext则用于实际使用这些资源并操纵渲染管道本身,包括绑定资源、着色器对象、状态对象到渲染管道,以及控制渲染和计算管道的执行。ID3D11DeviceContext接口支持两种类型的上下文:即时上下文ImmediateContext和延迟上下文DeferredContext,前者直接链接到渲染管线,后者提供线程安全机制,用于异步线程模型。总的来说D3D11CreateDevice不仅是创建Direct3D11设备的入口点,而且也是配置渲染环境和指定硬件使用方式的关键步骤,对于实现高效的图形渲染和游戏开发至关重要。
public void Initialize(bool swapChain = true)
{
ID3D11Device tempDevice;
IDXGIAdapter1 adapter = null;
var creationFlags = DeviceCreationFlags.BgraSupport /*| DeviceCreationFlags.VideoSupport*/; // Let FFmpeg failed for VA if does not support it
var creationFlagsWarp = DeviceCreationFlags.None;
if (Environment.OSVersion.Version.Major <= 7)
{
for (int i = 0; Engine.Video.Factory.EnumAdapters1(i, out adapter).Success; i++)
{
break;
}
if (D3D11.D3D11CreateDevice(adapter, adapter == null ? DriverType.Hardware : DriverType.Unknown, creationFlags, featureLevelsAll, out tempDevice).Failure)
{
if (D3D11.D3D11CreateDevice(adapter, adapter == null ? DriverType.Hardware : DriverType.Unknown, creationFlags, featureLevels, out tempDevice).Failure)
{
Config.Video.GPUAdapter = "WARP";
D3D11.D3D11CreateDevice(null, DriverType.Warp, creationFlagsWarp, featureLevels, out tempDevice).CheckError();
}
}
Device = tempDevice.QueryInterface<ID3D11Device1>();
}
else
{
if (!string.IsNullOrWhiteSpace(Config.Video.GPUAdapter) && Config.Video.GPUAdapter.ToUpper() != "WARP")
{
for (int i = 0; Engine.Video.Factory.EnumAdapters1(i, out adapter).Success; i++)
{
if (adapter.Description1.Description == Config.Video.GPUAdapter)
break;
if (Regex.IsMatch(adapter.Description1.Description + " luid=" + adapter.Description1.Luid, Config.Video.GPUAdapter, RegexOptions.IgnoreCase))
break;
adapter.Dispose();
}
if (adapter == null)
{
Config.Video.GPUAdapter = null;
}
}
if (!string.IsNullOrWhiteSpace(Config.Video.GPUAdapter) && Config.Video.GPUAdapter.ToUpper()