1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "d3d12_context.h" 25bf215546Sopenharmony_ci#include "d3d12_screen.h" 26bf215546Sopenharmony_ci#include "d3d12_video_proc.h" 27bf215546Sopenharmony_ci#include "d3d12_residency.h" 28bf215546Sopenharmony_ci#include "d3d12_util.h" 29bf215546Sopenharmony_ci#include "d3d12_resource.h" 30bf215546Sopenharmony_ci#include "d3d12_video_buffer.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_civoid 33bf215546Sopenharmony_cid3d12_video_processor_begin_frame(struct pipe_video_codec * codec, 34bf215546Sopenharmony_ci struct pipe_video_buffer *target, 35bf215546Sopenharmony_ci struct pipe_picture_desc *picture) 36bf215546Sopenharmony_ci{ 37bf215546Sopenharmony_ci struct d3d12_video_processor * pD3D12Proc = (struct d3d12_video_processor *) codec; 38bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_begin_frame - " 39bf215546Sopenharmony_ci "fenceValue: %d\n", 40bf215546Sopenharmony_ci pD3D12Proc->m_fenceValue); 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci // Setup process frame arguments for output/target texture. 43bf215546Sopenharmony_ci struct d3d12_video_buffer *pOutputVideoBuffer = (struct d3d12_video_buffer *) target; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci // Make the resources permanently resident for video use 46bf215546Sopenharmony_ci d3d12_promote_to_permanent_residency(pD3D12Proc->m_pD3D12Screen, pOutputVideoBuffer->texture); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci ID3D12Resource *pDstD3D12Res = d3d12_resource_resource(pOutputVideoBuffer->texture); 49bf215546Sopenharmony_ci auto dstDesc = GetDesc(pDstD3D12Res); 50bf215546Sopenharmony_ci pD3D12Proc->m_OutputArguments = { 51bf215546Sopenharmony_ci { 52bf215546Sopenharmony_ci { 53bf215546Sopenharmony_ci pDstD3D12Res, // ID3D12Resource *pTexture2D; 54bf215546Sopenharmony_ci 0, // UINT Subresource; 55bf215546Sopenharmony_ci }, 56bf215546Sopenharmony_ci { 57bf215546Sopenharmony_ci NULL, // ID3D12Resource *pTexture2D; 58bf215546Sopenharmony_ci 0 // UINT Subresource; 59bf215546Sopenharmony_ci } 60bf215546Sopenharmony_ci }, 61bf215546Sopenharmony_ci { 0, 0, (int) dstDesc.Width, (int) dstDesc.Height } 62bf215546Sopenharmony_ci }; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_begin_frame: Beginning new scene with Output ID3D12Resource: %p (%d %d)\n", pDstD3D12Res, (int) dstDesc.Width, (int) dstDesc.Height); 65bf215546Sopenharmony_ci} 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_civoid 68bf215546Sopenharmony_cid3d12_video_processor_end_frame(struct pipe_video_codec * codec, 69bf215546Sopenharmony_ci struct pipe_video_buffer *target, 70bf215546Sopenharmony_ci struct pipe_picture_desc *picture) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci struct d3d12_video_processor * pD3D12Proc = (struct d3d12_video_processor *) codec; 73bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_end_frame - " 74bf215546Sopenharmony_ci "fenceValue: %d\n", 75bf215546Sopenharmony_ci pD3D12Proc->m_fenceValue); 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci auto curOutputDesc = GetOutputStreamDesc(pD3D12Proc->m_spVideoProcessor.Get()); 78bf215546Sopenharmony_ci auto curOutputTexFmt = GetDesc(pD3D12Proc->m_OutputArguments.OutputStream[0].pTexture2D).Format; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci bool inputFmtsMatch = pD3D12Proc->m_inputStreamDescs.size() == pD3D12Proc->m_ProcessInputs.size(); 81bf215546Sopenharmony_ci unsigned curInputIdx = 0; 82bf215546Sopenharmony_ci while( (curInputIdx < pD3D12Proc->m_inputStreamDescs.size()) && inputFmtsMatch) 83bf215546Sopenharmony_ci { 84bf215546Sopenharmony_ci inputFmtsMatch = inputFmtsMatch && (pD3D12Proc->m_inputStreamDescs[curInputIdx].Format == GetDesc(pD3D12Proc->m_ProcessInputs[curInputIdx].InputStream[0].pTexture2D).Format); 85bf215546Sopenharmony_ci curInputIdx++; 86bf215546Sopenharmony_ci } 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci bool inputCountMatches = (pD3D12Proc->m_ProcessInputs.size() == pD3D12Proc->m_spVideoProcessor->GetNumInputStreamDescs()); 89bf215546Sopenharmony_ci bool outputFmtMatches = (curOutputDesc.Format == curOutputTexFmt); 90bf215546Sopenharmony_ci bool needsVPRecreation = ( 91bf215546Sopenharmony_ci !inputCountMatches // Requested batch has different number of Inputs to be blit'd 92bf215546Sopenharmony_ci || !outputFmtMatches // output texture format different than vid proc object expects 93bf215546Sopenharmony_ci || !inputFmtsMatch // inputs texture formats different than vid proc object expects 94bf215546Sopenharmony_ci ); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci if(needsVPRecreation) { 97bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_end_frame - Attempting to re-create ID3D12VideoProcessor " 98bf215546Sopenharmony_ci "input count matches %d inputFmtsMatch: %d outputFmtsMatch %d \n", inputCountMatches, inputFmtsMatch, outputFmtMatches); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci DXGI_COLOR_SPACE_TYPE InputColorSpace = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709; 101bf215546Sopenharmony_ci DXGI_FORMAT OutputFormat = curOutputTexFmt; 102bf215546Sopenharmony_ci DXGI_COLOR_SPACE_TYPE OutputColorSpace = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci std::vector<DXGI_FORMAT> InputFormats; 105bf215546Sopenharmony_ci for(D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1 curInput : pD3D12Proc->m_ProcessInputs) 106bf215546Sopenharmony_ci { 107bf215546Sopenharmony_ci InputFormats.push_back(GetDesc(curInput.InputStream[0].pTexture2D).Format); 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci if(!d3d12_video_processor_check_caps_and_create_processor(pD3D12Proc, InputFormats, InputColorSpace, OutputFormat, OutputColorSpace)) 111bf215546Sopenharmony_ci { 112bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_end_frame - Failure when " 113bf215546Sopenharmony_ci " trying to re-create the ID3D12VideoProcessor for current batch streams configuration\n"); 114bf215546Sopenharmony_ci assert(false); 115bf215546Sopenharmony_ci } 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci // Schedule barrier transitions 119bf215546Sopenharmony_ci std::vector<D3D12_RESOURCE_BARRIER> barrier_transitions; 120bf215546Sopenharmony_ci barrier_transitions.push_back(CD3DX12_RESOURCE_BARRIER::Transition( 121bf215546Sopenharmony_ci pD3D12Proc->m_OutputArguments.OutputStream[0].pTexture2D, 122bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COMMON, 123bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_VIDEO_PROCESS_WRITE)); 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci for(D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1 curInput : pD3D12Proc->m_ProcessInputs) 126bf215546Sopenharmony_ci barrier_transitions.push_back(CD3DX12_RESOURCE_BARRIER::Transition( 127bf215546Sopenharmony_ci curInput.InputStream[0].pTexture2D, 128bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COMMON, 129bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_VIDEO_PROCESS_READ)); 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci pD3D12Proc->m_spCommandList->ResourceBarrier(static_cast<uint32_t>(barrier_transitions.size()), barrier_transitions.data()); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci // Schedule process operation 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci pD3D12Proc->m_spCommandList->ProcessFrames1(pD3D12Proc->m_spVideoProcessor.Get(), &pD3D12Proc->m_OutputArguments, pD3D12Proc->m_ProcessInputs.size(), pD3D12Proc->m_ProcessInputs.data()); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci // Schedule reverse (back to common) transitions before command list closes for current frame 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci for (auto &BarrierDesc : barrier_transitions) 140bf215546Sopenharmony_ci std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci pD3D12Proc->m_spCommandList->ResourceBarrier(static_cast<uint32_t>(barrier_transitions.size()), barrier_transitions.data()); 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_civoid 146bf215546Sopenharmony_cid3d12_video_processor_process_frame(struct pipe_video_codec *codec, 147bf215546Sopenharmony_ci struct pipe_video_buffer *input_texture, 148bf215546Sopenharmony_ci const struct pipe_vpp_desc *process_properties) 149bf215546Sopenharmony_ci{ 150bf215546Sopenharmony_ci struct d3d12_video_processor * pD3D12Proc = (struct d3d12_video_processor *) codec; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci // Get the underlying resources from the pipe_video_buffers 153bf215546Sopenharmony_ci struct d3d12_video_buffer *pInputVideoBuffer = (struct d3d12_video_buffer *) input_texture; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci // Make the resources permanently resident for video use 156bf215546Sopenharmony_ci d3d12_promote_to_permanent_residency(pD3D12Proc->m_pD3D12Screen, pInputVideoBuffer->texture); 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci ID3D12Resource *pSrcD3D12Res = d3d12_resource_resource(pInputVideoBuffer->texture); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci // y0 = top 161bf215546Sopenharmony_ci // x0 = left 162bf215546Sopenharmony_ci // x1 = right 163bf215546Sopenharmony_ci // y1 = bottom 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Adding Input ID3D12Resource: %p to scene (Output target %p)\n", pSrcD3D12Res, pD3D12Proc->m_OutputArguments.OutputStream[0].pTexture2D); 166bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Input box: top: %d left: %d right: %d bottom: %d\n", process_properties->src_region.y0, process_properties->src_region.x0, process_properties->src_region.x1, process_properties->src_region.y1); 167bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Output box: top: %d left: %d right: %d bottom: %d\n", process_properties->dst_region.y0, process_properties->dst_region.x0, process_properties->dst_region.x1, process_properties->dst_region.y1); 168bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Requested alpha blend mode %d global alpha: %f \n", process_properties->blend.mode, process_properties->blend.global_alpha); 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci // Setup process frame arguments for current input texture. 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci unsigned curInputStreamIndex = pD3D12Proc->m_ProcessInputs.size(); 173bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1 InputArguments = { 174bf215546Sopenharmony_ci { 175bf215546Sopenharmony_ci { // D3D12_VIDEO_PROCESS_INPUT_STREAM InputStream[0]; 176bf215546Sopenharmony_ci pSrcD3D12Res, // ID3D12Resource *pTexture2D; 177bf215546Sopenharmony_ci 0, // UINT Subresource 178bf215546Sopenharmony_ci {//D3D12_VIDEO_PROCESS_REFERENCE_SET ReferenceSet; 179bf215546Sopenharmony_ci 0, //UINT NumPastFrames; 180bf215546Sopenharmony_ci NULL, //ID3D12Resource **ppPastFrames; 181bf215546Sopenharmony_ci NULL, // UINT *pPastSubresources; 182bf215546Sopenharmony_ci 0, //UINT NumFutureFrames; 183bf215546Sopenharmony_ci NULL, //ID3D12Resource **ppFutureFrames; 184bf215546Sopenharmony_ci NULL //UINT *pFutureSubresources; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci }, 187bf215546Sopenharmony_ci { // D3D12_VIDEO_PROCESS_INPUT_STREAM InputStream[1]; 188bf215546Sopenharmony_ci NULL, //ID3D12Resource *pTexture2D; 189bf215546Sopenharmony_ci 0, //UINT Subresource; 190bf215546Sopenharmony_ci {//D3D12_VIDEO_PROCESS_REFERENCE_SET ReferenceSet; 191bf215546Sopenharmony_ci 0, //UINT NumPastFrames; 192bf215546Sopenharmony_ci NULL, //ID3D12Resource **ppPastFrames; 193bf215546Sopenharmony_ci NULL, // UINT *pPastSubresources; 194bf215546Sopenharmony_ci 0, //UINT NumFutureFrames; 195bf215546Sopenharmony_ci NULL, //ID3D12Resource **ppFutureFrames; 196bf215546Sopenharmony_ci NULL //UINT *pFutureSubresources; 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci }, 200bf215546Sopenharmony_ci { // D3D12_VIDEO_PROCESS_TRANSFORM Transform; 201bf215546Sopenharmony_ci // y0 = top 202bf215546Sopenharmony_ci // x0 = left 203bf215546Sopenharmony_ci // x1 = right 204bf215546Sopenharmony_ci // y1 = bottom 205bf215546Sopenharmony_ci // typedef struct _RECT 206bf215546Sopenharmony_ci // { 207bf215546Sopenharmony_ci // int left; 208bf215546Sopenharmony_ci // int top; 209bf215546Sopenharmony_ci // int right; 210bf215546Sopenharmony_ci // int bottom; 211bf215546Sopenharmony_ci // } RECT; 212bf215546Sopenharmony_ci { process_properties->src_region.x0/*left*/, process_properties->src_region.y0/*top*/, process_properties->src_region.x1/*right*/, process_properties->src_region.y1/*bottom*/ }, 213bf215546Sopenharmony_ci { process_properties->dst_region.x0/*left*/, process_properties->dst_region.y0/*top*/, process_properties->dst_region.x1/*right*/, process_properties->dst_region.y1/*bottom*/ }, // D3D12_RECT DestinationRectangle; 214bf215546Sopenharmony_ci pD3D12Proc->m_inputStreamDescs[curInputStreamIndex].EnableOrientation ? d3d12_video_processor_convert_pipe_rotation(process_properties->orientation) : D3D12_VIDEO_PROCESS_ORIENTATION_DEFAULT, // D3D12_VIDEO_PROCESS_ORIENTATION Orientation; 215bf215546Sopenharmony_ci }, 216bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_INPUT_STREAM_FLAG_NONE, 217bf215546Sopenharmony_ci { // D3D12_VIDEO_PROCESS_INPUT_STREAM_RATE RateInfo; 218bf215546Sopenharmony_ci 0, 219bf215546Sopenharmony_ci 0, 220bf215546Sopenharmony_ci }, 221bf215546Sopenharmony_ci // INT FilterLevels[32]; 222bf215546Sopenharmony_ci { 223bf215546Sopenharmony_ci 0, // Trailing zeroes on the rest 224bf215546Sopenharmony_ci }, 225bf215546Sopenharmony_ci //D3D12_VIDEO_PROCESS_ALPHA_BLENDING; 226bf215546Sopenharmony_ci { 227bf215546Sopenharmony_ci (process_properties->blend.mode == PIPE_VIDEO_VPP_BLEND_MODE_GLOBAL_ALPHA), 228bf215546Sopenharmony_ci process_properties->blend.global_alpha 229bf215546Sopenharmony_ci }, 230bf215546Sopenharmony_ci // D3D12_VIDEO_FIELD_TYPE FieldType 231bf215546Sopenharmony_ci D3D12_VIDEO_FIELD_TYPE_NONE, 232bf215546Sopenharmony_ci }; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci debug_printf("ProcessFrame InArgs Orientation %d \n\tSrc top: %d left: %d right: %d bottom: %d\n\tDst top: %d left: %d right: %d bottom: %d\n", InputArguments.Transform.Orientation, 235bf215546Sopenharmony_ci InputArguments.Transform.SourceRectangle.top, InputArguments.Transform.SourceRectangle.left, InputArguments.Transform.SourceRectangle.right, InputArguments.Transform.SourceRectangle.bottom, 236bf215546Sopenharmony_ci InputArguments.Transform.DestinationRectangle.top, InputArguments.Transform.DestinationRectangle.left, InputArguments.Transform.DestinationRectangle.right, InputArguments.Transform.DestinationRectangle.bottom); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci pD3D12Proc->m_ProcessInputs.push_back(InputArguments); 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci /// 241bf215546Sopenharmony_ci /// Flush work to the GPU and blocking wait until GPU finishes 242bf215546Sopenharmony_ci /// 243bf215546Sopenharmony_ci pD3D12Proc->m_needsGPUFlush = true; 244bf215546Sopenharmony_ci} 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_civoid 247bf215546Sopenharmony_cid3d12_video_processor_destroy(struct pipe_video_codec * codec) 248bf215546Sopenharmony_ci{ 249bf215546Sopenharmony_ci if (codec == nullptr) { 250bf215546Sopenharmony_ci return; 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci d3d12_video_processor_flush(codec); // Flush pending work before destroying. 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci // Call dtor to make ComPtr work 255bf215546Sopenharmony_ci struct d3d12_video_processor * pD3D12Proc = (struct d3d12_video_processor *) codec; 256bf215546Sopenharmony_ci delete pD3D12Proc; 257bf215546Sopenharmony_ci} 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_civoid 260bf215546Sopenharmony_cid3d12_video_processor_flush(struct pipe_video_codec * codec) 261bf215546Sopenharmony_ci{ 262bf215546Sopenharmony_ci struct d3d12_video_processor * pD3D12Proc = (struct d3d12_video_processor *) codec; 263bf215546Sopenharmony_ci assert(pD3D12Proc); 264bf215546Sopenharmony_ci assert(pD3D12Proc->m_spD3D12VideoDevice); 265bf215546Sopenharmony_ci assert(pD3D12Proc->m_spCommandQueue); 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci // Flush buffer_subdata batch and Wait the m_spCommandQueue for GPU upload completion 268bf215546Sopenharmony_ci // before executing the current batch below. Input objects coming from the pipe_context (ie. input texture) must be fully finished working with before processor can read them. 269bf215546Sopenharmony_ci struct pipe_fence_handle *completion_fence = NULL; 270bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush - Flushing pD3D12Proc->m_pD3D12Context->base. and GPU sync between Video/Context queues before flushing Video Process Queue.\n"); 271bf215546Sopenharmony_ci pD3D12Proc->m_pD3D12Context->base.flush(&pD3D12Proc->m_pD3D12Context->base, &completion_fence, PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH); 272bf215546Sopenharmony_ci assert(completion_fence); 273bf215546Sopenharmony_ci struct d3d12_fence *casted_completion_fence = d3d12_fence(completion_fence); 274bf215546Sopenharmony_ci pD3D12Proc->m_spCommandQueue->Wait(casted_completion_fence->cmdqueue_fence, casted_completion_fence->value); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush started. Will flush video queue work and CPU wait on " 277bf215546Sopenharmony_ci "fenceValue: %d\n", 278bf215546Sopenharmony_ci pD3D12Proc->m_fenceValue); 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci if (!pD3D12Proc->m_needsGPUFlush) { 281bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush started. Nothing to flush, all up to date.\n"); 282bf215546Sopenharmony_ci } else { 283bf215546Sopenharmony_ci HRESULT hr = pD3D12Proc->m_pD3D12Screen->dev->GetDeviceRemovedReason(); 284bf215546Sopenharmony_ci if (hr != S_OK) { 285bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush" 286bf215546Sopenharmony_ci " - D3D12Device was removed BEFORE commandlist " 287bf215546Sopenharmony_ci "execution with HR %x.\n", 288bf215546Sopenharmony_ci hr); 289bf215546Sopenharmony_ci goto flush_fail; 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci // Close and execute command list and wait for idle on CPU blocking 293bf215546Sopenharmony_ci // this method before resetting list and allocator for next submission. 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci if (pD3D12Proc->m_transitionsBeforeCloseCmdList.size() > 0) { 296bf215546Sopenharmony_ci pD3D12Proc->m_spCommandList->ResourceBarrier(pD3D12Proc->m_transitionsBeforeCloseCmdList.size(), 297bf215546Sopenharmony_ci pD3D12Proc->m_transitionsBeforeCloseCmdList.data()); 298bf215546Sopenharmony_ci pD3D12Proc->m_transitionsBeforeCloseCmdList.clear(); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci hr = pD3D12Proc->m_spCommandList->Close(); 302bf215546Sopenharmony_ci if (FAILED(hr)) { 303bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush - Can't close command list with HR %x\n", hr); 304bf215546Sopenharmony_ci goto flush_fail; 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci ID3D12CommandList *ppCommandLists[1] = { pD3D12Proc->m_spCommandList.Get() }; 308bf215546Sopenharmony_ci pD3D12Proc->m_spCommandQueue->ExecuteCommandLists(1, ppCommandLists); 309bf215546Sopenharmony_ci pD3D12Proc->m_spCommandQueue->Signal(pD3D12Proc->m_spFence.Get(), pD3D12Proc->m_fenceValue); 310bf215546Sopenharmony_ci pD3D12Proc->m_spFence->SetEventOnCompletion(pD3D12Proc->m_fenceValue, nullptr); 311bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush - ExecuteCommandLists finished on signal with " 312bf215546Sopenharmony_ci "fenceValue: %d\n", 313bf215546Sopenharmony_ci pD3D12Proc->m_fenceValue); 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci hr = pD3D12Proc->m_spCommandAllocator->Reset(); 316bf215546Sopenharmony_ci if (FAILED(hr)) { 317bf215546Sopenharmony_ci debug_printf( 318bf215546Sopenharmony_ci "[d3d12_video_processor] d3d12_video_processor_flush - resetting ID3D12CommandAllocator failed with HR %x\n", 319bf215546Sopenharmony_ci hr); 320bf215546Sopenharmony_ci goto flush_fail; 321bf215546Sopenharmony_ci } 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci hr = pD3D12Proc->m_spCommandList->Reset(pD3D12Proc->m_spCommandAllocator.Get()); 324bf215546Sopenharmony_ci if (FAILED(hr)) { 325bf215546Sopenharmony_ci debug_printf( 326bf215546Sopenharmony_ci "[d3d12_video_processor] d3d12_video_processor_flush - resetting ID3D12GraphicsCommandList failed with HR %x\n", 327bf215546Sopenharmony_ci hr); 328bf215546Sopenharmony_ci goto flush_fail; 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci // Validate device was not removed 332bf215546Sopenharmony_ci hr = pD3D12Proc->m_pD3D12Screen->dev->GetDeviceRemovedReason(); 333bf215546Sopenharmony_ci if (hr != S_OK) { 334bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush" 335bf215546Sopenharmony_ci " - D3D12Device was removed AFTER commandlist " 336bf215546Sopenharmony_ci "execution with HR %x, but wasn't before.\n", 337bf215546Sopenharmony_ci hr); 338bf215546Sopenharmony_ci goto flush_fail; 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci debug_printf( 342bf215546Sopenharmony_ci "[d3d12_video_processor] d3d12_video_processor_flush - GPU signaled execution finalized for fenceValue: %d\n", 343bf215546Sopenharmony_ci pD3D12Proc->m_fenceValue); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci pD3D12Proc->m_fenceValue++; 346bf215546Sopenharmony_ci pD3D12Proc->m_needsGPUFlush = false; 347bf215546Sopenharmony_ci } 348bf215546Sopenharmony_ci pD3D12Proc->m_ProcessInputs.clear(); 349bf215546Sopenharmony_ci // Free the fence after completion finished 350bf215546Sopenharmony_ci if(completion_fence) 351bf215546Sopenharmony_ci pD3D12Proc->m_pD3D12Screen->base.fence_reference(&pD3D12Proc->m_pD3D12Screen->base, &completion_fence, NULL); 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci return; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ciflush_fail: 356bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_flush failed for fenceValue: %d\n", pD3D12Proc->m_fenceValue); 357bf215546Sopenharmony_ci assert(false); 358bf215546Sopenharmony_ci} 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_cistruct pipe_video_codec * 361bf215546Sopenharmony_cid3d12_video_processor_create(struct pipe_context *context, const struct pipe_video_codec *codec) 362bf215546Sopenharmony_ci{ 363bf215546Sopenharmony_ci /// 364bf215546Sopenharmony_ci /// Initialize d3d12_video_processor 365bf215546Sopenharmony_ci /// 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci // Not using new doesn't call ctor and the initializations in the class declaration are lost 368bf215546Sopenharmony_ci struct d3d12_video_processor *pD3D12Proc = new d3d12_video_processor; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci pD3D12Proc->base = *codec; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci pD3D12Proc->base.context = context; 373bf215546Sopenharmony_ci pD3D12Proc->base.width = codec->width; 374bf215546Sopenharmony_ci pD3D12Proc->base.height = codec->height; 375bf215546Sopenharmony_ci pD3D12Proc->base.destroy = d3d12_video_processor_destroy; 376bf215546Sopenharmony_ci pD3D12Proc->base.begin_frame = d3d12_video_processor_begin_frame; 377bf215546Sopenharmony_ci pD3D12Proc->base.process_frame = d3d12_video_processor_process_frame; 378bf215546Sopenharmony_ci pD3D12Proc->base.end_frame = d3d12_video_processor_end_frame; 379bf215546Sopenharmony_ci pD3D12Proc->base.flush = d3d12_video_processor_flush; 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci /// 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci /// 384bf215546Sopenharmony_ci /// Try initializing D3D12 Video device and check for device caps 385bf215546Sopenharmony_ci /// 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci struct d3d12_context *pD3D12Ctx = (struct d3d12_context *) context; 388bf215546Sopenharmony_ci pD3D12Proc->m_pD3D12Context = pD3D12Ctx; 389bf215546Sopenharmony_ci pD3D12Proc->m_pD3D12Screen = d3d12_screen(pD3D12Ctx->base.screen); 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci // Assume defaults for now, can re-create if necessary when d3d12_video_processor_end_frame kicks off the processing 392bf215546Sopenharmony_ci DXGI_COLOR_SPACE_TYPE InputColorSpace = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709; 393bf215546Sopenharmony_ci std::vector<DXGI_FORMAT> InputFormats = { DXGI_FORMAT_NV12 }; 394bf215546Sopenharmony_ci DXGI_FORMAT OutputFormat = DXGI_FORMAT_NV12; 395bf215546Sopenharmony_ci DXGI_COLOR_SPACE_TYPE OutputColorSpace = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci /// 398bf215546Sopenharmony_ci /// Create processor objects 399bf215546Sopenharmony_ci /// 400bf215546Sopenharmony_ci if (FAILED(pD3D12Proc->m_pD3D12Screen->dev->QueryInterface( 401bf215546Sopenharmony_ci IID_PPV_ARGS(pD3D12Proc->m_spD3D12VideoDevice.GetAddressOf())))) { 402bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_create_processor - D3D12 Device has no Video support\n"); 403bf215546Sopenharmony_ci goto failed; 404bf215546Sopenharmony_ci } 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci if (!d3d12_video_processor_check_caps_and_create_processor(pD3D12Proc, InputFormats, InputColorSpace, OutputFormat, OutputColorSpace)) { 407bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_create_processor - Failure on " 408bf215546Sopenharmony_ci "d3d12_video_processor_check_caps_and_create_processor\n"); 409bf215546Sopenharmony_ci goto failed; 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci if (!d3d12_video_processor_create_command_objects(pD3D12Proc)) { 413bf215546Sopenharmony_ci debug_printf( 414bf215546Sopenharmony_ci "[d3d12_video_processor] d3d12_video_create_processor - Failure on d3d12_video_processor_create_command_objects\n"); 415bf215546Sopenharmony_ci goto failed; 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_create_processor - Created successfully!\n"); 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci return &pD3D12Proc->base; 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_cifailed: 423bf215546Sopenharmony_ci if (pD3D12Proc != nullptr) { 424bf215546Sopenharmony_ci d3d12_video_processor_destroy(&pD3D12Proc->base); 425bf215546Sopenharmony_ci } 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci return nullptr; 428bf215546Sopenharmony_ci} 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_cibool 431bf215546Sopenharmony_cid3d12_video_processor_check_caps_and_create_processor(struct d3d12_video_processor *pD3D12Proc, 432bf215546Sopenharmony_ci std::vector<DXGI_FORMAT> InputFormats, 433bf215546Sopenharmony_ci DXGI_COLOR_SPACE_TYPE InputColorSpace, 434bf215546Sopenharmony_ci DXGI_FORMAT OutputFormat, 435bf215546Sopenharmony_ci DXGI_COLOR_SPACE_TYPE OutputColorSpace) 436bf215546Sopenharmony_ci{ 437bf215546Sopenharmony_ci HRESULT hr = S_OK; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci D3D12_VIDEO_FIELD_TYPE FieldType = D3D12_VIDEO_FIELD_TYPE_NONE; 440bf215546Sopenharmony_ci D3D12_VIDEO_FRAME_STEREO_FORMAT StereoFormat = D3D12_VIDEO_FRAME_STEREO_FORMAT_NONE; 441bf215546Sopenharmony_ci DXGI_RATIONAL FrameRate = { 30, 1 }; 442bf215546Sopenharmony_ci DXGI_RATIONAL AspectRatio = { 1, 1 }; 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci struct ResolStruct { 445bf215546Sopenharmony_ci uint Width; 446bf215546Sopenharmony_ci uint Height; 447bf215546Sopenharmony_ci }; 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci ResolStruct resolutionsList[] = { 450bf215546Sopenharmony_ci { 8192, 8192 }, // 8k 451bf215546Sopenharmony_ci { 8192, 4320 }, // 8k - alternative 452bf215546Sopenharmony_ci { 7680, 4800 }, // 8k - alternative 453bf215546Sopenharmony_ci { 7680, 4320 }, // 8k - alternative 454bf215546Sopenharmony_ci { 4096, 2304 }, // 2160p (4K) 455bf215546Sopenharmony_ci { 4096, 2160 }, // 2160p (4K) - alternative 456bf215546Sopenharmony_ci { 2560, 1440 }, // 1440p 457bf215546Sopenharmony_ci { 1920, 1200 }, // 1200p 458bf215546Sopenharmony_ci { 1920, 1080 }, // 1080p 459bf215546Sopenharmony_ci { 1280, 720 }, // 720p 460bf215546Sopenharmony_ci { 800, 600 }, 461bf215546Sopenharmony_ci }; 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps = 464bf215546Sopenharmony_ci { 465bf215546Sopenharmony_ci 0, // NodeIndex 466bf215546Sopenharmony_ci { resolutionsList[0].Width, resolutionsList[0].Height, { InputFormats[0], InputColorSpace } }, 467bf215546Sopenharmony_ci FieldType, 468bf215546Sopenharmony_ci StereoFormat, 469bf215546Sopenharmony_ci FrameRate, 470bf215546Sopenharmony_ci { OutputFormat, OutputColorSpace }, 471bf215546Sopenharmony_ci StereoFormat, 472bf215546Sopenharmony_ci FrameRate, 473bf215546Sopenharmony_ci }; 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci uint32_t idxResol = 0; 476bf215546Sopenharmony_ci bool bSupportsAny = false; 477bf215546Sopenharmony_ci while ((idxResol < ARRAY_SIZE(resolutionsList)) && !bSupportsAny) { 478bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps.InputSample.Width = resolutionsList[idxResol].Width; 479bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps.InputSample.Height = resolutionsList[idxResol].Height; 480bf215546Sopenharmony_ci if (SUCCEEDED(pD3D12Proc->m_spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_PROCESS_SUPPORT, &pD3D12Proc->m_SupportCaps, sizeof(pD3D12Proc->m_SupportCaps)))) { 481bf215546Sopenharmony_ci bSupportsAny = ((pD3D12Proc->m_SupportCaps.SupportFlags & D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) != 0); 482bf215546Sopenharmony_ci } 483bf215546Sopenharmony_ci idxResol++; 484bf215546Sopenharmony_ci } 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci if ((pD3D12Proc->m_SupportCaps.SupportFlags & D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) != D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) 487bf215546Sopenharmony_ci { 488bf215546Sopenharmony_ci if((pD3D12Proc->m_SupportCaps.SupportFlags & D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) != D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) { 489bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_check_caps_and_create_processor - D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED not returned by driver. " 490bf215546Sopenharmony_ci "failed with SupportFlags %x\n", 491bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps.SupportFlags); 492bf215546Sopenharmony_ci } 493bf215546Sopenharmony_ci } 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_FILTER_FLAGS enabledFilterFlags = D3D12_VIDEO_PROCESS_FILTER_FLAG_NONE; 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci bool enableOrientation = ( 498bf215546Sopenharmony_ci ((pD3D12Proc->m_SupportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_ROTATION) != 0) 499bf215546Sopenharmony_ci || ((pD3D12Proc->m_SupportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_FLIP) != 0) 500bf215546Sopenharmony_ci ); 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_INPUT_STREAM_DESC inputStreamDesc = { 503bf215546Sopenharmony_ci InputFormats[0], 504bf215546Sopenharmony_ci InputColorSpace, 505bf215546Sopenharmony_ci AspectRatio, // SourceAspectRatio; 506bf215546Sopenharmony_ci AspectRatio, // DestinationAspectRatio; 507bf215546Sopenharmony_ci FrameRate, // FrameRate 508bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps.ScaleSupport.OutputSizeRange, // SourceSizeRange 509bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps.ScaleSupport.OutputSizeRange, // DestinationSizeRange 510bf215546Sopenharmony_ci enableOrientation, 511bf215546Sopenharmony_ci enabledFilterFlags, 512bf215546Sopenharmony_ci StereoFormat, 513bf215546Sopenharmony_ci FieldType, 514bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG_NONE, 515bf215546Sopenharmony_ci ((pD3D12Proc->m_SupportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_ALPHA_BLENDING) != 0) 516bf215546Sopenharmony_ci && ((pD3D12Proc->m_SupportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_ALPHA_FILL) != 0), // EnableAlphaBlending 517bf215546Sopenharmony_ci {}, // LumaKey 518bf215546Sopenharmony_ci 0, // NumPastFrames 519bf215546Sopenharmony_ci 0, // NumFutureFrames 520bf215546Sopenharmony_ci FALSE // EnableAutoProcessing 521bf215546Sopenharmony_ci }; 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_OUTPUT_STREAM_DESC outputStreamDesc = 524bf215546Sopenharmony_ci { 525bf215546Sopenharmony_ci pD3D12Proc->m_SupportCaps.OutputFormat.Format, 526bf215546Sopenharmony_ci OutputColorSpace, 527bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_ALPHA_FILL_MODE_OPAQUE, // AlphaFillMode 528bf215546Sopenharmony_ci 0u, // AlphaFillModeSourceStreamIndex 529bf215546Sopenharmony_ci {0, 0, 0, 0}, // BackgroundColor 530bf215546Sopenharmony_ci FrameRate, // FrameRate 531bf215546Sopenharmony_ci FALSE // EnableStereo 532bf215546Sopenharmony_ci }; 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci // gets the required past/future frames for VP creation 535bf215546Sopenharmony_ci { 536bf215546Sopenharmony_ci D3D12_FEATURE_DATA_VIDEO_PROCESS_REFERENCE_INFO referenceInfo = {}; 537bf215546Sopenharmony_ci referenceInfo.NodeIndex = 0; 538bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_FEATURE_FLAGS featureFlags = D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE; 539bf215546Sopenharmony_ci featureFlags |= outputStreamDesc.AlphaFillMode ? D3D12_VIDEO_PROCESS_FEATURE_FLAG_ALPHA_FILL : D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE; 540bf215546Sopenharmony_ci featureFlags |= inputStreamDesc.LumaKey.Enable ? D3D12_VIDEO_PROCESS_FEATURE_FLAG_LUMA_KEY : D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE; 541bf215546Sopenharmony_ci featureFlags |= (inputStreamDesc.StereoFormat != D3D12_VIDEO_FRAME_STEREO_FORMAT_NONE || outputStreamDesc.EnableStereo) ? D3D12_VIDEO_PROCESS_FEATURE_FLAG_STEREO : D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE; 542bf215546Sopenharmony_ci featureFlags |= inputStreamDesc.EnableOrientation ? D3D12_VIDEO_PROCESS_FEATURE_FLAG_ROTATION | D3D12_VIDEO_PROCESS_FEATURE_FLAG_FLIP : D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE; 543bf215546Sopenharmony_ci featureFlags |= inputStreamDesc.EnableAlphaBlending ? D3D12_VIDEO_PROCESS_FEATURE_FLAG_ALPHA_BLENDING : D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE; 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ci referenceInfo.DeinterlaceMode = inputStreamDesc.DeinterlaceMode; 546bf215546Sopenharmony_ci referenceInfo.Filters = inputStreamDesc.FilterFlags; 547bf215546Sopenharmony_ci referenceInfo.FeatureSupport = featureFlags; 548bf215546Sopenharmony_ci referenceInfo.InputFrameRate = inputStreamDesc.FrameRate; 549bf215546Sopenharmony_ci referenceInfo.OutputFrameRate = outputStreamDesc.FrameRate; 550bf215546Sopenharmony_ci referenceInfo.EnableAutoProcessing = inputStreamDesc.EnableAutoProcessing; 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci hr = pD3D12Proc->m_spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_PROCESS_REFERENCE_INFO, &referenceInfo, sizeof(referenceInfo)); 553bf215546Sopenharmony_ci if (FAILED(hr)) { 554bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_check_caps_and_create_processor - CheckFeatureSupport " 555bf215546Sopenharmony_ci "failed with HR %x\n", 556bf215546Sopenharmony_ci hr); 557bf215546Sopenharmony_ci return false; 558bf215546Sopenharmony_ci } 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci inputStreamDesc.NumPastFrames = referenceInfo.PastFrames; 561bf215546Sopenharmony_ci inputStreamDesc.NumFutureFrames = referenceInfo.FutureFrames; 562bf215546Sopenharmony_ci } 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci pD3D12Proc->m_outputStreamDesc = outputStreamDesc; 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor]\t Creating Video Processor\n"); 567bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor]\t NumInputs: %d\n", (int) InputFormats.size()); 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci pD3D12Proc->m_inputStreamDescs.clear(); 570bf215546Sopenharmony_ci for (unsigned i = 0; i < InputFormats.size(); i++) 571bf215546Sopenharmony_ci { 572bf215546Sopenharmony_ci inputStreamDesc.Format = InputFormats[i]; 573bf215546Sopenharmony_ci pD3D12Proc->m_inputStreamDescs.push_back(inputStreamDesc); 574bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor]\t Input Stream #%d Format: %d\n", i, inputStreamDesc.Format); 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor]\t Output Stream Format: %d\n", pD3D12Proc->m_outputStreamDesc.Format); 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci hr = pD3D12Proc->m_spD3D12VideoDevice->CreateVideoProcessor(pD3D12Proc->m_NodeMask, 579bf215546Sopenharmony_ci &pD3D12Proc->m_outputStreamDesc, 580bf215546Sopenharmony_ci pD3D12Proc->m_inputStreamDescs.size(), 581bf215546Sopenharmony_ci pD3D12Proc->m_inputStreamDescs.data(), 582bf215546Sopenharmony_ci IID_PPV_ARGS(pD3D12Proc->m_spVideoProcessor.GetAddressOf())); 583bf215546Sopenharmony_ci if (FAILED(hr)) { 584bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_check_caps_and_create_processor - CreateVideoProcessor " 585bf215546Sopenharmony_ci "failed with HR %x\n", 586bf215546Sopenharmony_ci hr); 587bf215546Sopenharmony_ci return false; 588bf215546Sopenharmony_ci } 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci return true; 591bf215546Sopenharmony_ci} 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_cibool 594bf215546Sopenharmony_cid3d12_video_processor_create_command_objects(struct d3d12_video_processor *pD3D12Proc) 595bf215546Sopenharmony_ci{ 596bf215546Sopenharmony_ci assert(pD3D12Proc->m_spD3D12VideoDevice); 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS }; 599bf215546Sopenharmony_ci HRESULT hr = pD3D12Proc->m_pD3D12Screen->dev->CreateCommandQueue( 600bf215546Sopenharmony_ci &commandQueueDesc, 601bf215546Sopenharmony_ci IID_PPV_ARGS(pD3D12Proc->m_spCommandQueue.GetAddressOf())); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci if (FAILED(hr)) { 604bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_create_command_objects - Call to CreateCommandQueue " 605bf215546Sopenharmony_ci "failed with HR %x\n", 606bf215546Sopenharmony_ci hr); 607bf215546Sopenharmony_ci return false; 608bf215546Sopenharmony_ci } 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci hr = pD3D12Proc->m_pD3D12Screen->dev->CreateFence(0, 611bf215546Sopenharmony_ci D3D12_FENCE_FLAG_NONE, 612bf215546Sopenharmony_ci IID_PPV_ARGS(&pD3D12Proc->m_spFence)); 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci if (FAILED(hr)) { 615bf215546Sopenharmony_ci debug_printf( 616bf215546Sopenharmony_ci "[d3d12_video_processor] d3d12_video_processor_create_command_objects - Call to CreateFence failed with HR %x\n", 617bf215546Sopenharmony_ci hr); 618bf215546Sopenharmony_ci return false; 619bf215546Sopenharmony_ci } 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci hr = pD3D12Proc->m_pD3D12Screen->dev->CreateCommandAllocator( 622bf215546Sopenharmony_ci D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS, 623bf215546Sopenharmony_ci IID_PPV_ARGS(pD3D12Proc->m_spCommandAllocator.GetAddressOf())); 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci if (FAILED(hr)) { 626bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_create_command_objects - Call to " 627bf215546Sopenharmony_ci "CreateCommandAllocator failed with HR %x\n", 628bf215546Sopenharmony_ci hr); 629bf215546Sopenharmony_ci return false; 630bf215546Sopenharmony_ci } 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci hr = pD3D12Proc->m_pD3D12Screen->dev->CreateCommandList(0, 633bf215546Sopenharmony_ci D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS, 634bf215546Sopenharmony_ci pD3D12Proc->m_spCommandAllocator.Get(), 635bf215546Sopenharmony_ci nullptr, 636bf215546Sopenharmony_ci IID_PPV_ARGS(pD3D12Proc->m_spCommandList.GetAddressOf())); 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci if (FAILED(hr)) { 639bf215546Sopenharmony_ci debug_printf("[d3d12_video_processor] d3d12_video_processor_create_command_objects - Call to CreateCommandList " 640bf215546Sopenharmony_ci "failed with HR %x\n", 641bf215546Sopenharmony_ci hr); 642bf215546Sopenharmony_ci return false; 643bf215546Sopenharmony_ci } 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci return true; 646bf215546Sopenharmony_ci} 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ciD3D12_VIDEO_PROCESS_ORIENTATION 649bf215546Sopenharmony_cid3d12_video_processor_convert_pipe_rotation(enum pipe_video_vpp_orientation orientation_flags) 650bf215546Sopenharmony_ci{ 651bf215546Sopenharmony_ci D3D12_VIDEO_PROCESS_ORIENTATION result = D3D12_VIDEO_PROCESS_ORIENTATION_DEFAULT; 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci if(orientation_flags & PIPE_VIDEO_VPP_ROTATION_90) 654bf215546Sopenharmony_ci { 655bf215546Sopenharmony_ci result = (orientation_flags & PIPE_VIDEO_VPP_FLIP_HORIZONTAL) ? D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_90_FLIP_HORIZONTAL : D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_90; 656bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Orientation Mode: %s\n", (orientation_flags & PIPE_VIDEO_VPP_FLIP_HORIZONTAL) ? "D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_90_FLIP_HORIZONTAL" : "D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_90"); 657bf215546Sopenharmony_ci } 658bf215546Sopenharmony_ci else if(orientation_flags & PIPE_VIDEO_VPP_ROTATION_180) 659bf215546Sopenharmony_ci { 660bf215546Sopenharmony_ci result = D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_180; 661bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Orientation Mode: D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_180\n"); 662bf215546Sopenharmony_ci } 663bf215546Sopenharmony_ci else if(orientation_flags & PIPE_VIDEO_VPP_ROTATION_270) 664bf215546Sopenharmony_ci { 665bf215546Sopenharmony_ci result = (orientation_flags & PIPE_VIDEO_VPP_FLIP_HORIZONTAL) ? D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_270_FLIP_HORIZONTAL : D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_270; 666bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Orientation Mode: %s\n", (orientation_flags & PIPE_VIDEO_VPP_FLIP_HORIZONTAL) ? "D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_270_FLIP_HORIZONTAL" : "D3D12_VIDEO_PROCESS_ORIENTATION_CLOCKWISE_270"); 667bf215546Sopenharmony_ci } 668bf215546Sopenharmony_ci else if(orientation_flags & PIPE_VIDEO_VPP_FLIP_HORIZONTAL) 669bf215546Sopenharmony_ci { 670bf215546Sopenharmony_ci result = D3D12_VIDEO_PROCESS_ORIENTATION_FLIP_HORIZONTAL; 671bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Orientation Mode: D3D12_VIDEO_PROCESS_ORIENTATION_FLIP_HORIZONTAL\n"); 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci else if(orientation_flags & PIPE_VIDEO_VPP_FLIP_VERTICAL) 674bf215546Sopenharmony_ci { 675bf215546Sopenharmony_ci result = D3D12_VIDEO_PROCESS_ORIENTATION_FLIP_VERTICAL; 676bf215546Sopenharmony_ci debug_printf("d3d12_video_processor_process_frame: Orientation Mode: D3D12_VIDEO_PROCESS_ORIENTATION_FLIP_VERTICAL\n"); 677bf215546Sopenharmony_ci } 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci return result; 680bf215546Sopenharmony_ci} 681