繁体   English   中英

在DirectX中跨线程传递纹理的数据竞赛

[英]Data race in passing a texture across threads in DirectX

我在具有两个线程的DirectX应用程序中遇到了数据争用:使用者和生产者。

第一个线程( 生产者 )是屏幕抓取器,它使用桌面复制来获取纹理中的桌面图像。 它在适配器X上创建一个ID3D11Device和ID3D11DeviceContext。

dxgi_dd->AcquireNextFrame(INFINITE, &frame_info, &desktop_resource);

ID3D11Texture2D *desktop_texture;
desktop_resource->QueryInterface(__uuidof(ID3D11Texture2D), (void **)&desktop_texture);
desktop_resource->Release();

D3D11_TEXTURE2D_DESC texture_desc;

memset(&texture_desc, 0, sizeof(texture_desc));
texture_desc.Width = desktop_desc.Width;
texture_desc.Height = desktop_desc.Height;
texture_desc.MipLevels = 1;
texture_desc.ArraySize = 1;
texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texture_desc.SampleDesc.Count = 1;
texture_desc.SampleDesc.Quality = 0;
texture_desc.Usage = D3D11_USAGE_DEFAULT;
texture_desc.BindFlags = 0;
texture_desc.CPUAccessFlags = 0;
texture_desc.MiscFlags = 0;

d3d11_device->CreateTexture2D(&texture_desc, NULL, &return_texture);

// Copy it to a return texture
immediate_context->CopyResource(return_texture, desktop_texture);
immediate_context->Flush();

dxgi_dd->ReleaseFrame();
desktop_texture->Release();

return encapsulate(return_texture); // Thread returns the pointer encapsulated in a structure

第二个线程(消费者) 在同一适配器X ID3D11Device和ID3D11DeviceContext

ID3D11Texture2D *dx_input_texture;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = received_texture.width;
desc.Height = received_texture.height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET;
desc.CPUAccessFlags = 0;
d3d11_device->CreateTexture2D(&desc, NULL, &dx_input_texture)

ID3D11Texture2D *frame_texture = (ID3D11Texture2D*)received_texture.pointer_received_from_other_thread;

immediate_context->CopyResource(dx_input_texture, frame_texture);
immediate_context->Flush();

// Use dx_input_texture now

不幸的是,我在使用这种方法时遇到随机问题(无效的纹理或指针导致其他DX库期望有效的纹理失败),如果我在生产者线程中放置了sleep(1000) ,这些问题就会消失。 这让我觉得这可能是一场数据竞赛。

两个线程之间是否需要同步? 我现在故意跳过纹理Release() (即使我最终可能会用完GPU内存)来调试此数据争用。

  • 您的代码释放指针desktop_texture->Release(); 然后出于某种原因将其返回,这看起来像是一个错字,并且可能应该将其return encapsulate(return_texture);
  • 要使用其他设备处理纹理,您将需要创建带有D3D11_RESOURCE_MISC_SHARED标志的资源,通过调用IDXGIResource::GetSharedHandle将其转换为HANDLE ,然后通过调用ID3D11Device::OpenSharedResource使其可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM