int vboxVhwaHlpTranslateFormat(VBOXVHWA_PIXELFORMAT *pFormat, D3DDDIFORMAT enmFormat) { pFormat->Reserved = 0; switch (enmFormat) { case D3DDDIFMT_A8R8G8B8: case D3DDDIFMT_X8R8G8B8: pFormat->flags = VBOXVHWA_PF_RGB; pFormat->c.rgbBitCount = 32; pFormat->m1.rgbRBitMask = 0xff0000; pFormat->m2.rgbGBitMask = 0xff00; pFormat->m3.rgbBBitMask = 0xff; /* always zero for now */ pFormat->m4.rgbABitMask = 0; return VINF_SUCCESS; case D3DDDIFMT_R8G8B8: pFormat->flags = VBOXVHWA_PF_RGB; pFormat->c.rgbBitCount = 24; pFormat->m1.rgbRBitMask = 0xff0000; pFormat->m2.rgbGBitMask = 0xff00; pFormat->m3.rgbBBitMask = 0xff; /* always zero for now */ pFormat->m4.rgbABitMask = 0; return VINF_SUCCESS; case D3DDDIFMT_R5G6B5: pFormat->flags = VBOXVHWA_PF_RGB; pFormat->c.rgbBitCount = 16; pFormat->m1.rgbRBitMask = 0xf800; pFormat->m2.rgbGBitMask = 0x7e0; pFormat->m3.rgbBBitMask = 0x1f; /* always zero for now */ pFormat->m4.rgbABitMask = 0; 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: { uint32_t fourcc = vboxWddmFormatToFourcc(enmFormat); Assert(fourcc); if (fourcc) { pFormat->flags = VBOXVHWA_PF_FOURCC; pFormat->fourCC = fourcc; return VINF_SUCCESS; } return VERR_NOT_SUPPORTED; } } }
HRESULT VBoxDispD3DGlobal2DFormatsInit(PVBOXWDDMDISP_ADAPTER pAdapter) { HRESULT hr = S_OK; memset(&pAdapter->D3D, 0, sizeof (pAdapter->D3D)); memset(&pAdapter->Formats, 0, sizeof (pAdapter->Formats)); /* just calc the max number of formats */ uint32_t cFormats = RT_ELEMENTS(gVBoxFormatOpsBase); uint32_t cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase); uint32_t cOverlayFormats = 0; for (uint32_t i = 0; i < pAdapter->cHeads; ++i) { VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa; if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED) { cOverlayFormats += pVhwa->Settings.cFormats; } } cFormats += cOverlayFormats; cSurfDescs += cOverlayFormats; uint32_t cbFormatOps = cFormats * sizeof (FORMATOP); cbFormatOps = (cbFormatOps + 7) & ~3; /* ensure the surf descs are 8 byte aligned */ uint32_t offSurfDescs = (cbFormatOps + 7) & ~3; uint32_t cbSurfDescs = cSurfDescs * sizeof (DDSURFACEDESC); uint32_t cbBuf = offSurfDescs + cbSurfDescs; uint8_t* pvBuf = (uint8_t*)RTMemAllocZ(cbBuf); if (pvBuf) { pAdapter->Formats.paFormstOps = (FORMATOP*)pvBuf; memcpy ((void*)pAdapter->Formats.paFormstOps , gVBoxFormatOpsBase, sizeof (gVBoxFormatOpsBase)); pAdapter->Formats.cFormstOps = RT_ELEMENTS(gVBoxFormatOpsBase); FORMATOP fo = {D3DDDIFMT_UNKNOWN, 0, 0, 0, 0}; for (uint32_t i = 0; i < pAdapter->cHeads; ++i) { VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa; if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED) { for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j) { fo.Format = pVhwa->Settings.aFormats[j]; fo.Operations = FORMATOP_OVERLAY; hr = vboxFormatOpsMerge((FORMATOP *)pAdapter->Formats.paFormstOps, &pAdapter->Formats.cFormstOps, cFormats, &fo); if (FAILED(hr)) { WARN(("vboxFormatOpsMerge failed, hr 0x%x", hr)); } } } } pAdapter->Formats.paSurfDescs = (DDSURFACEDESC*)(pvBuf + offSurfDescs); memcpy ((void*)pAdapter->Formats.paSurfDescs , gVBoxSurfDescsBase, sizeof (gVBoxSurfDescsBase)); pAdapter->Formats.cSurfDescs = RT_ELEMENTS(gVBoxSurfDescsBase); DDSURFACEDESC sd; for (uint32_t i = 0; i < pAdapter->cHeads; ++i) { VBOXDISPVHWA_INFO *pVhwa = &pAdapter->aHeads[i].Vhwa; if (pVhwa->Settings.fFlags & VBOXVHWA_F_ENABLED) { for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j) { uint32_t fourcc = vboxWddmFormatToFourcc(pVhwa->Settings.aFormats[j]); if (fourcc) { vboxVhwaPopulateOverlayFourccSurfDesc(&sd, fourcc); hr = vboxSurfDescMerge((DDSURFACEDESC *)pAdapter->Formats.paSurfDescs, &pAdapter->Formats.cSurfDescs, cSurfDescs, &sd); if (FAILED(hr)) { WARN(("vboxFormatOpsMerge failed, hr 0x%x", hr)); } } } } } } else { WARN(("RTMemAllocZ failed")); return E_FAIL; } return S_OK; }