DirectX 11共享纹理加锁

共享纹理使用场景:
当硬解码的纹理跨两个device对象(对应一张显卡)传递,比如解码是device1,渲染是device2,此时需要通过共享纹理将解码得到的纹理先拷贝到共享纹理上,然后获取纹理句柄,将该句柄传递给渲染的device2,渲染的device2打开该句柄就可以得到一个纹理进行采样渲染了。
如果不加锁,绘制大分辨率的视频或者输出大分辨的画面时就会有撕裂现象。

具体步骤如下:

1.获取解码的纹理。

ID3D11VideoDecoderOutputView* srcSurface = (ID3D11VideoDecoderOutputView*)(uintptr_t)frame->m_frame->data[3];
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
srcSurface->GetDesc(&viewDesc);
int slice = viewDesc.Texture2D.ArraySlice;
ComPtr<ID3D11Texture2D> srcTexture;
srcSurface->GetResource((ID3D11Resource**)srcTexture.GetAddressOf());

2.创建共享纹理

D3D11_TEXTURE2D_DESC dstTexDesc;
ZeroMemory(&dstTexDesc, sizeof(dstTexDesc));
dstTexDesc.Width = frame->getWidth();
dstTexDesc.Height = frame->getHeight();
dstTexDesc.MipLevels = 1;
dstTexDesc.ArraySize = 1;
dstTexDesc.Format = DXGI_FORMAT_NV12;
dstTexDesc.SampleDesc.Count = 1;
dstTexDesc.Usage = D3D11_USAGE_DEFAULT;
dstTexDesc.BindFlags =  D3D11_BIND_SHADER_RESOURCE| D3D11_BIND_RENDER_TARGET;
dstTexDesc.CPUAccessFlags = 0;
dstTexDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; //带锁的共享纹理 注意:D3D11_RESOURCE_MISC_SHARED_NTHANDLE该标志会导致花瓶,谨慎使用
//dstTexDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
HRESULT hr = m_device->CreateTexture2D(&dstTexDesc, nullptr, m_sharedTexture_HW.ReleaseAndGetAddressOf());

3.获取共享纹理句柄和锁

//获取纹理的锁
 m_sharedTexture_HW.As(&m_sharedkeyMutex0);

//获取纹理的句柄
 ComPtr<IDXGIResource1> sharedResource = nullptr;
 m_sharedTexture_HW->QueryInterface(__uuidof(IDXGIResource1), reinterpret_cast<void**>(sharedResource.ReleaseAndGetAddressOf()));
 //D3D11_RESOURCE_MISC_SHARED_NTHANDLE 该标志使用下面的方式获取纹理句柄
 //sharedResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &m_sharedHandle0_SW);
 sharedResource->GetSharedHandle(&m_sharedHandle_HW);
 sharedResource.Reset();
 

5.更新纹理时加锁

//blt转换方式更新纹理
m_sharedkeyMutex0->AcquireSync(0, INFINITE);
bool processFlag = m_d3d11VideoPorcessor->process(srcTexture.Get(), viewDesc.Texture2D.ArraySlice);
m_sharedkeyMutex0->ReleaseSync(0);

//另一种copy方式更新纹理
m_sharedkeyMutex0->AcquireSync(0, INFINITE);
m_pd3dDeviceContext->CopySubresourceRegion( m_sharedTexture_HW.Get(), 0, 0, 0, 0, srcTexture.Get(), slice, nullptr);
m_sharedkeyMutex0->ReleaseSync(0);

6.渲染设备打开共享纹理句柄

ComPtr<ID3D11Texture2D> pTexture0;
ComPtr<IDXGIKeyedMutex> sharedkeyMutex;
HRESULT hr = m_pd3dDevice->OpenSharedResource(m_sharedHandle_HW, __uuidof(ID3D11Texture2D), (void**)(&pTexture0));
pTexture0.As(&sharedkeyMutex);

7.绘制前加锁,绘制完解锁

 sharedkeyMutex->AcquireSync(0, INFINITE);
 deviceContext->DrawIndexed(m_IndexCount, 0, 0);
 sharedkeyMutex->ReleaseSync(0);
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Unity是一款广泛应用于游戏开发的跨平台游戏引擎,而DX11则是较新一代的DirectX图形API。共享纹理是Unity和DX11之间的一种交互方式,用于在Unity中使用DX11的功能。下面将就Unity中DX11共享纹理进行简要阐述。 首先,DX11共享纹理允许在Unity和DX11之间实现纹理资源的共享,这意味着可以在Unity中创建纹理,然后将其传递给DX11进行进一步的图形渲染处理。这种共享可以通过创建和管理ID3D11Texture2D对象来实现。 其次,为了在Unity中使用DX11共享纹理,需要建立一个安装了DX11支持的插件。这个插件将提供一些接口和函数,使得Unity能够与DX11进行交互。在使用DX11共享纹理时,需要在Unity中导入插件并设置相关的渲染纹理。 另外,由于Unity使用的是OpenGL图形API,而不是DX11,因此在使用DX11共享纹理时需要对纹理进行格式转换以适应OpenGL。这可以通过将DX11纹理复制到辅助纹理中,并将其绑定到OpenGL纹理进行实现。 最后,Unity中的脚本可以使用DX11共享纹理进行更高级的图形处理,例如实现自定义的图形特效、着色器等。通过将Unity和DX11结合起来,可以获得更高质量和更灵活的图像渲染效果,从而提升游戏的视觉体验。 总的来说,Unity中的DX11共享纹理能够实现Unity和DX11之间的纹理资源共享,需要使用支持DX11的插件并进行纹理格式转换。这种搭配可以提供更多的图形渲染功能和更好的图像效果,让游戏开发者能够更自由地实现各种图形特效和着色器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhh-cy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值