当前位置:网站首页>DXGI acquisition process
DXGI acquisition process
2022-07-27 14:50:00 【Clear water welcomes the rising sun】
Catalog
One 、DXGI technological process
One 、DXGI technological process
DXGI The full name is Microsoft DirectX Graphics Infrastructure, Microsoft graphics device infrastructure .
Its work , It is to provide the interface support of the underlying hardware device for the graphics library .
Because of it , It also enables interaction between different graphic libraries , Because in DXGI in , The interface of resources is IDXGIResource, It can be converted into the interface of the upper graphic library , Such as D3D The texture of .
This article , It mainly introduces the use of DXGI Collection desktop , Compared with the traditional GDI The way , A lot more powerful .
1、 Official information
DXGI
Desktop Duplication API - Win32 apps | Microsoft Docs
2、 The official sample
You can also download it here :https://download.csdn.net/download/shuilan0066/86260425
But this example is complicated ,
The following example is simpler , from github Download from , I forgot the original address
https://download.csdn.net/download/shuilan0066/86260562
3、 Collect desktop process
The key is To get IDXGIOutputDuplication Interface , Then get desktop data through this interface
1)、 get D3D equipment
typedef struct _DX_RESOURCES
{
ID3D11Device* Device;
ID3D11DeviceContext* Context;
ID3D11VertexShader* VertexShader;
ID3D11PixelShader* PixelShader;
ID3D11InputLayout* InputLayout;
ID3D11SamplerState* SamplerLinear;
} DX_RESOURCES;DUPL_RETURN InitializeDx()
{
HRESULT hr = S_OK;
// Driver types supported
D3D_DRIVER_TYPE DriverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
// Feature levels supported
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
D3D_FEATURE_LEVEL FeatureLevel;
// Create device
for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
{
hr = D3D11CreateDevice(nullptr, DriverTypes[DriverTypeIndex], nullptr, 0, FeatureLevels, NumFeatureLevels,
D3D11_SDK_VERSION, &m_DxRes->Device, &FeatureLevel, &m_DxRes->Context);
if (SUCCEEDED(hr))
{
// Device creation success, no need to loop anymore
break;
}
}
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to create device in InitializeDx", hr);
}
return DUPL_RETURN_SUCCESS;
} DX_RESOURCES *m_DxRes; m_DxRes = new (std::nothrow) DX_RESOURCES;
RtlZeroMemory(m_DxRes, sizeof(DX_RESOURCES));
DUPL_RETURN Ret = InitializeDx();
if (Ret != DUPL_RETURN_SUCCESS)
{
fprintf_s(log_file, "DX_RESOURCES couldn't be initialized.");
return Ret;
}2)、 get DXGI equipment
// Get DXGI device
IDXGIDevice* DxgiDevice = nullptr;
HRESULT hr = m_DxRes->Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice));
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for DXGI Device", hr);
}3)、 obtain DXGI Adapter
Adapter It can be understood as the abstract layer of our graphics card . When we create D3D Equipment time , In fact, which graphics card has been specified in the parameters , I did NULL, And the designation is of hardware type , So it will specify a default ( Of course , I just have a graphics card ). besides , You can also get IDXGIFactory object , And then call EnumAdapters Method to get something Adapter. The code is as follows
// Get DXGI adapter
IDXGIAdapter* DxgiAdapter = nullptr;
hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter));
DxgiDevice->Release();
DxgiDevice = nullptr;
if (FAILED(hr))
{
return ProcessFailure(m_DxRes->Device, L"Failed to get parent DXGI Adapter", hr, SystemTransitionsExpectedErrors);
}4)、 obtain DXGI Output
After specifying the graphics card , We are about to specify its output . We know , Sometimes we may use more than one monitor , obviously , The graphics card supports multiple display devices for output , So we need to specify which output device , We need to call IDXGIAdapter Inside EnumOutputs Method , I just have a monitor , The first parameter is filled directly 0 Just a matter of .
// Get output
IDXGIOutput* DxgiOutput = nullptr;
hr = DxgiAdapter->EnumOutputs(0, &DxgiOutput);
DxgiAdapter->Release();
DxgiAdapter = nullptr;
if (FAILED(hr))
{
return ProcessFailure(m_DxRes->Device, L"Failed to get specified output in DUPLICATIONMANAGER", hr, EnumOutputsExpectedErrors);
}5)、 obtain DXGI Output1
At this time, readers who see this title may ask again ,output1 What the hell is it , I just got it output Why? . Of course ,output1 Nor does it represent the first display , It can be said to be output An extension of , It's in DXGI 1.2 After the launch of , It contains us Desktop Duplication API Interface . Maybe Microsoft wants to be compatible with the previous interface , Let's get output, And then through output To get to the output1. obtain DXGI output1 The code for is as follows :
DxgiOutput->GetDesc(&m_OutputDesc);
// QI for Output 1
IDXGIOutput1* DxgiOutput1 = nullptr;
hr = DxgiOutput->QueryInterface(__uuidof(DxgiOutput1), reinterpret_cast<void**>(&DxgiOutput1));
DxgiOutput->Release();
DxgiOutput = nullptr;
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for DxgiOutput1 in DUPLICATIONMANAGER", hr);
}6)、 obtain Output Duplication
In what we just got output1 in , You can call DuplicateOutput Method to get Output Duplication, Then we can use it to collect desktop images
IDXGIOutputDuplication* m_DeskDupl;
// Create desktop duplication
hr = DxgiOutput1->DuplicateOutput(m_DxRes->Device, &m_DeskDupl);
DxgiOutput1->Release();
DxgiOutput1 = nullptr;
if (FAILED(hr))
{
if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
{
MessageBoxW(nullptr, L"There is already the maximum number of applications using the Desktop Duplication API running, please close one of those applications and then try again.", L"Error", MB_OK);
return DUPL_RETURN_ERROR_UNEXPECTED;
}
return ProcessFailure(m_DxRes->Device, L"Failed to get duplicate output in DUPLICATIONMANAGER", hr, CreateDuplicationExpectedErrors);
}7)、 obtain Output Desc
Before collecting desktop , We need information about display devices , In this way, it is convenient for us to do coding and rendering in the future , Such as the width and height of the display , The refresh rate , Pixel format , Scanning mode , Zoom format and so on . call GetDesc Method , We can get a structure object related to this information , You can read through it , The code is as follows :
DXGI_OUTDUPL_DESC lOutputDuplDesc;
m_DeskDupl->GetDesc(&lOutputDuplDesc);8)、 Get desktop image
At this point , We can get the desktop image , Call directly AcquireNextFrame that will do , The code is as follows :
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(0, &FrameInfo, &DesktopResource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
return DUPL_RETURN_SUCCESS;
}
if (FAILED(hr))
{
return ProcessFailure(m_DxRes->Device, L"Failed to acquire next frame in DUPLICATIONMANAGER", hr, FrameInfoExpectedErrors);
}
IDXGIResource This is our image . We can't directly access the data inside , These data exist in video memory .
For NVIDIA's hard coding , It must be in the graphics card , So theoretically, we can throw it directly to help us code . However , NVIDIA does not support IDXGIResource Form of image input , But support DirectX Texture input (dx The minimum version is 9, Is the highest 11,12 It is not supported in official documents ), therefore , We need to turn it into dx texture , Can be thrown in for coding .
9)、 Create texture
D3D11_TEXTURE2D_DESC desc;
DXGI_OUTDUPL_DESC lOutputDuplDesc;
m_DeskDupl->GetDesc(&lOutputDuplDesc);
desc.Width = lOutputDuplDesc.ModeDesc.Width;
desc.Height = lOutputDuplDesc.ModeDesc.Height;
desc.Format = lOutputDuplDesc.ModeDesc.Format;
desc.ArraySize = 1;
desc.BindFlags = 0;
desc.MiscFlags = 0;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.MipLevels = 1;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.Usage = D3D11_USAGE_STAGING;
hr = m_DxRes->Device->CreateTexture2D(&desc, NULL, &m_DestImage);
if (FAILED(hr))
{
ProcessFailure(nullptr, L"Creating cpu accessable texture failed.", hr);
return DUPL_RETURN_ERROR_UNEXPECTED;
}
if (m_DestImage == nullptr)
{
ProcessFailure(nullptr, L"Creating cpu accessable texture failed.", hr);
return DUPL_RETURN_ERROR_UNEXPECTED;
} ID3D11Texture2D* m_AcquiredDesktopImage;
// If still holding old frame, destroy it
if (m_AcquiredDesktopImage)
{
m_AcquiredDesktopImage->Release();
m_AcquiredDesktopImage = nullptr;
}
// QI for IDXGIResource
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for ID3D11Texture2D from acquired IDXGIResource in DUPLICATIONMANAGER", hr);
}
10)、 Copy image data
void CopyImage(BYTE* ImageData)
{
m_DxRes->Context->CopyResource(m_DestImage, m_AcquiredDesktopImage);
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0, 0, 0);
m_DxRes->Context->Map(m_DestImage, subresource, D3D11_MAP_READ, 0, &resource);
BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
//Store Image Pitch
m_ImagePitch = resource.RowPitch;
int height = GetImageHeight();
memcpy_s(ImageData, resource.RowPitch*height, sptr, resource.RowPitch*height);
m_DxRes->Context->Unmap(m_DestImage, subresource);
DoneWithFrame();
} Reference material :
Windows Live software development ——DXGI - Nuggets
【 Technology sharing 】Windows Desktop recording screen acquisition implementation tutorial
Use DirectX Equipment resources - Win32 apps | Microsoft Docs
边栏推荐
- poj3461 Oulipo【KMP】
- CPU、GPU、NPU的区别
- Toward Fast, Flexible, and Robust Low-Light Image Enhancement(实现快速、灵活和稳健的弱光图像增强)CVPR2022
- mysql保存数据提示:Out of range value for column错误
- printf函数缓冲区问题
- STM32 - capacitive touch button experiment
- Advanced MySQL III. storage engine
- 文献翻译__基于自适应全变差L1正则化的椒盐图像去噪
- [ManageEngine] what is Siem
- How to solve cache avalanche, breakdown and penetration problems
猜你喜欢

这年头谁还不会抓包,WireShark 抓包及常用协议分析送给你!
Database storage series (1) column storage

FPGA timing constraint sharing 04_ Output delay constraint

idea打jar包与引入jar包
![Detailed explanation of Telnet remote login AAA mode [Huawei ENSP]](/img/48/dd0fa3c494c45f604b7a93c707b808.png)
Detailed explanation of Telnet remote login AAA mode [Huawei ENSP]

Tencent two sides: @bean and @component are used in the same class, what will happen?

Airport cloud business sign analysis
![[ManageEngine] what is Siem](/img/a6/0fbe60df6bef337a91a10fe046aa8a.jpg)
[ManageEngine] what is Siem

一篇文章看懂JS执行上下文

视觉系统设计实例(halcon-winform)-10.PLC通讯
随机推荐
一文搞懂 Redis 架构演化之路
力扣SQL语句习题,错题记录
np. Usage and difference of range() and range()
Graphic SQL of giant image
User question understanding and answer content organization for epidemic disease Science Popularization
线程知识总结
STM32 - capacitive touch button experiment
软件产品第三方测试费用为什么没有统一的报价?
[medical industry] DICOM converter tools
Architecture - the sublimation of MVC
Disk troubleshooting of kubernetes node
Docker practical experience: deploy mysql8 master-slave replication on docker
web上构建3d效果 基于three.js的实例
Document translation__ Salt and pepper image denoising based on adaptive total variation L1 regularization
Unityui aspect processing (induction and accumulation)
Secondary spanning tree [template]
Detoxify! After Harbin Institute of technology was disabled MATLAB, domestic industrial software fought back domineering
<C> C语言哈希表使用
telnet远程登录aaa模式详解【华为eNSP】
Toward Fast, Flexible, and Robust Low-Light Image Enhancement(实现快速、灵活和稳健的弱光图像增强)CVPR2022