78 WaitForSingleObjectEx(
ctx, INFINITE, FALSE);
88 uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->
fence);
89 if (completion < psync_ctx->fence_value) {
90 if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->
fence, psync_ctx->
fence_value, psync_ctx->
event)))
93 WaitForSingleObjectEx(psync_ctx->
event, INFINITE, FALSE);
109 ID3D12Resource **ppResource,
int download)
113 D3D12_HEAP_PROPERTIES props = { .Type = download ? D3D12_HEAP_TYPE_READBACK : D3D12_HEAP_TYPE_UPLOAD };
114 D3D12_RESOURCE_DESC
desc = {
115 .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
117 .Width =
s->luma_component_size + (
s->luma_component_size >> 1),
119 .DepthOrArraySize = 1,
121 .Format = DXGI_FORMAT_UNKNOWN,
122 .SampleDesc = { .Count = 1, .Quality = 0 },
123 .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
124 .Flags = D3D12_RESOURCE_FLAG_NONE,
127 if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->
device, &props, D3D12_HEAP_FLAG_NONE, &
desc,
128 states,
NULL, &IID_ID3D12Resource, (
void **)ppResource))) {
142 D3D12_COMMAND_QUEUE_DESC queue_desc = {
143 .Type = D3D12_COMMAND_LIST_TYPE_COPY,
148 s->luma_component_size =
FFALIGN(
ctx->width * (frames_hwctx->
format != DXGI_FORMAT_NV12 ? 2 : 1),
149 D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) *
ctx->height;
151 DX_CHECK(ID3D12Device_CreateFence(device_hwctx->
device, 0, D3D12_FENCE_FLAG_NONE,
152 &IID_ID3D12Fence, (
void **)&
s->sync_ctx.fence));
154 s->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE,
NULL);
155 if (!
s->sync_ctx.event)
158 DX_CHECK(ID3D12Device_CreateCommandQueue(device_hwctx->
device, &queue_desc,
159 &IID_ID3D12CommandQueue, (
void **)&
s->command_queue));
161 DX_CHECK(ID3D12Device_CreateCommandAllocator(device_hwctx->
device, queue_desc.Type,
162 &IID_ID3D12CommandAllocator, (
void **)&
s->command_allocator));
164 DX_CHECK(ID3D12Device_CreateCommandList(device_hwctx->
device, 0, queue_desc.Type,
165 s->command_allocator,
NULL, &IID_ID3D12GraphicsCommandList, (
void **)&
s->command_list));
167 DX_CHECK(ID3D12GraphicsCommandList_Close(
s->command_list));
169 ID3D12CommandQueue_ExecuteCommandLists(
s->command_queue, 1, (ID3D12CommandList **)&
s->command_list);
183 if (
s->sync_ctx.event)
184 CloseHandle(
s->sync_ctx.event);
199 int nb_sw_formats = 0;
208 D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = {
supported_formats[
i].d3d_format };
209 hr = ID3D12Device_CheckFeatureSupport(device_hwctx->
device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support,
sizeof(format_support));
210 if (SUCCEEDED(hr) && (format_support.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
233 if (
frame->sync_ctx.event)
234 CloseHandle(
frame->sync_ctx.event);
249 DX_CHECK(ID3D12Device_CreateFence(device_hwctx->
device, 0, D3D12_FENCE_FLAG_NONE,
250 &IID_ID3D12Fence, (
void **)&
frame->sync_ctx.fence));
251 frame->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE,
NULL);
252 if (!
frame->sync_ctx.event)
255 if (
s->nb_surfaces_used >=
ctx->initial_pool_size) {
261 frame->subresource_index =
s->nb_surfaces_used;
268 s->nb_surfaces_used++;
287 D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
288 D3D12_RESOURCE_DESC
desc = {
289 .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
292 .Height =
ctx->height,
293 .DepthOrArraySize = 1,
296 .SampleDesc = {.Count = 1, .Quality = 0 },
297 .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
305 if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->
device, &props, hwctx->
heap_flags, &
desc,
306 D3D12_RESOURCE_STATE_COMMON,
NULL, &IID_ID3D12Resource, (
void **)&
frame->texture))) {
311 DX_CHECK(ID3D12Device_CreateFence(device_hwctx->
device, 0, D3D12_FENCE_FLAG_NONE,
312 &IID_ID3D12Fence, (
void **)&
frame->sync_ctx.fence));
314 frame->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE,
NULL);
315 if (!
frame->sync_ctx.event)
334 D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
336 D3D12_RESOURCE_DESC
desc = {
337 .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
340 .Height =
ctx->height,
341 .DepthOrArraySize =
ctx->initial_pool_size,
344 .SampleDesc = {.Count = 1, .Quality = 0 },
345 .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
349 if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->
device, &props, hwctx->
heap_flags, &
desc,
350 D3D12_RESOURCE_STATE_COMMON,
NULL, &IID_ID3D12Resource, (
void **)&hwctx->
texture_array))) {
365 if (hwctx->
format != DXGI_FORMAT_UNKNOWN &&
407 D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
429 fmts[0] =
ctx->sw_format;
450 ID3D12Resource *texture = (ID3D12Resource *)
f->texture;
452 uint8_t *mapped_data;
456 D3D12_TEXTURE_COPY_LOCATION staging_y_location = { 0 };
457 D3D12_TEXTURE_COPY_LOCATION staging_uv_location = { 0 };
459 D3D12_TEXTURE_COPY_LOCATION texture_y_location = {
460 .pResource = texture,
461 .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
462 .SubresourceIndex = 0,
465 D3D12_TEXTURE_COPY_LOCATION texture_uv_location = {
466 .pResource = texture,
467 .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
468 .SubresourceIndex = 1,
471 D3D12_RESOURCE_BARRIER barrier = {
472 .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
473 .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
475 .pResource = texture,
476 .StateBefore = D3D12_RESOURCE_STATE_COMMON,
477 .StateAfter = download ? D3D12_RESOURCE_STATE_COPY_SOURCE : D3D12_RESOURCE_STATE_COPY_DEST,
478 .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
482 if (
frame->hw_frames_ctx->data != (uint8_t *)
ctx || other->
format !=
ctx->sw_format)
487 if (!
s->command_queue) {
493 for (
int i = 0;
i < 4;
i++)
495 D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
497 staging_y_location = (D3D12_TEXTURE_COPY_LOCATION) {
498 .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
502 .Format = frames_hwctx->
format != DXGI_FORMAT_NV12 ?
503 DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM,
505 .Height =
ctx->height,
507 .RowPitch = linesizes[0],
512 staging_uv_location = (D3D12_TEXTURE_COPY_LOCATION) {
513 .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
515 .Offset =
s->luma_component_size,
517 .Format = frames_hwctx->
format != DXGI_FORMAT_NV12 ?
518 DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM,
519 .Width =
ctx->width >> 1,
520 .Height =
ctx->height >> 1,
522 .RowPitch = linesizes[0],
527 DX_CHECK(ID3D12CommandAllocator_Reset(
s->command_allocator));
529 DX_CHECK(ID3D12GraphicsCommandList_Reset(
s->command_list,
s->command_allocator,
NULL));
532 if (!
s->staging_download_buffer) {
534 &
s->staging_download_buffer, 1);
540 staging_y_location.pResource = staging_uv_location.pResource =
s->staging_download_buffer;
542 ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
544 ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
545 &staging_y_location, 0, 0, 0,
546 &texture_y_location,
NULL);
548 ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
549 &staging_uv_location, 0, 0, 0,
550 &texture_uv_location,
NULL);
552 barrier.Transition.StateBefore = barrier.Transition.StateAfter;
553 barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
554 ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
556 DX_CHECK(ID3D12GraphicsCommandList_Close(
s->command_list));
558 DX_CHECK(ID3D12CommandQueue_Wait(
s->command_queue,
f->sync_ctx.fence,
f->sync_ctx.fence_value));
560 ID3D12CommandQueue_ExecuteCommandLists(
s->command_queue, 1, (ID3D12CommandList **)&
s->command_list);
566 DX_CHECK(ID3D12Resource_Map(
s->staging_download_buffer, 0,
NULL, (
void **)&mapped_data));
570 ctx->sw_format,
ctx->width,
ctx->height);
572 ID3D12Resource_Unmap(
s->staging_download_buffer, 0,
NULL);
574 if (!
s->staging_upload_buffer) {
576 &
s->staging_upload_buffer, 0);
582 staging_y_location.pResource = staging_uv_location.pResource =
s->staging_upload_buffer;
584 DX_CHECK(ID3D12Resource_Map(
s->staging_upload_buffer, 0,
NULL, (
void **)&mapped_data));
588 ctx->sw_format,
ctx->width,
ctx->height);
590 ID3D12Resource_Unmap(
s->staging_upload_buffer, 0,
NULL);
592 ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
594 ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
595 &texture_y_location, 0, 0, 0,
596 &staging_y_location,
NULL);
598 ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
599 &texture_uv_location, 0, 0, 0,
600 &staging_uv_location,
NULL);
602 barrier.Transition.StateBefore = barrier.Transition.StateAfter;
603 barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
604 ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
606 DX_CHECK(ID3D12GraphicsCommandList_Close(
s->command_list));
608 ID3D12CommandQueue_ExecuteCommandLists(
s->command_queue, 1, (ID3D12CommandList **)&
s->command_list);
629 priv->
d3d12lib = dlopen(
"d3d12.dll", 0);
630 priv->
dxgilib = dlopen(
"dxgi.dll", 0);
645 priv->
create_device = (PFN_D3D12_CREATE_DEVICE) D3D12CreateDevice;
676 if (
ctx->lock_ctx == INVALID_HANDLE_VALUE) {
684 if (!
ctx->video_device)
685 DX_CHECK(ID3D12Device_QueryInterface(
ctx->device, &IID_ID3D12VideoDevice, (
void **)&
ctx->video_device));
700 CloseHandle(device_hwctx->
lock_ctx);
701 device_hwctx->
lock_ctx = INVALID_HANDLE_VALUE;
713 UINT create_flags = 0;
714 IDXGIAdapter *pAdapter =
NULL;
728 create_flags |= DXGI_CREATE_FACTORY_DEBUG;
729 ID3D12Debug_EnableDebugLayer(pDebug);
736 IDXGIFactory2 *pDXGIFactory =
NULL;
740 int adapter = device ? atoi(device) : 0;
741 if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
743 IDXGIFactory2_Release(pDXGIFactory);
747 DXGI_ADAPTER_DESC
desc;
748 hr = IDXGIAdapter2_GetDesc(pAdapter, &
desc);
755 hr = priv->
create_device((IUnknown *)pAdapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (
void **)&
ctx->device);
758 av_log(hwdev,
AV_LOG_ERROR,
"Failed to create Direct 3D 12 device (%lx)\n", (
long)hr);
764 ctx->resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
767 ctx->resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
770 ctx->heap_flags |= D3D12_HEAP_FLAG_SHARED;