How to map a d3d11texture in format nv12 to d3d12 with d3d11on12?

I try to get a handle of this d3d11texture : getsharedhandle
, open the handle by the d3d11on12 device : opensharedresource
,and then map the d3d11texture to d3d12
: UnwrapUnderlyingResource
.But i can only get the Y data.
Windows API - Win32
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-20T02:47:24.007+00:00 Could you show how you create NV12 and D3D11_MAPPED_SUBRESOURCE?
-
Logoro 1 Reputation point
2022-04-20T03:35:31.733+00:00 I get the NV12 from ffmpeg d3d11va decoder.
D3D11_TEXTURE2D_DESC texture_desc = {0}; texture_desc.Width = 640; texture_desc.Height = 480; texture_desc.MipLevels = 1; texture_desc.Format = DXGI_FORMAT_NV12; texture_desc.SampleDesc.Count = 1; texture_desc.ArraySize = 1; texture_desc.Usage = D3D11_USAGE_DEFAULT; texture_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; Microsoft::WRL::ComPtr<ID3D11Texture2D> shared_texture_for_ffmpeg_device{nullptr}; ffmpeg_device->CreateTexture2D(&texture_desc, NULL, &shared_texture_for_ffmpeg_device); ffmpeg_device_context->CopySubresourceRegion(shared_texture_for_ffmpeg_device.Get(), 0, 0, 0, 0, (ID3D11Texture2D*)ffmpeg_avframe->data[0], (int)ffmpeg_avframe->data[1], NULL); ffmpeg_device_context->Flush(); Microsoft::WRL::ComPtr<IDXGIResource> dxgi_resource{nullptr}; shared_texture_for_ffmpeg_device.As(&dxgi_resource); HANDLE shared_handle = NULL; dxgi_resource->GetSharedHandle(&shared_handle); dxgi_resource->Release(); Micsoft::WRL::ComPtr<ID3D11Device> my_d3d11_device{nullptr}; my_d3d11on12_device.As(&my_d3d11_device); Microsoft::WRL::ComPtr<ID3D11Texture2D> temp_texture_for_my_device {nullptr}; my_d3d11_device->OpenSharedResource(shared_handle, __uuidof(ID3D11Texture2D), (void**)temp_texture_for_my_device .GetAddressOf()); my_d3d11on12_device->UnwrapUnderlyingResource(temp_texture_for_my_device .Get(), my_d3d12_command_queue.Get(), IID_PPV_ARGS(&my_d3d12_resource));
-
Logoro 1 Reputation point
2022-04-20T03:35:44.553+00:00 If i need read back
ID3D11Texture2D* readback_buffer; ID3D11Texture2D_DESC readback_desc = { 0 }; readback_desc.Width = 640; readback_desc.Height = 480; readback_desc.MipLevels = 1; readback_desc.Format = DXGI_FORMAT_NV12; readback_desc.SampleDesc.Count = 1; readback_desc.ArraySize = 1; readback_desc.Usage = D3D11_USAGE_STAGING; readback_desc.CPUAccessFlags = D3D11CPU_ACCESS_READ | D3D11CPU_ACCESS_WRITE; my_d3d11_device->CreateTexture2D(&readback_desc, NULL, &readback_buffer); my_d3d11_contex->CopyResource(read_back, temp_texture_for_my_device.Get() ); my_d3d11_contex->Flush(); D3D11_MAPPED_SUBRESOURCE mapped; my_d3d11_contex->Map(readback_buffer, 0, D3D11_MAP_READ, 0, &mapped);
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-20T07:53:55.293+00:00 Try this
my_d3d11on12_device->UnwrapUnderlyingResource(temp_texture_for_my_device.Get(), my_d3d12_command_queue.Get(), __uuidof(ID3D12Resource),&my_d3d12_resource);
I think the process you copied conforms to the official instructions. Could you debug the change oftemp_texture_for_my_device
-
Logoro 1 Reputation point
2022-04-20T08:08:43.563+00:00 Thanks for your anwser,but i get a same result.
When i maptemp_texture_for_my_device
to CPU, i can only get the Y datas,but when i mapshared_texture_for_ffmpeg_device
to CPU, it's normal.
I'm confused,it's a same resource with different pointer. -
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-20T08:14:09.61+00:00 or Try this, Not use
AS
,IDXGIResource* dxgi_resource(NULL); shared_texture_for_ffmpeg_device->QueryInterface(__uuidof(IDXGIResource), (void**)& dxgi_resource); HANDLE shared_handle = NULL; dxgi_resource->GetSharedHandle(&shared_handle); dxgi_resource->Release();
-
Logoro 1 Reputation point
2022-04-20T08:20:02.163+00:00 It's not working...
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-20T08:36:31.197+00:00 Could you give me a more complete and reproducible code? Does not contain any personal privacy so that I can reproduce your question.
-
Logoro 1 Reputation point
2022-04-20T09:03:07.883+00:00 Of course.
Create d3d11on12 device:int d3d11_device_flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; Micsoft::WRL::ComPtr<ID3D11Device> d3d11_device; Micsoft::WRL::ComPtr<ID3D11DeviceContext> d3d11_device_context; D3D11On12CreateDevice(my_d3d12_device.Get(), d3d11_device_flags, nullptr, 0, reinerpret_cast<IUnKnow**>(my_d3d12_commadn_queue.GetAddressOf()), 1, 0, &d3d11_device, &d3d11_device_context, nullptr); Micsoft::WRL::ComPtr<ID3D11DeviceContext4> my_d3d11_context; Micsoft::WRL::ComPtr<ID3D11On12Device2> my_d3d11on12_device; d3d11_device.As(&my_d3d11on12_device); d3d11_device_context.As(&my_d3d11_context);
Create d3d12 device:
D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&my_d3d12_device)); D3D12_COMMAND_QUEUE_DESC queue_desc{}; queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; my_d3d12_device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&my_d3d12_queue));
If you need anything else, I can continue to provide.
-
Logoro 1 Reputation point
2022-04-20T09:20:27.03+00:00 When i create staging resource with a same
D3D11_TEXTURE2D_DESC
and map toD3D11_MAPPED_SUBRESOURCE
, the result offfmpeg_device
is different frommy_d3d11_device
's. -
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-20T09:22:21.257+00:00 I will try to reproduce your issue.
-
Logoro 1 Reputation point
2022-04-21T07:35:00.6+00:00 Any good news?
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-21T07:39:11.587+00:00 I'm working on your issue with team engineers and will keep you informed if there is any progress.
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-22T08:35:37.89+00:00 Is this the right result you want?
-
Logoro 1 Reputation point
2022-04-22T08:45:36.373+00:00 Can you get a right result when you pass a nv12 texture?
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-22T08:55:05.787+00:00 try use CreateSharedHandle. If it still fails, Could you please provide the code about
ffmpeg_device
or runnable code without Privacy?ComPtr<IDXGIResource1> dxgi_resource; HANDLE shared_handle = NULL; shared_texture_for_ffmpeg_device->QueryInterface(__uuidof(IDXGIResource1), (void**)& dxgi_resource); dxgi_resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, NULL, &shared_handle); dxgi_resource->GetSharedHandle(&shared_handle); dxgi_resource->Release();
-
Logoro 1 Reputation point
2022-04-22T09:06:46.763+00:00 AVHWFramesContext* ctx = (AVHWFramesContext*)ffmpeg_avframe->hw_frames_ctx->data; AVD3D11VADeviceContext* device_hwctx = (AVD3D11VADeviceContext*)ctx->device_ctx->hectx; ID3D11Device* ffmpeg_device = device_hwctx->device; ID3D11DeviceContext* ffmpeg_device_context = device_hwctx->device_context;
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-22T09:18:27.283+00:00 May I ask your version of ffmpeg?
-
Logoro 1 Reputation point
2022-04-22T09:23:04.903+00:00 V4.2.
-
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-22T09:25:08.937+00:00 I will test it and keep you informed if there is any progress.
-
-
Logoro 1 Reputation point
2022-04-26T06:13:14.157+00:00 I create a srv
srv_desc.Texture2D.PlaneSlice = 1
, but i cann't get any chroma data in my shader. -
Logoro 1 Reputation point
2022-04-26T09:34:52.917+00:00 Thanks for your help,my problem is solved.Maybe d3d think there is only one subresource in
temp_texture_for_my_device
,so when i copytemp_texture_for_my_device
totexture_for_my_device
viaCopyResource
,only the luma data is replicated. -
Junjie Zhu - MSFT 7,666 Reputation points • Microsoft Vendor
2022-04-26T09:48:48.783+00:00 Glad that your problem has been solved. I didn't find
CopyResource
in your code. I tried to reproduce your situation these days but failed. If you have any other questions, please feel free to ask them.
Sign in to comment