Я испытываю гонку данных в приложении DirectX с двумя потоками: потребителем и производителем.
Первый поток ( производитель ) - это средство захвата экрана, которое использует дублирование рабочего стола , чтобы получить изображение рабочего стола в текстуре.Он создает ID3D11Device и ID3D11DeviceContext на адаптере X.
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
Второй поток (потребитель) ID3D11Device и ID3D11DeviceContext на один и тот же адаптер X
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) для отладки этой гонки данных.