mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-11-01 19:28:02 +03:00
init
This commit is contained in:
12511 files changed
+6156641
No files matched your search
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hmft_entrypoints.h"
|
||||
#include "videobufferlock.h"
|
||||
|
||||
// utility functions to retrieve plane information from IMFMediaType
|
||||
HRESULT
|
||||
MFTypeToBitmapInfo(
|
||||
IMFMediaType *pType, UINT32 *pcbActualBytesPerLine, UINT32 *punLines, UINT32 *pcbSBytesPerLine, UINT32 *punSLines )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
LONG lMinPitch;
|
||||
UINT32 unWidth, unHeight;
|
||||
UINT32 cbImageSize, cbActualBytesPerLine, unLines;
|
||||
GUID format;
|
||||
CHECKHR_GOTO( pType->GetGUID( MF_MT_SUBTYPE, &format ), done );
|
||||
CHECKHR_GOTO( MFGetAttributeSize( pType, MF_MT_FRAME_SIZE, &unWidth, &unHeight ), done );
|
||||
CHECKHR_GOTO( MFCalculateImageSize( format, unWidth, unHeight, &cbImageSize ), done );
|
||||
CHECKHR_GOTO( MFGetStrideForBitmapInfoHeader( format.Data1, unWidth, &lMinPitch ), done );
|
||||
|
||||
cbActualBytesPerLine = abs( lMinPitch );
|
||||
|
||||
// dual half-planar formats
|
||||
if( format == MFVideoFormat_YV12 || format == MFVideoFormat_IYUV || format == MFVideoFormat_I420 )
|
||||
{
|
||||
unLines = cbImageSize / ( cbActualBytesPerLine + cbActualBytesPerLine / 2 );
|
||||
if( nullptr != pcbSBytesPerLine )
|
||||
*pcbSBytesPerLine = cbActualBytesPerLine / 2;
|
||||
// processing 2 half planes with half lines, should process double lines
|
||||
if( nullptr != punSLines )
|
||||
*punSLines = unLines;
|
||||
}
|
||||
else
|
||||
{
|
||||
unLines = cbImageSize / cbActualBytesPerLine;
|
||||
if( nullptr != pcbSBytesPerLine )
|
||||
*pcbSBytesPerLine = 0;
|
||||
if( nullptr != punSLines )
|
||||
*punSLines = 0;
|
||||
}
|
||||
|
||||
if( nullptr != pcbActualBytesPerLine )
|
||||
*pcbActualBytesPerLine = cbActualBytesPerLine;
|
||||
if( nullptr != punLines )
|
||||
*punLines = unLines;
|
||||
done:
|
||||
return hr;
|
||||
}
|
||||
|
||||
// utility function to retrieve default image size from IMFMediaType
|
||||
HRESULT
|
||||
MFTypeToImageSize( IMFMediaType *pType, UINT32 *pcbSize )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
UINT32 unWidth, unHeight;
|
||||
UINT32 cbImageSize;
|
||||
GUID format;
|
||||
CHECKHR_GOTO( pType->GetGUID( MF_MT_SUBTYPE, &format ), done );
|
||||
CHECKHR_GOTO( MFGetAttributeSize( pType, MF_MT_FRAME_SIZE, &unWidth, &unHeight ), done );
|
||||
CHECKHR_GOTO( MFCalculateImageSize( format, unWidth, unHeight, &cbImageSize ), done );
|
||||
*pcbSize = cbImageSize;
|
||||
done:
|
||||
return hr;
|
||||
}
|
||||
|
||||
// utility function to retrieve D3D11 texture from IMFMediaBuffer
|
||||
HRESULT
|
||||
MFBufferToDXType( _In_ IMFMediaBuffer *pBuffer, _Outptr_ ID3D11Texture2D **ppTexture, _Out_ UINT *uiViewIndex )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
ComPtr<IMFDXGIBuffer> spDXGIBuffer;
|
||||
|
||||
hr = pBuffer->QueryInterface( __uuidof( IMFDXGIBuffer ), (LPVOID *) ( &spDXGIBuffer ) );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = spDXGIBuffer->GetResource( __uuidof( ID3D11Texture2D ), (LPVOID *) ppTexture );
|
||||
}
|
||||
if( SUCCEEDED( hr ) && uiViewIndex != nullptr )
|
||||
{
|
||||
hr = spDXGIBuffer->GetSubresourceIndex( uiViewIndex );
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// utility function to retrieve D3D12 texture from IMFMediaBuffer
|
||||
HRESULT
|
||||
MFBufferToDXType( _In_ IMFMediaBuffer *pBuffer, _Outptr_ ID3D12Resource **ppTexture, _Out_ UINT *uiViewIndex )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
ComPtr<IMFDXGIBuffer> spDXGIBuffer;
|
||||
|
||||
hr = pBuffer->QueryInterface( __uuidof( IMFDXGIBuffer ), (LPVOID *) ( &spDXGIBuffer ) );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = spDXGIBuffer->GetResource( __uuidof( ID3D12Resource ), (LPVOID *) ppTexture );
|
||||
}
|
||||
if( SUCCEEDED( hr ) && uiViewIndex != nullptr )
|
||||
{
|
||||
hr = spDXGIBuffer->GetSubresourceIndex( uiViewIndex );
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// utility function to copy MFSample
|
||||
HRESULT
|
||||
MFCopySample( IMFSample *dest, IMFSample *src, IMFMediaType *pmt )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
ComPtr<IMFMediaBuffer> pOutput, pInput;
|
||||
ComPtr<ID3D11Texture2D> srcTexture, dstTexture;
|
||||
ComPtr<ID3D11Device> pSrcDevice, pDstDevice;
|
||||
ComPtr<ID3D11DeviceContext> pCtx;
|
||||
UINT uiSrcIndex, uiDstIndex;
|
||||
DWORD dwBufferCount;
|
||||
UINT32 dwSize = 0;
|
||||
BOOL bUsedDX = FALSE;
|
||||
UINT32 cbActualBytesPerLine, unLines, cbSActualBytes, unSLines;
|
||||
|
||||
CHECKHR_GOTO( MFTypeToBitmapInfo( pmt, &cbActualBytesPerLine, &unLines, &cbSActualBytes, &unSLines ), done );
|
||||
|
||||
if( !dest || !src )
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
(void) src->CopyAllItems( dest );
|
||||
|
||||
LONGLONG hnsTime;
|
||||
hr = src->GetSampleTime( &hnsTime );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = dest->SetSampleTime( hnsTime );
|
||||
}
|
||||
hr = S_OK;
|
||||
|
||||
LONGLONG hnsDuration;
|
||||
hr = src->GetSampleDuration( &hnsDuration );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = dest->SetSampleDuration( hnsDuration );
|
||||
}
|
||||
hr = S_OK;
|
||||
|
||||
hr = src->GetBufferCount( &dwBufferCount );
|
||||
|
||||
if( SUCCEEDED( hr ) )
|
||||
for( DWORD x = 0; x < dwBufferCount; x++ )
|
||||
{
|
||||
hr = src->GetBufferByIndex( x, &pInput );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
hr = dest->GetBufferByIndex( x, &pOutput );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
hr = MFCreateMediaBufferFromMediaType( pmt, hnsDuration, 0, 0, &pOutput );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
hr = dest->AddBuffer( pOutput.Get() );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to use DX if available
|
||||
if( SUCCEEDED( MFBufferToDXType( pOutput.Get(), &srcTexture, &uiSrcIndex ) ) &&
|
||||
SUCCEEDED( MFBufferToDXType( pInput.Get(), &dstTexture, &uiDstIndex ) ) )
|
||||
{
|
||||
srcTexture->GetDevice( &pSrcDevice );
|
||||
dstTexture->GetDevice( &pDstDevice );
|
||||
if( pSrcDevice != pDstDevice )
|
||||
{
|
||||
// TODO: if both are shared we can keyed mutex them across
|
||||
}
|
||||
else
|
||||
{
|
||||
pSrcDevice->GetImmediateContext( &pCtx );
|
||||
pCtx->CopySubresourceRegion( dstTexture.Get(), uiDstIndex, 0, 0, 0, srcTexture.Get(), uiSrcIndex, NULL );
|
||||
bUsedDX = TRUE;
|
||||
}
|
||||
|
||||
hr = MFTypeToImageSize( pmt, &dwSize );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !bUsedDX )
|
||||
{
|
||||
VideoBufferLock inputLock( pInput.Get(), pmt );
|
||||
VideoBufferLock outputLock( pOutput.Get(), pmt );
|
||||
|
||||
hr = inputLock.lock( MF2DBuffer_LockFlags_Read );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
hr = outputLock.lock( MF2DBuffer_LockFlags_Write );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hr = MFCopyImage( outputLock.data(),
|
||||
outputLock.stride(),
|
||||
inputLock.data(),
|
||||
inputLock.stride(),
|
||||
cbActualBytesPerLine,
|
||||
unLines );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( unSLines )
|
||||
{
|
||||
hr = MFCopyImage( outputLock.data(),
|
||||
outputLock.stride(),
|
||||
inputLock.data(),
|
||||
inputLock.stride(),
|
||||
cbSActualBytes,
|
||||
unSLines );
|
||||
}
|
||||
|
||||
dwSize = inputLock.size();
|
||||
}
|
||||
|
||||
hr = pOutput->SetCurrentLength( dwSize );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// MFAttachPipeResourceAsSampleExtension
|
||||
//
|
||||
// Description:
|
||||
// Converts a Gallium pipe_resource into a D3D12 resource and wraps it as an IMFMediaBuffer,
|
||||
// then attaches it as a sample extension on an IMFSample using the specified GUID.
|
||||
//
|
||||
// Parameters:
|
||||
// pPipeContext - Pointer to the Gallium pipe context.
|
||||
// pPipeRes - Pointer to the pipe_resource to be wrapped.
|
||||
// pSyncObjectQueue - Pointer to the sync object command queue.
|
||||
// guidExtension - The GUID of the Media Foundation sample extension to attach the buffer as.
|
||||
// pSample - The output IMFSample to attach the media buffer to.
|
||||
//
|
||||
// Returns:
|
||||
// S_OK if the operation was successful.
|
||||
// E_INVALIDARG if any required pointer is null.
|
||||
// E_FAIL if resource_get_handle fails.
|
||||
// E_POINTER if the returned COM object is null.
|
||||
// Other HRESULT failure codes from MFCreateDXGISurfaceBuffer or SetUnknown.
|
||||
//
|
||||
HRESULT
|
||||
MFAttachPipeResourceAsSampleExtension( struct pipe_context *pPipeContext,
|
||||
struct pipe_resource *pPipeRes,
|
||||
UINT PipeResourceReconstructedPictureSubresource,
|
||||
ID3D12CommandQueue *pSyncObjectQueue,
|
||||
REFGUID guidExtension,
|
||||
IMFSample *pSample )
|
||||
{
|
||||
if( !pPipeContext || !pPipeRes || !pSample || !pSyncObjectQueue )
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
struct winsys_handle whandle = {};
|
||||
whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
|
||||
|
||||
if( !pPipeContext->screen->resource_get_handle( pPipeContext->screen, pPipeContext, pPipeRes, &whandle, 0u ) )
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if( !whandle.com_obj )
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
ID3D12Resource *pD3D12Res = static_cast<ID3D12Resource *>( whandle.com_obj );
|
||||
ComPtr<IMFMediaBuffer> spMediaBuffer;
|
||||
HRESULT hr = MFCreateDXGISurfaceBuffer( __uuidof( ID3D12Resource ),
|
||||
pD3D12Res,
|
||||
PipeResourceReconstructedPictureSubresource,
|
||||
FALSE,
|
||||
&spMediaBuffer );
|
||||
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Tell MF that this buffer is ready to use.
|
||||
ComPtr<IMFD3D12SynchronizationObjectCommands> spOutputSync; // needed to call Lock() for IMFMediaBuffer.
|
||||
ComPtr<IMFDXGIBuffer> spDxgiBuffer;
|
||||
hr = spMediaBuffer->QueryInterface( IID_PPV_ARGS( &spDxgiBuffer ) );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = spDxgiBuffer->GetUnknown( MF_D3D12_SYNCHRONIZATION_OBJECT, IID_PPV_ARGS( &spOutputSync ) );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = spOutputSync->EnqueueResourceReady( pSyncObjectQueue );
|
||||
if( FAILED( hr ) )
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
return pSample->SetUnknown( guidExtension, spMediaBuffer.Get() );
|
||||
}
|
||||
Reference in new issue
Block a user