We have successfully implemented texture sharing across different Direct3D contexts using WrapBackendTexture in a multithreaded environment (4 threads).
Background Thread Code
In the background thread:
GrD3DTextureResourceInfo texResourceInfo = {};
texResourceInfo.fResource = gr_cp<ID3D12Resource>(d3dTexture);
texResourceInfo.fResourceState = D3D12_RESOURCE_STATE_RENDER_TARGET;
texResourceInfo.fFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
texResourceInfo.fSampleCount = 1;
texResourceInfo.fLevelCount = 1;
texResourceInfo.fProtected = GrProtected::kNo;
GrBackendTexture backendTexture(width * scaleFactor, height * scaleFactor, texResourceInfo);
sk_sp<SkSurface> newSurface = SkSurfaces::WrapBackendTexture(
fgrBgContext,
backendTexture,
origin,
1,
colorType,
nullptr,
&surfaceProps,
nullptr, nullptr
);
After drawing on this surface, we flush the commands to the GPU, then share the texture:
directContext->flushAndSubmit();
setTexture(std::make_shared<GrBackendTexture>(backendTexture));
Main Thread Code
In the main thread:
auto sharedTexturePointer = getTexture();
skimage = SkImages::AdoptTextureFrom(dContext.get(), sharedTexturePointer,
kTopLeft_GrSurfaceOrigin,
SkColorType::kRGBA_8888_SkColorType);
Crash Details
We encounter a crash in adoptTextureFrom api call in that while validating the backendTexture in GrBackendTexture::getBackendFormat(), specifically at:
GrBackendFormat GrBackendTexture::getBackendFormat() const {
if (!this->isValid()) {
return GrBackendFormat();
}
// ...
#ifdef SK_DIRECT3D
case GrBackendApi::kDirect3D: {
// Crash occurs here (access reading violation)
auto d3dInfo = fD3DInfo.snapTextureResourceInfo();
return GrBackendFormat::MakeDxgi(d3dInfo.fFormat);
}
#endif
}
Can you explain the underlying concepts and potential issues with sharing GrBackendTexture between Direct3D contexts across threads? What synchronization or context sharing mechanisms are required for D3D12 textures to remain valid when accessed from different GrDirectContext instances?