VBoxVideoVhwa.cpp revision 7704ab3cf2fe38a3307d6abee1f097fa4346e20e
/*
* Copyright (C) 2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "../VBoxVideo.h"
#include "../Helper.h"
#ifndef VBOXVHWA_WITH_SHGSMI
# include <iprt/semaphore.h>
#endif
DECLINLINE(void) vboxVhwaHdrInit(VBOXVHWACMD* pHdr, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, VBOXVHWACMD_TYPE enmCmd)
{
#ifndef VBOXVHWA_WITH_SHGSMI
#endif
}
#ifdef VBOXVHWA_WITH_SHGSMI
{
return VINF_SUCCESS;
}
#else
{
if(!cRefs)
{
}
}
{
}
/* do not wait for completion */
void vboxVhwaCommandSubmitAsynch(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd, PFNVBOXVHWACMDCOMPLETION pfnCompletion, void * pContext)
{
{
/* the command is completed */
}
}
static DECLCALLBACK(void) vboxVhwaCompletionSetEvent(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD * pCmd, void * pvContext)
{
}
void vboxVhwaCommandSubmitAsynchByEvent(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd, RTSEMEVENT hEvent)
{
}
#endif
{
}
VBOXVHWACMD* vboxVhwaCommandCreate(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd)
{
#ifdef VBOXVHWA_WITH_SHGSMI
#else
#endif
if (!pHdr)
{
}
else
{
}
return pHdr;
}
{
#ifdef VBOXVHWA_WITH_SHGSMI
#else
#endif
}
{
#ifdef VBOXVHWA_WITH_SHGSMI
const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
int rc = VERR_GENERAL_FAILURE;
if (pHdr)
{
do
{
if (offCmd != HGSMIOFFSET_VOID)
{
if (RT_SUCCESS(rc))
{
break;
}
}
else
/* fail to submit, cancel it */
} while (0);
}
else
return rc;
#else
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
}
return rc;
#endif
}
#ifndef VBOXVHWA_WITH_SHGSMI
static DECLCALLBACK(void) vboxVhwaCompletionFreeCmd(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD * pCmd, void * pContext)
{
}
{
{
/* need to save next since the command may be released in a pfnCallback and thus its data might be invalid */
}
}
#endif
{
#ifdef VBOXVHWA_WITH_SHGSMI
# error "port me"
#else
#endif
}
{
}
{
}
VBOXVHWACMD_QUERYINFO1* vboxVhwaQueryHostInfo1(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
{
VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_QUERY_INFO1, sizeof(VBOXVHWACMD_QUERYINFO1));
if (!pCmd)
{
drprintf((0, "VBoxDISP::vboxVhwaQueryHostInfo1: vboxVhwaCommandCreate failed\n"));
return NULL;
}
if(RT_SUCCESS(rc))
{
{
}
}
return NULL;
}
VBOXVHWACMD_QUERYINFO2* vboxVhwaQueryHostInfo2(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, uint32_t numFourCC)
{
VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_QUERY_INFO2, VBOXVHWAINFO2_SIZE(numFourCC));
if (!pCmd)
{
drprintf((0, "VBoxDISP::vboxVhwaQueryHostInfo2: vboxVhwaCommandCreate failed\n"));
return NULL;
}
if(RT_SUCCESS(rc))
{
{
{
return pInfo2;
}
}
}
return NULL;
}
{
int rc = VERR_GENERAL_FAILURE;
if (!pCmd)
{
drprintf((0, "VBoxDISP::vboxVhwaEnable: vboxVhwaCommandCreate failed\n"));
return rc;
}
if(RT_SUCCESS(rc))
{
rc = VINF_SUCCESS;
else
}
return rc;
}
{
int rc = VERR_GENERAL_FAILURE;
if (!pCmd)
{
drprintf((0, "VBoxDISP::vboxVhwaDisable: vboxVhwaCommandCreate failed\n"));
return rc;
}
if(RT_SUCCESS(rc))
{
rc = VINF_SUCCESS;
else
}
return rc;
}
DECLINLINE(VOID) vboxVhwaHlpOverlayListInit(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
{
}
{
if (pInfo1)
{
{
{
{
{
/* todo: VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE ? */
}
{
/* todo: VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE ? */
}
}
{
if (pInfo2)
{
{
}
}
}
}
}
}
}
{
{
}
}
{
* to ensure all pending commands are flushed */
{
vboxVhwaDisable(pDevExt, i);
}
}
{
switch (enmFormat)
{
case D3DDDIFMT_A8R8G8B8:
case D3DDDIFMT_X8R8G8B8:
/* always zero for now */
return VINF_SUCCESS;
case D3DDDIFMT_R8G8B8:
/* always zero for now */
return VINF_SUCCESS;
case D3DDDIFMT_R5G6B5:
/* always zero for now */
return VINF_SUCCESS;
case D3DDDIFMT_P8:
case D3DDDIFMT_A8:
case D3DDDIFMT_X1R5G5B5:
case D3DDDIFMT_A1R5G5B5:
case D3DDDIFMT_A4R4G4B4:
case D3DDDIFMT_R3G3B2:
case D3DDDIFMT_A8R3G3B2:
case D3DDDIFMT_X4R4G4B4:
case D3DDDIFMT_A2B10G10R10:
case D3DDDIFMT_A8B8G8R8:
case D3DDDIFMT_X8B8G8R8:
case D3DDDIFMT_G16R16:
case D3DDDIFMT_A2R10G10B10:
case D3DDDIFMT_A16B16G16R16:
case D3DDDIFMT_A8P8:
default:
{
if (fourcc)
{
return VINF_SUCCESS;
}
return VERR_NOT_SUPPORTED;
}
}
}
{
if (!pSurf->hHostHandle)
return VERR_INVALID_STATE;
if(pCmd)
{
/* we're not interested in completion, just send the command */
return VINF_SUCCESS;
}
return VERR_OUT_OF_RESOURCES;
}
{
if (fFlags & VBOXVHWA_SD_PITCH)
{
}
if (cBackBuffers)
{
}
else
pInfo->cBackBuffers = 0;
/* @todo: color keys */
// pInfo->DstOverlayCK;
// pInfo->DstBltCK;
// pInfo->SrcOverlayCK;
// pInfo->SrcBltCK;
if (RT_SUCCESS(rc))
{
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (!(fFlags & VBOXVHWA_SD_PITCH))
{
/* should be set by host */
// Assert(pInfo->flags & VBOXVHWA_SD_PITCH);
/* @todo: make this properly */
}
else
{
{
}
}
{
}
return rc;
}
{
/* the first thing we need is to post create primary */
if (pCmd)
{
int rc = VINF_SUCCESS;
if (RT_SUCCESS(rc))
{
{
}
else
}
return rc;
}
return VERR_OUT_OF_RESOURCES;
}
int vboxVhwaHlpGetSurfInfoForSource(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
{
/* the first thing we need is to post create primary */
if (pCmd)
{
int rc = VINF_SUCCESS;
0, 0, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX,
if (RT_SUCCESS(rc))
{
{
}
else
}
return rc;
}
return VERR_OUT_OF_RESOURCES;
}
{
{
{
return rc;
}
}
return VERR_NOT_SUPPORTED;
}
int vboxVhwaHlpDestroyPrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
{
return rc;
}
int vboxVhwaHlpCreatePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
{
return VERR_INVALID_STATE;
VBOXVHWA_SD_PITCH, 0, VBOXVHWA_SCAPS_PRIMARYSURFACE | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM,
return rc;
}
{
return VERR_INVALID_PARAMETER;
return VERR_NOT_SUPPORTED;
int rc = VINF_SUCCESS;
/* @todo: need a better sync */
if (cNew == 1)
{
if (RT_SUCCESS(rc))
{
if (RT_FAILURE(rc))
{
}
}
}
else
{
if (pFbSurf->hHostHandle)
else
}
if (RT_FAILURE(rc))
return rc;
}
{
return VERR_INVALID_PARAMETER;
/* @todo: need a better sync */
int rc = VINF_SUCCESS;
if (!cNew)
{
}
else
{
}
return rc;
}
{
int rc = VINF_SUCCESS;
{
VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
if(pCmd)
{
// pBody->TargGuestSurfInfo;
// pBody->CurrGuestSurfInfo;
{
else
{
/* top & left are zero-inited with the above memset */
}
}
/* we're not interested in completion, just send the command */
rc = VINF_SUCCESS;
}
else
}
else
return rc;
}
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
{
/* check if this is a primary surf */
{
}
}
#endif
int rc;
VBOXVHWACMD_TYPE_SURF_FLIP, RT_OFFSETOF(VBOXVHWACMD_SURF_COLORFILL, u.in.aRects[pCF->ClrFill.Rects.cRects]));
if(pCmd)
{
memcpy (pBody->u.in.aRects, pCF->ClrFill.Rects.aRects, pCF->ClrFill.Rects.cRects * sizeof (pCF->ClrFill.Rects.aRects[0]));
rc = VINF_SUCCESS;
}
else
return rc;
}
static void vboxVhwaHlpOverlayDstRectSet(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay, const RECT *pRect)
{
}
{
}
{
}
int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo, RECT * pDstUpdateRect)
{
int rc = VINF_SUCCESS;
{
if(pCmd)
{
{
}
{
}
{
else
{
/* top & left are zero-inited with the above memset */
}
}
if (pDstUpdateRect)
{
}
/* we're not interested in completion, just send the command */
rc = VINF_SUCCESS;
}
else
}
else
return rc;
}
{
}
{
int rc = VINF_SUCCESS;
{
}
if (RT_SUCCESS(rc))
{
}
return rc;
}
int vboxVhwaHlpOverlayCreate(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, DXGK_OVERLAYINFO *pOverlayInfo,
{
if (RT_SUCCESS(rc))
{
{
0, pRc->cAllocations - 1, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX,
if (!RT_SUCCESS(rc))
{
int tmpRc;
for (uint32_t j = 0; j < i; ++j)
{
}
break;
}
}
if (RT_SUCCESS(rc))
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
/* ignore primary update failure */
#endif
if (!RT_SUCCESS(rc))
{
}
}
if (RT_FAILURE(rc))
{
}
}
return rc;
}
BOOLEAN vboxVhwaHlpOverlayListIsEmpty(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
{
}
#define VBOXWDDM_OVERLAY_FROM_ENTRY(_pEntry) ((PVBOXWDDM_OVERLAY)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXWDDM_OVERLAY, ListEntry)))
void vboxVhwaHlpOverlayDstRectUnion(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT *pRect)
{
{
return;
}
{
{
}
}
}
void vboxVhwaHlpOverlayDstRectGet(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay, RECT *pRect)
{
}