#include "ExD3D12_Device.h" #include #include "mfxstructures.h" #include #include #define MSDK_ZERO_MEMORY(VAR) {memset(&VAR, 0, sizeof(VAR));} #define MSDK_MEMCPY_VAR(dstVarName, src, count) memcpy_s(&(dstVarName), sizeof(dstVarName), (src), (count)) #define MSDK_CHECK_STATUS(X, MSG) {if ((X) < MFX_ERR_NONE) { return X;}} ExD3D12_Device::ExD3D12_Device() { } ExD3D12_Device::~ExD3D12_Device() { } inline std::string HrToString(HRESULT hr) { char s_str[64] = {}; sprintf_s(s_str, "HRESULT of 0x%08X", static_cast(hr)); return std::string(s_str); } class HrException : public std::runtime_error { public: HrException(HRESULT hr) : std::runtime_error(HrToString(hr)), m_hr(hr) {} HRESULT Error() const { return m_hr; } private: const HRESULT m_hr; }; inline void ThrowIfFailed(HRESULT hr) { if (FAILED(hr)) { throw HrException(hr); } } void ExD3D12_Device::CreateDevice(HWND hwnd) { m_MyWind = hwnd; } void ExD3D12_Device::RenderUI() { D2D1_SIZE_F rtSize = m_d2dRenderTargets[m_frameIndex]->GetSize(); D2D1_RECT_F textRect = D2D1::RectF(0, 0, rtSize.width, rtSize.height); static const WCHAR text[] = L"11On12"; // Acquire our wrapped render target resource for the current back buffer. m_d3d11On12Device->AcquireWrappedResources(m_wrappedBackBuffers[m_frameIndex].GetAddressOf(), 1); // Render text directly to the back buffer. m_d2dDeviceContext->SetTarget(m_d2dRenderTargets[m_frameIndex].Get()); m_d2dDeviceContext->BeginDraw(); m_d2dDeviceContext->SetTransform(D2D1::Matrix3x2F::Identity()); m_d2dDeviceContext->DrawText( text, _countof(text) - 1, m_textFormat.Get(), &textRect, m_textBrush.Get() ); ThrowIfFailed(m_d2dDeviceContext->EndDraw()); // Release our wrapped render target resource. Releasing // transitions the back buffer resource to the state specified // as the OutState when the wrapped resource was created. m_d3d11On12Device->ReleaseWrappedResources(m_wrappedBackBuffers[m_frameIndex].GetAddressOf(), 1); // Flush to submit the 11 command list to the shared command queue. m_d3d11DeviceContext->Flush(); } // Load the rendering pipeline dependencies. void ExD3D12_Device::LoadPipeline() { HRESULT hres = NO_ERROR; UINT dxgiFactoryFlags = 0; UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; D2D1_FACTORY_OPTIONS d2dFactoryOptions = {}; #if defined(_DEBUG) // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. { ComPtr debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { debugController->EnableDebugLayer(); // Enable additional debug layers. dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; d3d11DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; d2dFactoryOptions.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; } } #endif ComPtr factory; ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory))); { ComPtr hardwareAdapter; GetHardwareAdapter(factory.Get(), &hardwareAdapter); ThrowIfFailed(D3D12CreateDevice( hardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_d3d12Device) )); //MyTest add >> ThrowIfFailed(D3D12CreateDevice( hardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_pDX12VideoDevice) )); //MyTest add << } #if defined(_DEBUG) // Filter a debug error coming from the 11on12 layer. ComPtr infoQueue; if (SUCCEEDED(m_d3d12Device->QueryInterface(IID_PPV_ARGS(&infoQueue)))) { // Suppress whole categories of messages. //D3D12_MESSAGE_CATEGORY categories[] = {}; // Suppress messages based on their severity level. D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO, }; // Suppress individual messages by their ID. D3D12_MESSAGE_ID denyIds[] = { // This occurs when there are uninitialized descriptors in a descriptor table, even when a // shader does not access the missing descriptors. D3D12_MESSAGE_ID_INVALID_DESCRIPTOR_HANDLE, }; D3D12_INFO_QUEUE_FILTER filter = {}; //filter.DenyList.NumCategories = _countof(categories); //filter.DenyList.pCategoryList = categories; filter.DenyList.NumSeverities = _countof(severities); filter.DenyList.pSeverityList = severities; filter.DenyList.NumIDs = _countof(denyIds); filter.DenyList.pIDList = denyIds; ThrowIfFailed(infoQueue->PushStorageFilter(&filter)); } #endif // Describe and create the command queue. D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; ThrowIfFailed(m_d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue))); NAME_D3D12_OBJECT(m_commandQueue); //MyTest add >> D3D12_COMMAND_QUEUE_DESC videoQueueDesc = {}; videoQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAGS::D3D12_COMMAND_QUEUE_FLAG_NONE; videoQueueDesc.Type = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS; ThrowIfFailed(m_d3d12Device->CreateCommandQueue(&videoQueueDesc, IID_PPV_ARGS(&m_pVideoCommandQueue))); NAME_D3D12_OBJECT(m_pVideoCommandQueue); //MyTest add << // Describe the swap chain. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.BufferCount = FrameCount; //swapChainDesc.Width = m_width; //swapChainDesc.Height = m_height; swapChainDesc.Width = 0xb0; //test param swapChainDesc.Height = 0x60; //test param swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.SampleDesc.Count = 1; ComPtr swapChain; ThrowIfFailed(factory->CreateSwapChainForHwnd( m_commandQueue.Get(), //m_pVideoCommandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it. m_MyWind, &swapChainDesc, nullptr, nullptr, &swapChain )); // This sample does not support fullscreen transitions. ThrowIfFailed(factory->MakeWindowAssociation(m_MyWind, DXGI_MWA_NO_ALT_ENTER)); ThrowIfFailed(swapChain.As(&m_swapChain)); m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); // Create an 11 device wrapped around the 12 device and share // 12's command queue. ComPtr d3d11Device; ThrowIfFailed(D3D11On12CreateDevice( m_d3d12Device.Get(), d3d11DeviceFlags, nullptr, 0, reinterpret_cast(m_commandQueue.GetAddressOf()), 1, 0, &d3d11Device, &m_d3d11DeviceContext, nullptr )); // Query the 11On12 device from the 11 device. ThrowIfFailed(d3d11Device.As(&m_d3d11On12Device)); // Create D2D/DWrite components. { D2D1_DEVICE_CONTEXT_OPTIONS deviceOptions = D2D1_DEVICE_CONTEXT_OPTIONS_NONE; ThrowIfFailed(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &m_d2dFactory)); ComPtr dxgiDevice; ThrowIfFailed(m_d3d11On12Device.As(&dxgiDevice)); ThrowIfFailed(m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)); ThrowIfFailed(m_d2dDevice->CreateDeviceContext(deviceOptions, &m_d2dDeviceContext)); ThrowIfFailed(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &m_dWriteFactory)); } // Query the desktop's dpi settings, which will be used to create // D2D's render targets. float dpiX; float dpiY; #pragma warning(push) #pragma warning(disable : 4996) // GetDesktopDpi is deprecated. m_d2dFactory->GetDesktopDpi(&dpiX, &dpiY); #pragma warning(pop) D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), dpiX, dpiY ); // Create descriptor heaps. { // Describe and create a render target view (RTV) descriptor heap. D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; rtvHeapDesc.NumDescriptors = FrameCount; rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; ThrowIfFailed(m_d3d12Device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap))); m_rtvDescriptorSize = m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); } // Create frame resources. { CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); // Create a RTV, D2D render target, and a command allocator for each frame. for (UINT n = 0; n < FrameCount; n++) { ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n]))); m_d3d12Device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle); NAME_D3D12_OBJECT_INDEXED(m_renderTargets, n); // Create a wrapped 11On12 resource of this back buffer. Since we are // rendering all D3D12 content first and then all D2D content, we specify // the In resource state as RENDER_TARGET - because D3D12 will have last // used it in this state - and the Out resource state as PRESENT. When // ReleaseWrappedResources() is called on the 11On12 device, the resource // will be transitioned to the PRESENT state. D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET }; ThrowIfFailed(m_d3d11On12Device->CreateWrappedResource( m_renderTargets[n].Get(), &d3d11Flags, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT, IID_PPV_ARGS(&m_wrappedBackBuffers[n]) )); // Create a render target for D2D to draw directly to this back buffer. ComPtr surface; ThrowIfFailed(m_wrappedBackBuffers[n].As(&surface)); ThrowIfFailed(m_d2dDeviceContext->CreateBitmapFromDxgiSurface( surface.Get(), &bitmapProperties, &m_d2dRenderTargets[n] )); rtvHandle.Offset(1, m_rtvDescriptorSize); ThrowIfFailed(m_d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n]))); //MyTest rep >> hres = m_d3d12Device->CreateCommandAllocator( D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS, IID_PPV_ARGS(&m_pVideoCommandAllocators[n])); //MyTest rep << } } //// DirextX11 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //CComPtr pCD3D11Device; //static D3D_FEATURE_LEVEL FeatureLevels[] = { // D3D_FEATURE_LEVEL_11_1, // D3D_FEATURE_LEVEL_11_0, // D3D_FEATURE_LEVEL_10_1, // D3D_FEATURE_LEVEL_10_0 //}; //D3D_FEATURE_LEVEL pFeatureLevelsOut; //CComPtr pDXGIFactory; //hres = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&pDXGIFactory)); //CComQIPtr pAdapter; //hres = pDXGIFactory->EnumAdapters(0, &pAdapter); //CComPtr pCD3D11Ctx; //hres = D3D11CreateDevice(pAdapter, // D3D_DRIVER_TYPE_UNKNOWN, // NULL, // 0, // FeatureLevels, // 4, // D3D11_SDK_VERSION, // &pCD3D11Device, // &pFeatureLevelsOut, // &pCD3D11Ctx); //if (FAILED(hres)) // return; // MFX_ERR_DEVICE_FAILED; //m_pDX11VideoDevice = pCD3D11Device; //m_pVideoContext = pCD3D11Ctx; //// DirextX11 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // Create Brush for Draw Text; LoadAssets(); } // Helper function for resolving the full path of assets. std::wstring ExD3D12_Device::GetAssetFullPath(LPCWSTR assetName) { return m_assetsPath + assetName; } // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. // If no such adapter can be found, *ppAdapter will be set to nullptr. _Use_decl_annotations_ void ExD3D12_Device::GetHardwareAdapter( IDXGIFactory1* pFactory, IDXGIAdapter1** ppAdapter, bool requestHighPerformanceAdapter) { *ppAdapter = nullptr; ComPtr adapter; ComPtr factory6; if (SUCCEEDED(pFactory->QueryInterface(IID_PPV_ARGS(&factory6)))) { for ( UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != factory6->EnumAdapterByGpuPreference( adapterIndex, requestHighPerformanceAdapter == true ? DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE : DXGI_GPU_PREFERENCE_UNSPECIFIED, IID_PPV_ARGS(&adapter)); ++adapterIndex) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { // Don't select the Basic Render Driver adapter. // If you want a software adapter, pass in "/warp" on the command line. continue; } // Check to see whether the adapter supports Direct3D 12, but don't create the // actual device yet. if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) { break; } } } else { for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { // Don't select the Basic Render Driver adapter. // If you want a software adapter, pass in "/warp" on the command line. continue; } // Check to see whether the adapter supports Direct3D 12, but don't create the // actual device yet. if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) { break; } } } *ppAdapter = adapter.Detach(); } mfxStatus ExD3D12_Device::Dx11CreateVideoProcessor(mfxFrameSurface1 * pSrf) { //// DirextX11 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //HRESULT hres = S_OK; //if (m_VideoProcessorEnum.p || NULL == pSrf) // return MFX_ERR_NONE; ////create video processor //D3D11_VIDEO_PROCESSOR_CONTENT_DESC ContentDesc; //MSDK_ZERO_MEMORY(ContentDesc); //ContentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; //ContentDesc.InputFrameRate.Numerator = 30000; //ContentDesc.InputFrameRate.Denominator = 1000; //ContentDesc.InputWidth = pSrf->Info.CropW; //ContentDesc.InputHeight = pSrf->Info.CropH; //ContentDesc.OutputWidth = pSrf->Info.CropW; //ContentDesc.OutputHeight = pSrf->Info.CropH; //ContentDesc.OutputFrameRate.Numerator = 30000; //ContentDesc.OutputFrameRate.Denominator = 1000; //ContentDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; //hres = m_pDX11VideoDevice->CreateVideoProcessorEnumerator(&ContentDesc, &m_VideoProcessorEnum); //if (FAILED(hres)) // return MFX_ERR_DEVICE_FAILED; //hres = m_pDX11VideoDevice->CreateVideoProcessor(m_VideoProcessorEnum, 0, &m_pVideoProcessor); //if (FAILED(hres)) // return MFX_ERR_DEVICE_FAILED; //// DirextX11 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return MFX_ERR_NONE; } mfxStatus ExD3D12_Device::Dx12CreateVideoProcessor(mfxFrameSurface1 * pSrf) { HRESULT hres = S_OK; if (NULL == pSrf) return MFX_ERR_INVALID_VIDEO_PARAM; int DescFrameRate = 30; const int INPUT_DESCS_MAX = 1; // desc counts UINT NodeMask = 0; // 0 :Single GPU D3D12_VIDEO_PROCESS_OUTPUT_STREAM_DESC OutputStreamDesc; UINT NumInputStreamDescs = INPUT_DESCS_MAX; D3D12_VIDEO_PROCESS_INPUT_STREAM_DESC InputStreamDescs[INPUT_DESCS_MAX]; // OUTPUT DESC //OutputStreamDesc.Format = DXGI_FORMAT::DXGI_FORMAT_NV12; OutputStreamDesc.Format = DXGI_FORMAT::DXGI_FORMAT_B8G8R8A8_UNORM; OutputStreamDesc.ColorSpace = DXGI_COLOR_SPACE_TYPE::DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; OutputStreamDesc.AlphaFillMode = D3D12_VIDEO_PROCESS_ALPHA_FILL_MODE::D3D12_VIDEO_PROCESS_ALPHA_FILL_MODE_OPAQUE; // Existing alpha values remain unchanged in the output surface. OutputStreamDesc.AlphaFillModeSourceStreamIndex = 0; // D3D12_VIDEO_PROCESS_ALPHA_FILL_MODE_SOURCE_STREAM is not used OutputStreamDesc.BackgroundColor[0] = 1; // RGBA:R / YCbCrA:Y OutputStreamDesc.BackgroundColor[1] = 1; // RGBA:G / YCbCrA:Cb OutputStreamDesc.BackgroundColor[2] = 1; // RGBA:B / YCbCrA:Cr OutputStreamDesc.BackgroundColor[3] = 1; // RGBA:A / YCbCrA:A OutputStreamDesc.FrameRate.Numerator = DescFrameRate; // DXGI_RATIONAL 30fps:30/1 OutputStreamDesc.FrameRate.Denominator = 1; OutputStreamDesc.EnableStereo = FALSE; // If TRUE, stereo output is enabled. Otherwise, the video processor produces mono video frames. // INPUT DESC UINT RANGE_MIN = 8; // 8未満だとINVALIDARGエラーになる。 (MSDNs info :mim = 1 ->err) UINT RANGE_MAN = 1920 * 4; // 8K相当程度ならエラーにならない  (MSDNs info :max = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION -> err) for (int i = 0; i < INPUT_DESCS_MAX; i++) { //InputStreamDescs[0].Format = DXGI_FORMAT::DXGI_FORMAT_NV12; // DXGI_FORMAT InputStreamDescs[i].Format = DXGI_FORMAT::DXGI_FORMAT_B8G8R8A8_UNORM; InputStreamDescs[i].ColorSpace = DXGI_COLOR_SPACE_TYPE::DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; // DXGI_COLOR_SPACE_TYPE InputStreamDescs[i].SourceAspectRatio.Numerator = 16; // DXGI_RATIONAL InputStreamDescs[i].SourceAspectRatio.Denominator = 9; InputStreamDescs[i].DestinationAspectRatio.Numerator = 16; // DXGI_RATIONAL InputStreamDescs[i].DestinationAspectRatio.Denominator = 9; InputStreamDescs[i].FrameRate.Numerator = DescFrameRate; // DXGI_RATIONAL InputStreamDescs[i].FrameRate.Denominator = 1; InputStreamDescs[i].SourceSizeRange.MinWidth = RANGE_MIN; // ×:1 InputStreamDescs[i].SourceSizeRange.MinHeight = RANGE_MIN; // ×:1 InputStreamDescs[i].SourceSizeRange.MaxWidth = RANGE_MAN; // ×:D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; InputStreamDescs[i].SourceSizeRange.MaxHeight = RANGE_MAN; // ×:D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; InputStreamDescs[i].DestinationSizeRange.MinWidth = RANGE_MIN; // ×:1 InputStreamDescs[i].DestinationSizeRange.MinHeight = RANGE_MIN; // ×:1 InputStreamDescs[i].DestinationSizeRange.MaxWidth = RANGE_MAN; // ×:D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; InputStreamDescs[i].DestinationSizeRange.MaxHeight = RANGE_MAN; // ×:D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; InputStreamDescs[i].EnableOrientation = FALSE; InputStreamDescs[i].FilterFlags = D3D12_VIDEO_PROCESS_FILTER_FLAGS::D3D12_VIDEO_PROCESS_FILTER_FLAG_NONE; //InputStreamDescs[i].FilterFlags = D3D12_VIDEO_PROCESS_FILTER_FLAGS::D3D12_VIDEO_PROCESS_FILTER_FLAG_BRIGHTNESS | D3D12_VIDEO_PROCESS_FILTER_FLAGS::D3D12_VIDEO_PROCESS_FILTER_FLAG_CONTRAST | D3D12_VIDEO_PROCESS_FILTER_FLAGS::D3D12_VIDEO_PROCESS_FILTER_FLAG_ANAMORPHIC_SCALING; InputStreamDescs[i].StereoFormat = D3D12_VIDEO_FRAME_STEREO_FORMAT::D3D12_VIDEO_FRAME_STEREO_FORMAT_MONO; InputStreamDescs[i].FieldType = D3D12_VIDEO_FIELD_TYPE::D3D12_VIDEO_FIELD_TYPE_NONE; // The frame is progressive. InputStreamDescs[i].DeinterlaceMode = D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG_NONE; // D3D12_VIDEO_PROCESS_DEINTERLACE_FLAGS::D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG_NONE; InputStreamDescs[i].EnableAlphaBlending = FALSE; InputStreamDescs[i].LumaKey.Enable = FALSE; // D3D12_VIDEO_PROCESS_LUMA_KEY InputStreamDescs[i].LumaKey.Lower = 0.500000; InputStreamDescs[i].LumaKey.Upper = 270.000000; InputStreamDescs[i].NumPastFrames = 0; InputStreamDescs[i].NumFutureFrames = 0; InputStreamDescs[i].EnableAutoProcessing = FALSE; } hres = m_pDX12VideoDevice->CreateVideoProcessor(NodeMask, &OutputStreamDesc, NumInputStreamDescs, InputStreamDescs, IID_PPV_ARGS(&m_pDX12VideoProcessor)); if (FAILED(hres)) return MFX_ERR_DEVICE_FAILED; hres = m_d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS, m_pVideoCommandAllocators[m_frameIndex].Get(), nullptr, IID_PPV_ARGS(&m_pID3D12VideoProcessCommandList1)); if (FAILED(hres)) return MFX_ERR_DEVICE_FAILED; return MFX_ERR_NONE; } mfxStatus ExD3D12_Device::RenderFrame(mfxFrameSurface1 * pSrf, mfxFrameAllocator * pAlloc) { HRESULT hres = S_OK; mfxStatus sts; // NV12 surface to RGB backbuffer RECT rect = { 0 }; rect.right = pSrf->Info.CropW; rect.bottom = pSrf->Info.CropH; //sts = Dx11CreateVideoProcessor(pSrf); //MSDK_CHECK_STATUS(sts, "CreateDx11VideoProcessor failed"); sts = Dx12CreateVideoProcessor(pSrf); MSDK_CHECK_STATUS(sts, "CreateDx12VideoProcessor failed"); //hres = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_pDX12GIBackBuffer.p); // Not Surported hres = m_swapChain->GetBuffer(0, IID_PPV_ARGS(&m_pVideoRenderTargets[FrameCount])); if (FAILED(hres)) return MFX_ERR_DEVICE_FAILED; mfxHDLPair pair = { NULL }; sts = pAlloc->GetHDL(pAlloc->pthis, pSrf->Data.MemId, (mfxHDL*)&pair); MSDK_CHECK_STATUS(sts, "pAlloc->GetHDL failed"); ID3D11Texture2D *pRTTexture2D = reinterpret_cast(pair.first); //ID3D12Resource *pRTTexture2D = reinterpret_cast(pair.first); // can not cast (err) ID3D12Resource *pOut12RTTexture2D = m_pVideoRenderTargets[FrameCount].Get(); // (ID3D12Resource*)(m_pDX12GIBackBuffer.Get()); #if 0 // try to reinterpret_cast ID3D12Resource *pIn12RTTexture2D = reinterpret_cast(pRTTexture2D); // error on ProcessFrames1() #else #if 1 // try to copy resource ComPtr surface; ThrowIfFailed(m_wrappedBackBuffers[m_frameIndex].As(&surface)); // try to call D3D11: Copy the entire contents of the source resource to the destination resource using the GPU. m_d3d11DeviceContext->CopyResource(surface.Get(), pRTTexture2D); ID3D12Resource *pIn12RTTexture2D = reinterpret_cast(surface.Get()); // error on ProcessFrames1() #else // try to get byte data sts = pAlloc->Lock(pAlloc->pthis, pSrf->Data.MemId, &pSrf->Data); MSDK_CHECK_STATUS(sts, "pAllocator->Lock of pSurface failed"); BYTE DestBuf[30000] = { 0 }; int wordsNum = pSrf->Data.Pitch*pSrf->Info.Height * 3 / 16; // Number of 8-byte words mfxU64* pBuf = (mfxU64*)pSrf->Data.Y16; mfxU64* pDestBuf = (mfxU64*)&DestBuf[0]; for (int i = 0; i < wordsNum; i++) { //pDestBuf[i] = (pBuf[i] << 6) & 0xFFC0FFC0FFC0FFC0; pDestBuf[i] = pBuf[i]; } sts = pAlloc->Unlock(pAlloc->pthis, pSrf->Data.MemId, &pSrf->Data); MSDK_CHECK_STATUS(sts, "pAllocator->Unlock of pSurface failed"); UINT siz = (UINT)(wordsNum * sizeof(mfxU64)); BYTE *p2DBuf = &DestBuf[0]; /*GUID bufId = __uuidof(pOut12RTTexture2D); hres = pIn12RTTexture2D->SetPrivateData(bufId, siz, p2DBuf); */ GUID bufId = __uuidof(ID3D11Texture2D); //hres = surface.Get()->SetPrivateData(bufId, siz, p2DBuf); ComPtr surface; ThrowIfFailed(m_wrappedBackBuffers[m_frameIndex].As(&surface)); ID3D12Resource *pIn12RTTexture2D = reinterpret_cast(surface.Get()); // error on ProcessFrames1() #endif #endif // Test Draw Text "11 on 12" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> this->RenderUI(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< D3D12_VIDEO_PROCESS_OUTPUT_STREAM_ARGUMENTS outputStreamArgs; outputStreamArgs.TargetRectangle.left = rect.left; outputStreamArgs.TargetRectangle.top = rect.top; outputStreamArgs.TargetRectangle.right = rect.right; outputStreamArgs.TargetRectangle.bottom = rect.bottom; outputStreamArgs.OutputStream[0].pTexture2D = pOut12RTTexture2D; outputStreamArgs.OutputStream[0].Subresource = NULL; outputStreamArgs.OutputStream[1].pTexture2D = nullptr; outputStreamArgs.OutputStream[1].Subresource = NULL; const int INPUT_ARG_MAX = 1; D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1 inputStreamArgs[INPUT_ARG_MAX]; for (int i = 0; i < INPUT_ARG_MAX; i++) { inputStreamArgs[i].InputStream[0].pTexture2D = pIn12RTTexture2D; // D3D12_VIDEO_PROCESS_INPUT_STREAM; inputStreamArgs[i].InputStream[0].ReferenceSet.NumPastFrames = 0; // The number of past reference frames provided in ppPastFrames. inputStreamArgs[i].InputStream[0].ReferenceSet.ppPastFrames = NULL; // A pointer to an array of ID3D12Resource surfaces. The number of elements in the array is NumPastFrames. inputStreamArgs[i].InputStream[0].ReferenceSet.pPastSubresources = NULL; // An array of subresource indices for the list of ppPastFrames textures. NULL indicates subresource 0 for each resource. inputStreamArgs[i].InputStream[0].ReferenceSet.NumFutureFrames = 0; // The number of future reference frames provided in ppPastFrames. inputStreamArgs[i].InputStream[0].ReferenceSet.ppFutureFrames = NULL; // A pointer to an array of ID3D12Resource surfaces. The number of elements in the array is NumFutureFrames. inputStreamArgs[i].InputStream[0].ReferenceSet.pFutureSubresources = NULL; // An array of subresource indices for the list of ppFutureFrames textures. NULL indicates subresource 0 for each resource. inputStreamArgs[i].InputStream[0].Subresource = NULL; inputStreamArgs[i].InputStream[1].pTexture2D = nullptr; // D3D12_VIDEO_PROCESS_INPUT_STREAM; inputStreamArgs[i].InputStream[1].ReferenceSet.NumPastFrames = 0; // The number of past reference frames provided in ppPastFrames. inputStreamArgs[i].InputStream[1].ReferenceSet.ppPastFrames = NULL; // A pointer to an array of ID3D12Resource surfaces. The number of elements in the array is NumPastFrames. inputStreamArgs[i].InputStream[1].ReferenceSet.pPastSubresources = NULL; // An array of subresource indices for the list of ppPastFrames textures. NULL indicates subresource 0 for each resource. inputStreamArgs[i].InputStream[1].ReferenceSet.NumFutureFrames = 0; // The number of future reference frames provided in ppPastFrames. inputStreamArgs[i].InputStream[1].ReferenceSet.ppFutureFrames = NULL; // A pointer to an array of ID3D12Resource surfaces. The number of elements in the array is NumFutureFrames. inputStreamArgs[i].InputStream[1].ReferenceSet.pFutureSubresources = NULL; // An array of subresource indices for the list of ppFutureFrames textures. NULL indicates subresource 0 for each resource. inputStreamArgs[i].InputStream[1].Subresource = NULL; inputStreamArgs[i].Transform.DestinationRectangle.left = rect.left; inputStreamArgs[i].Transform.DestinationRectangle.top = rect.top; inputStreamArgs[i].Transform.DestinationRectangle.right = rect.right; inputStreamArgs[i].Transform.DestinationRectangle.bottom = rect.bottom; inputStreamArgs[i].Transform.Orientation = D3D12_VIDEO_PROCESS_ORIENTATION::D3D12_VIDEO_PROCESS_ORIENTATION_DEFAULT; inputStreamArgs[i].Transform.SourceRectangle.left = rect.left; inputStreamArgs[i].Transform.SourceRectangle.top = rect.top; inputStreamArgs[i].Transform.SourceRectangle.right = rect.right; inputStreamArgs[i].Transform.SourceRectangle.bottom = rect.bottom; inputStreamArgs[i].Flags = D3D12_VIDEO_PROCESS_INPUT_STREAM_FLAGS::D3D12_VIDEO_PROCESS_INPUT_STREAM_FLAG_NONE; inputStreamArgs[i].RateInfo.InputFrameOrField = 0; // D3D12_VIDEO_PROCESS_INPUT_STREAM_RATE; inputStreamArgs[i].RateInfo.OutputIndex = 0; inputStreamArgs[i].FieldType = D3D12_VIDEO_FIELD_TYPE::D3D12_VIDEO_FIELD_TYPE_NONE; for (int j = 0; j > sizeof(D3D12_VIDEO_PROCESS_INPUT_STREAM_ARGUMENTS1::FilterLevels); j++) { inputStreamArgs[i].FilterLevels[j] = 0; } inputStreamArgs[i].AlphaBlending.Enable = FALSE; // D3D12_VIDEO_PROCESS_ALPHA_BLENDING: FALSE=Disable inputStreamArgs[i].AlphaBlending.Alpha = 1.0f; // 1.0=opaque } // error //m_pID3D12VideoProcessCommandList1->ProcessFrames1(m_pDX12VideoProcessor.Get(), &outputStreamArgs, INPUT_ARG_MAX, &inputStreamArgs[0]); // displayed DXGI_PRESENT_PARAMETERS parameters = { 0 }; hres = m_swapChain->Present1(0, 0, ¶meters); if (FAILED(hres)) return MFX_ERR_DEVICE_FAILED; // check result of ProcessFrames1() hres = m_pID3D12VideoProcessCommandList1->Close(); if (FAILED(hres)) return MFX_ERR_DEVICE_FAILED; return MFX_ERR_NONE; } // Load the sample assets. (for Draw Text) void ExD3D12_Device::LoadAssets() { // Create an empty root signature. { CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr signature; ComPtr error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); NAME_D3D12_OBJECT(m_rootSignature); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr vertexShader; ComPtr pixelShader; #if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"C:/Dxbin/shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"C:/Dxbin/shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; // Describe and create the graphics pipeline state object (PSO). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = CD3DX12_SHADER_BYTECODE(vertexShader.Get()); psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShader.Get()); psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_d3d12Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); NAME_D3D12_OBJECT(m_pipelineState); } ThrowIfFailed(m_d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); NAME_D3D12_OBJECT(m_commandList); // Create D2D/DWrite objects for rendering text. { ThrowIfFailed(m_d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::CadetBlue), &m_textBrush)); ThrowIfFailed(m_dWriteFactory->CreateTextFormat( L"Verdana", NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 50, L"en-us", &m_textFormat )); ThrowIfFailed(m_textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_JUSTIFIED)); ThrowIfFailed(m_textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR)); } // Close the command list and execute it to begin the vertex buffer copy into // the default heap. ThrowIfFailed(m_commandList->Close()); ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); }