我正在尝试使用Windows Graphics Capture Api(windows-capture)构建一个屏幕捕获库,但是在处理映射缓冲区image stride时遇到了问题,这是每个RowPitch末尾的空缓冲区。目前我是这样处理的:
let row_size = self.width as usize * std::mem::size_of::<Rgba>();
for i in 0..self.height {
unsafe {
ptr::copy_nonoverlapping(
mapped_resource
.pData
.add((i * mapped_resource.RowPitch) as usize)
as *mut u8,
self.buffer.add(i as usize * row_size),
row_size,
)
};
}
这个方法有点慢(在我的CPU上需要4毫秒),有没有办法在GPU上做,这样会更快一些?我试过使用计算着色器,但没有成功。
我基本上想要以最快的方式获取屏幕像素数据缓冲区,存储在一个[u8]中。
谢谢你的帮助。
Map
可能会阻塞。尝试先将数据复制到D3D11_USAGE_STAGING
缓冲区,然后再映射该缓冲区。然而,您需要进行同步,即使用一个栅栏,以确保在映射之前复制操作已完成。 - undefinedMap
pingD3D11_USAGE_DEFAULT
和D3D11_USAGE_STAGING
资源之间的区别。D3D11_USAGE_DEFAULT
是由GPU支持的内存,当进行映射时,运行时会从GPU复制到CPU创建CPU支持的内存副本,然后阻塞等待复制完成,然后给你指针。为了避免阻塞,你需要将其复制到D3D11_USAGE_STAGING
资源并进行映射。 - undefinedptr::copy_nonoverlapping
之前D3D11的复制已经完成了吗?可能发生了一些有趣的事情,请参考https://stackoverflow.com/a/75871029/11998382。 - undefinedmapped_resource
。也许你的计时有问题,4毫秒太慢了。 - undefined