75     WaitForSingleObjectEx(
ctx, INFINITE, FALSE);
 
   85     uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->
fence);
 
   86     if (completion < psync_ctx->fence_value) {
 
   87         if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->
fence, psync_ctx->
fence_value, psync_ctx->
event)))
 
   90         WaitForSingleObjectEx(psync_ctx->
event, INFINITE, FALSE);
 
  106                                                   ID3D12Resource **ppResource, 
int download)
 
  110     D3D12_HEAP_PROPERTIES props = { .Type = download ? D3D12_HEAP_TYPE_READBACK : D3D12_HEAP_TYPE_UPLOAD };
 
  111     D3D12_RESOURCE_DESC 
desc = {
 
  112         .Dimension          = D3D12_RESOURCE_DIMENSION_BUFFER,
 
  114         .Width              = 
s->luma_component_size + (
s->luma_component_size >> 1),
 
  116         .DepthOrArraySize   = 1,
 
  118         .Format             = DXGI_FORMAT_UNKNOWN,
 
  119         .SampleDesc         = { .Count = 1, .Quality = 0 },
 
  120         .Layout             = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
 
  121         .Flags              = D3D12_RESOURCE_FLAG_NONE,
 
  124     if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->
device, &props, D3D12_HEAP_FLAG_NONE, &
desc,
 
  125         states, 
NULL, &IID_ID3D12Resource, (
void **)ppResource))) {
 
  139     D3D12_COMMAND_QUEUE_DESC queue_desc = {
 
  140         .Type     = D3D12_COMMAND_LIST_TYPE_COPY,
 
  145     s->luma_component_size = 
FFALIGN(
ctx->width * (frames_hwctx->
format == DXGI_FORMAT_P010 ? 2 : 1),
 
  146                                      D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) * 
ctx->height;
 
  148     DX_CHECK(ID3D12Device_CreateFence(device_hwctx->
device, 0, D3D12_FENCE_FLAG_NONE,
 
  149                                       &IID_ID3D12Fence, (
void **)&
s->sync_ctx.fence));
 
  151     s->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE, 
NULL);
 
  152     if (!
s->sync_ctx.event)
 
  155     DX_CHECK(ID3D12Device_CreateCommandQueue(device_hwctx->
device, &queue_desc,
 
  156              &IID_ID3D12CommandQueue, (
void **)&
s->command_queue));
 
  158     DX_CHECK(ID3D12Device_CreateCommandAllocator(device_hwctx->
device, queue_desc.Type,
 
  159              &IID_ID3D12CommandAllocator, (
void **)&
s->command_allocator));
 
  161     DX_CHECK(ID3D12Device_CreateCommandList(device_hwctx->
device, 0, queue_desc.Type,
 
  162              s->command_allocator, 
NULL, &IID_ID3D12GraphicsCommandList, (
void **)&
s->command_list));
 
  164     DX_CHECK(ID3D12GraphicsCommandList_Close(
s->command_list));
 
  166     ID3D12CommandQueue_ExecuteCommandLists(
s->command_queue, 1, (ID3D12CommandList **)&
s->command_list);
 
  179     if (
s->sync_ctx.event)
 
  180         CloseHandle(
s->sync_ctx.event);
 
  192     int nb_sw_formats = 0;
 
  201         D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { 
supported_formats[
i].d3d_format };
 
  202         hr = ID3D12Device_CheckFeatureSupport(device_hwctx->
device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support, 
sizeof(format_support));
 
  203         if (SUCCEEDED(hr) && (format_support.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
 
  224     if (
frame->sync_ctx.event)
 
  225         CloseHandle(
frame->sync_ctx.event);
 
  238     D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
 
  239     D3D12_RESOURCE_DESC 
desc = {
 
  240         .Dimension        = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
 
  243         .Height           = 
ctx->height,
 
  244         .DepthOrArraySize = 1,
 
  247         .SampleDesc       = {.Count = 1, .Quality = 0 },
 
  248         .Layout           = D3D12_TEXTURE_LAYOUT_UNKNOWN,
 
  249         .Flags            = D3D12_RESOURCE_FLAG_NONE,
 
  256     if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->
device, &props, D3D12_HEAP_FLAG_NONE, &
desc,
 
  257         D3D12_RESOURCE_STATE_COMMON, 
NULL, &IID_ID3D12Resource, (
void **)&
frame->texture))) {
 
  262     DX_CHECK(ID3D12Device_CreateFence(device_hwctx->
device, 0, D3D12_FENCE_FLAG_NONE,
 
  263                                       &IID_ID3D12Fence, (
void **)&
frame->sync_ctx.fence));
 
  265     frame->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE, 
NULL);
 
  266     if (!
frame->sync_ctx.event)
 
  287             if (hwctx->
format != DXGI_FORMAT_UNKNOWN &&
 
  319                                D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
 
  341     fmts[0] = 
ctx->sw_format;
 
  362     ID3D12Resource *texture = (ID3D12Resource *)
f->texture;
 
  364     uint8_t *mapped_data;
 
  368     D3D12_TEXTURE_COPY_LOCATION staging_y_location  = { 0 };
 
  369     D3D12_TEXTURE_COPY_LOCATION staging_uv_location = { 0 };
 
  371     D3D12_TEXTURE_COPY_LOCATION texture_y_location = {
 
  372         .pResource        = texture,
 
  373         .Type             = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
 
  374         .SubresourceIndex = 0,
 
  377     D3D12_TEXTURE_COPY_LOCATION texture_uv_location = {
 
  378         .pResource        = texture,
 
  379         .Type             = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
 
  380         .SubresourceIndex = 1,
 
  383     D3D12_RESOURCE_BARRIER barrier = {
 
  384         .Type  = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
 
  385         .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
 
  387             .pResource   = texture,
 
  388             .StateBefore = D3D12_RESOURCE_STATE_COMMON,
 
  389             .StateAfter  = download ? D3D12_RESOURCE_STATE_COPY_SOURCE : D3D12_RESOURCE_STATE_COPY_DEST,
 
  390             .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
 
  399     if (!
s->command_queue) {
 
  405     for (
int i = 0; 
i < 4; 
i++)
 
  407                                D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
 
  409     staging_y_location = (D3D12_TEXTURE_COPY_LOCATION) {
 
  410         .Type      = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
 
  414                 .Format   = frames_hwctx->
format == DXGI_FORMAT_P010 ?
 
  415                                                     DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM,
 
  417                 .Height   = 
ctx->height,
 
  419                 .RowPitch = linesizes[0],
 
  424     staging_uv_location = (D3D12_TEXTURE_COPY_LOCATION) {
 
  425         .Type      = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
 
  427             .Offset = 
s->luma_component_size,
 
  429                 .Format   = frames_hwctx->
format == DXGI_FORMAT_P010 ?
 
  430                                                     DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM,
 
  431                 .Width    = 
ctx->width  >> 1,
 
  432                 .Height   = 
ctx->height >> 1,
 
  434                 .RowPitch = linesizes[0],
 
  439     DX_CHECK(ID3D12CommandAllocator_Reset(
s->command_allocator));
 
  441     DX_CHECK(ID3D12GraphicsCommandList_Reset(
s->command_list, 
s->command_allocator, 
NULL));
 
  444         if (!
s->staging_download_buffer) {
 
  446                                                          &
s->staging_download_buffer, 1);
 
  452         staging_y_location.pResource = staging_uv_location.pResource = 
s->staging_download_buffer;
 
  454         ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
 
  456         ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
 
  457                                                     &staging_y_location, 0, 0, 0,
 
  458                                                     &texture_y_location, 
NULL);
 
  460         ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
 
  461                                                     &staging_uv_location, 0, 0, 0,
 
  462                                                     &texture_uv_location, 
NULL);
 
  464         barrier.Transition.StateBefore = barrier.Transition.StateAfter;
 
  465         barrier.Transition.StateAfter  = D3D12_RESOURCE_STATE_COMMON;
 
  466         ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
 
  468         DX_CHECK(ID3D12GraphicsCommandList_Close(
s->command_list));
 
  470         DX_CHECK(ID3D12CommandQueue_Wait(
s->command_queue, 
f->sync_ctx.fence, 
f->sync_ctx.fence_value));
 
  472         ID3D12CommandQueue_ExecuteCommandLists(
s->command_queue, 1, (ID3D12CommandList **)&
s->command_list);
 
  478         DX_CHECK(ID3D12Resource_Map(
s->staging_download_buffer, 0, 
NULL, (
void **)&mapped_data));
 
  482                        ctx->sw_format, 
ctx->width, 
ctx->height);
 
  484         ID3D12Resource_Unmap(
s->staging_download_buffer, 0, 
NULL);
 
  486         if (!
s->staging_upload_buffer) {
 
  488                                                         &
s->staging_upload_buffer, 0);
 
  494         staging_y_location.pResource = staging_uv_location.pResource = 
s->staging_upload_buffer;
 
  496         DX_CHECK(ID3D12Resource_Map(
s->staging_upload_buffer, 0, 
NULL, (
void **)&mapped_data));
 
  500                        ctx->sw_format, 
ctx->width, 
ctx->height);
 
  502         ID3D12Resource_Unmap(
s->staging_upload_buffer, 0, 
NULL);
 
  504         ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
 
  506         ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
 
  507                                                     &texture_y_location, 0, 0, 0,
 
  508                                                     &staging_y_location, 
NULL);
 
  510         ID3D12GraphicsCommandList_CopyTextureRegion(
s->command_list,
 
  511                                                     &texture_uv_location, 0, 0, 0,
 
  512                                                     &staging_uv_location, 
NULL);
 
  514         barrier.Transition.StateBefore = barrier.Transition.StateAfter;
 
  515         barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
 
  516         ID3D12GraphicsCommandList_ResourceBarrier(
s->command_list, 1, &barrier);
 
  518         DX_CHECK(ID3D12GraphicsCommandList_Close(
s->command_list));
 
  520         ID3D12CommandQueue_ExecuteCommandLists(
s->command_queue, 1, (ID3D12CommandList **)&
s->command_list);
 
  541     priv->
d3d12lib = dlopen(
"d3d12.dll", 0);
 
  542     priv->
dxgilib  = dlopen(
"dxgi.dll", 0);
 
  557     priv->
create_device        = (PFN_D3D12_CREATE_DEVICE) D3D12CreateDevice;
 
  588         if (
ctx->lock_ctx == INVALID_HANDLE_VALUE) {
 
  596     if (!
ctx->video_device)
 
  597         DX_CHECK(ID3D12Device_QueryInterface(
ctx->device, &IID_ID3D12VideoDevice, (
void **)&
ctx->video_device));
 
  612         CloseHandle(device_hwctx->
lock_ctx);
 
  613         device_hwctx->
lock_ctx = INVALID_HANDLE_VALUE;
 
  625     UINT create_flags = 0;
 
  626     IDXGIAdapter *pAdapter = 
NULL;
 
  640             create_flags |= DXGI_CREATE_FACTORY_DEBUG;
 
  641             ID3D12Debug_EnableDebugLayer(pDebug);
 
  648         IDXGIFactory2 *pDXGIFactory = 
NULL;
 
  652             int adapter = device ? atoi(device) : 0;
 
  653             if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
 
  655             IDXGIFactory2_Release(pDXGIFactory);
 
  659             DXGI_ADAPTER_DESC 
desc;
 
  660             hr = IDXGIAdapter2_GetDesc(pAdapter, &
desc);
 
  667         hr = priv->
create_device((IUnknown *)pAdapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (
void **)&
ctx->device);