VirtualBox

Changeset 57152 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Aug 2, 2015 8:31:46 PM (9 years ago)
Author:
vboxsync
Message:

vmsvga3d: Removed non-VMSVGA3D_OGL_WITH_SHARED_CTX OpenGL code.

Location:
trunk/src/VBox/Devices/Graphics
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp

    r57151 r57152  
    9999};
    100100VMSVGAINFOENUMMAP_MAKE(RT_NOTHING, g_SVGA3dSurfaceFormat2String, g_aSVGA3dSurfaceFormats, "SVGA3D_");
    101 
    102 
    103 /**
    104  * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.
    105  *
    106  * This will allocate heap buffers if necessary, thus increasing the memory
    107  * usage of the process.
    108  *
    109  * @todo Would be interesting to share this code with the saved state code.
    110  *
    111  * @returns VBox status code.
    112  * @param   pState              The 3D state structure.
    113  * @param   pSurface            The surface to refresh the heap buffers for.
    114  */
    115 static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
    116 {
    117     /*
    118      * Currently we've got trouble retreving bit for DEPTHSTENCIL
    119      * surfaces both for OpenGL and D3D, so skip these here (don't
    120      * wast memory on them).
    121      */
    122     uint32_t const fSwitchFlags = pSurface->flags
    123                                 & (  SVGA3D_SURFACE_HINT_INDEXBUFFER  | SVGA3D_SURFACE_HINT_VERTEXBUFFER
    124                                    | SVGA3D_SURFACE_HINT_TEXTURE      | SVGA3D_SURFACE_HINT_RENDERTARGET
    125                                    | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);
    126     if (   fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL
    127         && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))
    128     {
    129 
    130 #ifdef VMSVGA3D_OPENGL
    131         /*
    132          * Change OpenGL context to the one the surface is associated with.
    133          */
    134 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    135         PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    136         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    137 # else
    138         /** @todo stricter checks for associated context */
    139         uint32_t cid = pSurface->idAssociatedContext;
    140         if (    cid >= pState->cContexts
    141             ||  pState->papContexts[cid]->id != cid)
    142         {
    143             Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    144             AssertFailedReturn(VERR_INVALID_PARAMETER);
    145         }
    146         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    147         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    148 # endif
    149 #endif
    150 
    151         /*
    152          * Work thru each mipmap level for each face.
    153          */
    154         for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    155         {
    156             Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
    157             PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
    158             for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
    159             {
    160 #ifdef VMSVGA3D_DIRECT3D
    161                 if (pSurface->u.pSurface)
    162 #else
    163                 if (pSurface->oglId.texture != OPENGL_INVALID_ID)
    164 #endif
    165                 {
    166                     Assert(pMipmapLevel->cbSurface);
    167                     Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */
    168 
    169                     /*
    170                      * Make sure we've got surface memory buffer.
    171                      */
    172                     uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;
    173                     if (!pbDst)
    174                     {
    175                         pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);
    176                         AssertReturn(pbDst, VERR_NO_MEMORY);
    177                     }
    178 
    179 #ifdef VMSVGA3D_DIRECT3D
    180                     /*
    181                      * D3D specifics.
    182                      */
    183                     HRESULT  hr;
    184                     switch (fSwitchFlags)
    185                     {
    186                         case SVGA3D_SURFACE_HINT_TEXTURE:
    187                         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    188                         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    189                         {
    190                             /*
    191                              * Lock the buffer and make it accessible to memcpy.
    192                              */
    193                             D3DLOCKED_RECT LockedRect;
    194                             if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
    195                             {
    196                                 if (pSurface->bounce.pTexture)
    197                                 {
    198                                     if (    !pSurface->fDirty
    199                                         &&  fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)
    200                                         &&  i == 0 /* only the first time */)
    201                                     {
    202                                         /** @todo stricter checks for associated context */
    203                                         uint32_t cid = pSurface->idAssociatedContext;
    204                                         if (   cid >= pState->cContexts
    205                                             || pState->papContexts[cid]->id != cid)
    206                                         {
    207                                             Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    208                                             AssertFailedReturn(VERR_INVALID_PARAMETER);
    209                                         }
    210                                         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    211 
    212                                         IDirect3DSurface9 *pDst = NULL;
    213                                         hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);
    214                                         AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    215 
    216                                         IDirect3DSurface9 *pSrc = NULL;
    217                                         hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
    218                                         AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    219 
    220                                         hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);
    221                                         AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    222 
    223                                         pSrc->Release();
    224                                         pDst->Release();
    225                                     }
    226 
    227                                     hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
    228                                                                              &LockedRect,
    229                                                                              NULL,
    230                                                                              D3DLOCK_READONLY);
    231                                 }
    232                                 else
    233                                     hr = pSurface->u.pTexture->LockRect(i, /* texture level */
    234                                                                         &LockedRect,
    235                                                                         NULL,
    236                                                                         D3DLOCK_READONLY);
    237                             }
    238                             else
    239                                 hr = pSurface->u.pSurface->LockRect(&LockedRect,
    240                                                                     NULL,
    241                                                                     D3DLOCK_READONLY);
    242                             AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    243 
    244                             /*
    245                              * Copy the data.  Take care in case the pitch differs.
    246                              */
    247                             if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)
    248                                 memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);
    249                             else
    250                                 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
    251                                     memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,
    252                                            (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,
    253                                            pMipmapLevel->cbSurfacePitch);
    254 
    255                             /*
    256                              * Release the buffer.
    257                              */
    258                             if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
    259                             {
    260                                 if (pSurface->bounce.pTexture)
    261                                 {
    262                                     hr = pSurface->bounce.pTexture->UnlockRect(i);
    263                                     AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    264                                 }
    265                                 else
    266                                     hr = pSurface->u.pTexture->UnlockRect(i);
    267                             }
    268                             else
    269                                 hr = pSurface->u.pSurface->UnlockRect();
    270                             AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    271                             break;
    272                         }
    273 
    274                         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    275                         {
    276                             void *pvD3DData = NULL;
    277                             hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
    278                             AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);
    279 
    280                             memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
    281 
    282                             hr = pSurface->u.pVertexBuffer->Unlock();
    283                             AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));
    284                             break;
    285                         }
    286 
    287                         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    288                         {
    289                             void *pvD3DData = NULL;
    290                             hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
    291                             AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);
    292 
    293                             memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
    294 
    295                             hr = pSurface->u.pIndexBuffer->Unlock();
    296                             AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));
    297                             break;
    298                         }
    299 
    300                         default:
    301                             AssertMsgFailed(("%#x\n", fSwitchFlags));
    302                     }
    303 
    304 #elif defined(VMSVGA3D_OPENGL)
    305                     /*
    306                      * OpenGL specifics.
    307                      */
    308                     switch (fSwitchFlags)
    309                     {
    310                         case SVGA3D_SURFACE_HINT_TEXTURE:
    311                         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    312                         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    313                         {
    314                             GLint activeTexture;
    315                             glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    316                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    317 
    318                             glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    319                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    320 
    321                             /* Set row length and alignment of the output data. */
    322                             VMSVGAPACKPARAMS SavedParams;
    323                             vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);
    324 
    325                             glGetTexImage(GL_TEXTURE_2D,
    326                                           i,
    327                                           pSurface->formatGL,
    328                                           pSurface->typeGL,
    329                                           pbDst);
    330                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    331 
    332                             vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);
    333 
    334                             /* Restore the old active texture. */
    335                             glBindTexture(GL_TEXTURE_2D, activeTexture);
    336                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    337                             break;
    338                         }
    339 
    340                         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    341                         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    342                         {
    343                             pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
    344                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    345 
    346                             void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
    347                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    348                             if (RT_VALID_PTR(pvSrc))
    349                                 memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);
    350                             else
    351                                 AssertPtr(pvSrc);
    352 
    353                             pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
    354                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    355 
    356                             pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
    357                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    358                             break;
    359                         }
    360 
    361                         default:
    362                             AssertMsgFailed(("%#x\n", fSwitchFlags));
    363                     }
    364 #else
    365 # error "misconfigured"
    366 #endif
    367                 }
    368                 /* else: There is no data in hardware yet, so whatever we got is already current. */
    369             }
    370         }
    371     }
    372 
    373     return VINF_SUCCESS;
    374 }
    375 
    376 
    377 /**
    378  * Updates the heap buffers for all surfaces or one specific one.
    379  *
    380  * @param   pThis               The VGA device instance data.
    381  * @param   sid                 The surface ID, UINT32_MAX if all.
    382  * @thread  VMSVGAFIFO
    383  */
    384 void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)
    385 {
    386     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    387     AssertReturnVoid(pState);
    388 
    389     if (sid == UINT32_MAX)
    390     {
    391         uint32_t cSurfaces = pState->cSurfaces;
    392         for (sid = 0; sid < cSurfaces; sid++)
    393         {
    394             PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    395             if (pSurface && pSurface->id == sid)
    396                 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
    397         }
    398     }
    399     else if (sid < pState->cSurfaces)
    400     {
    401         PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    402         if (pSurface && pSurface->id == sid)
    403             vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
    404     }
    405 }
    406 
    407 
    408 
    409 
    410 void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)
    411 {
    412     for (uint32_t i = 0; i < cFlags; i++)
    413         if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)
    414         {
    415             Assert(paFlags[i].fFlags);
    416             pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);
    417             fFlags &= ~paFlags[i].fFlags;
    418             if (!fFlags)
    419                 return;
    420         }
    421     if (fFlags)
    422         pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);
    423 }
    424 
    425 
    426 /**
    427  * Worker for vmsvgaR3Info that display details of a host window.
    428  *
    429  * @param   pHlp            The output methods.
    430  * @param   idHostWindow    The host window handle/id/whatever.
    431  */
    432 void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)
    433 {
    434 #ifdef RT_OS_WINDOWS
    435     HWND hwnd = (HWND)(uintptr_t)idHostWindow;
    436     Assert((uintptr_t)hwnd == idHostWindow);
    437     if (hwnd != NULL)
    438     {
    439         WINDOWINFO Info;
    440         RT_ZERO(Info);
    441         Info.cbSize = sizeof(Info);
    442         if (GetWindowInfo(hwnd, &Info))
    443         {
    444             pHlp->pfnPrintf(pHlp, "     Window rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
    445                             Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,
    446                             Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);
    447             pHlp->pfnPrintf(pHlp, "     Client rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
    448                             Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,
    449                             Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);
    450             pHlp->pfnPrintf(pHlp, "     Style:         %#x", Info.dwStyle);
    451             static const VMSVGAINFOFLAGS32 g_aStyles[] =
    452             {
    453                 { WS_POPUP        , "POPUP" },
    454                 { WS_CHILD        , "CHILD" },
    455                 { WS_MINIMIZE     , "MINIMIZE" },
    456                 { WS_VISIBLE      , "VISIBLE" },
    457                 { WS_DISABLED     , "DISABLED" },
    458                 { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },
    459                 { WS_CLIPCHILDREN , "CLIPCHILDREN" },
    460                 { WS_MAXIMIZE     , "MAXIMIZE" },
    461                 { WS_BORDER       , "BORDER" },
    462                 { WS_DLGFRAME     , "DLGFRAME" },
    463                 { WS_VSCROLL      , "VSCROLL" },
    464                 { WS_HSCROLL      , "HSCROLL" },
    465                 { WS_SYSMENU      , "SYSMENU" },
    466                 { WS_THICKFRAME   , "THICKFRAME" },
    467                 { WS_GROUP        , "GROUP" },
    468                 { WS_TABSTOP      , "TABSTOP" },
    469             };
    470             vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));
    471             pHlp->pfnPrintf(pHlp, "\n");
    472 
    473             pHlp->pfnPrintf(pHlp, "     ExStyle:       %#x", Info.dwExStyle);
    474             static const VMSVGAINFOFLAGS32 g_aExStyles[] =
    475             {
    476                 { WS_EX_DLGMODALFRAME,   "DLGMODALFRAME" },
    477                 { 0x00000002,            "DRAGDETECT" },
    478                 { WS_EX_NOPARENTNOTIFY,  "NOPARENTNOTIFY" },
    479                 { WS_EX_TOPMOST,         "TOPMOST" },
    480                 { WS_EX_ACCEPTFILES,     "ACCEPTFILES" },
    481                 { WS_EX_TRANSPARENT,     "TRANSPARENT" },
    482                 { WS_EX_MDICHILD,        "MDICHILD" },
    483                 { WS_EX_TOOLWINDOW,      "TOOLWINDOW" },
    484                 { WS_EX_WINDOWEDGE,      "WINDOWEDGE" },
    485                 { WS_EX_CLIENTEDGE,      "CLIENTEDGE" },
    486                 { WS_EX_CONTEXTHELP,     "CONTEXTHELP" },
    487                 { WS_EX_RIGHT,           "RIGHT" },
    488                 /*{ WS_EX_LEFT,            "LEFT" }, = 0 */
    489                 { WS_EX_RTLREADING,      "RTLREADING" },
    490                 /*{ WS_EX_LTRREADING,      "LTRREADING" }, = 0 */
    491                 { WS_EX_LEFTSCROLLBAR,   "LEFTSCROLLBAR" },
    492                 /*{ WS_EX_RIGHTSCROLLBAR,  "RIGHTSCROLLBAR" }, = 0 */
    493                 { WS_EX_CONTROLPARENT,   "CONTROLPARENT" },
    494                 { WS_EX_STATICEDGE,      "STATICEDGE" },
    495                 { WS_EX_APPWINDOW,       "APPWINDOW" },
    496                 { WS_EX_LAYERED,         "LAYERED" },
    497                 { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },
    498                 { WS_EX_LAYOUTRTL,       "LAYOUTRTL" },
    499                 { WS_EX_COMPOSITED,      "COMPOSITED" },
    500                 { WS_EX_NOACTIVATE,      "NOACTIVATE" },
    501             };
    502             vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));
    503             pHlp->pfnPrintf(pHlp, "\n");
    504 
    505             pHlp->pfnPrintf(pHlp, "     Window Status: %#x\n", Info.dwWindowStatus);
    506             if (Info.cxWindowBorders || Info.cyWindowBorders)
    507                 pHlp->pfnPrintf(pHlp, "     Borders:       cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);
    508             pHlp->pfnPrintf(pHlp, "     Window Type:   %#x\n", Info.atomWindowType);
    509             pHlp->pfnPrintf(pHlp, "     Creator Ver:   %#x\n", Info.wCreatorVersion);
    510         }
    511         else
    512             pHlp->pfnPrintf(pHlp, "     GetWindowInfo: last error %d\n", GetLastError());
    513     }
    514 #else
    515     pHlp->pfnPrintf(pHlp, "    Windows info:   Not implemented on this platform\n");
    516 #endif
    517 
    518 }
    519 
    520 
    521 /**
    522  * Looks up an enum value in a translation table.
    523  *
    524  * @returns The value name.
    525  * @param   iValue              The value to name.
    526  * @param   pEnumMap            Enum value to string mapping.
    527  */
    528 const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)
    529 {
    530     PCVMSVGAINFOENUM paValues = pEnumMap->paValues;
    531 
    532 #ifdef VBOX_STRICT
    533     /*
    534      * Check that it's really sorted, or the binary lookup won't work right.
    535      */
    536     if (!*pEnumMap->pfAsserted)
    537     {
    538         *pEnumMap->pfAsserted = true;
    539         for (uint32_t i = 1; i < pEnumMap->cValues; i++)
    540             Assert(paValues[i - 1].iValue <= paValues[i].iValue);
    541     }
    542 #endif
    543 
    544     /*
    545      * Binary search
    546      */
    547     uint32_t iStart = 0;
    548     uint32_t iEnd   = (uint32_t)pEnumMap->cValues;
    549     for (;;)
    550     {
    551         uint32_t i = iStart + (iEnd - iStart) / 2;
    552         if (iValue < paValues[i].iValue)
    553         {
    554             if (i > iStart)
    555                 iEnd = i;
    556             else
    557                 break;
    558         }
    559         else if (iValue > paValues[i].iValue)
    560         {
    561             i++;
    562             if (i < iEnd)
    563                 iStart = i;
    564             else
    565                 break;
    566         }
    567         else
    568             return paValues[i].pszName;
    569     }
    570     return NULL;
    571 }
    572 
    573 
    574 /**
    575  * Formats an enum value as a string, sparse mapping table.
    576  *
    577  * @returns pszBuffer.
    578  * @param   pszBuffer           The output buffer.
    579  * @param   cbBuffer            The size of the output buffer.
    580  * @param   pszName             The variable name, optional.
    581  * @param   iValue              The enum value.
    582  * @param   fPrefix             Whether to prepend the prefix or not.
    583  * @param   pEnumMap            Enum value to string mapping.
    584  */
    585 char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
    586                               bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)
    587 {
    588     const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);
    589     const char *pszPrefix    = fPrefix ? pEnumMap->pszPrefix : "";
    590     if (pszValueName)
    591     {
    592         if (pszName)
    593             RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);
    594         else
    595             RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);
    596         return pszBuffer;
    597     }
    598 
    599     if (pszName)
    600         RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
    601     else
    602         RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
    603     return pszBuffer;
    604 }
    605 
    606 
    607 /**
    608  * Formats an enum value as a string.
    609  *
    610  * @returns pszBuffer.
    611  * @param   pszBuffer           The output buffer.
    612  * @param   cbBuffer            The size of the output buffer.
    613  * @param   pszName             The variable name, optional.
    614  * @param   uValue              The enum value.
    615  * @param   pszPrefix           The prefix of the enum values.  Empty string if
    616  *                              none.  This helps reduce the memory footprint
    617  *                              as well as the source code size.
    618  * @param   papszValues         One to one string mapping of the enum values.
    619  * @param   cValues             The number of values in the mapping.
    620  */
    621 char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
    622                             const char *pszPrefix, const char * const *papszValues, size_t cValues)
    623 {
    624     if (uValue < cValues)
    625     {
    626         if (pszName)
    627             RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
    628         else
    629             RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
    630     }
    631     else
    632     {
    633         if (pszName)
    634             RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
    635         else
    636             RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
    637     }
    638     return pszBuffer;
    639 }
    640 
    641 
    642 /**
    643  * DBGF info printer for vmsvga3dAsciiPrint.
    644  *
    645  * @param   pszLine             The line to print.
    646  * @param   pvUser              The debug info helpers.
    647  */
    648 DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
    649 {
    650     PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
    651     pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
    652 }
    653 
    654 
    655 /**
    656  * Log printer for vmsvga3dAsciiPrint.
    657  *
    658  * @param   pszLine             The line to print.
    659  * @param   pvUser              Ignored.
    660  */
    661 DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
    662 {
    663     size_t cch = strlen(pszLine);
    664     while (cch > 0 && pszLine[cch - 1] == ' ')
    665         cch--;
    666     RTLogPrintf("%.*s\n", cch, pszLine);
    667     NOREF(pvUser);
    668 }
    669 
    670 
    671 void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
    672                         uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
    673                         uint32_t cchMaxX, uint32_t cchMaxY)
    674 {
    675     /*
    676      * Skip stuff we can't or won't need to handle.
    677      */
    678     if (!cx || !cy)
    679         return;
    680     switch (enmFormat)
    681     {
    682         /* Compressed. */
    683         case SVGA3D_DXT1:
    684         case SVGA3D_DXT2:
    685         case SVGA3D_DXT3:
    686         case SVGA3D_DXT4:
    687         case SVGA3D_DXT5:
    688             return;
    689         /* Generic. */
    690         case SVGA3D_BUFFER:
    691             return;
    692         default:
    693             break; /* ok */
    694     }
    695 
    696     /*
    697      * Figure the pixel conversion factors.
    698      */
    699     uint32_t cxPerChar = cx / cchMaxX + 1;
    700     uint32_t cyPerChar = cy / cchMaxY + 1;
    701     /** @todo try keep aspect...   */
    702     uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
    703     uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
    704 
    705     /*
    706      * The very simple conversion we're doing in this function is based on
    707      * mapping a block of converted pixels to an ASCII character of similar
    708      * weigth.  We do that by summing up all the 8-bit gray scale pixels in
    709      * that block, applying a conversion factor and getting an index into an
    710      * array of increasingly weighty characters.
    711      */
    712     static const char       s_szPalette[] = "   ..`',:;icodxkO08XNWM";
    713     static const uint32_t   s_cchPalette  = sizeof(s_szPalette) - 1;
    714     uint32_t const          cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
    715 
    716     /*
    717      * Do the work
    718      */
    719     uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
    720     if (!pauScanline)
    721         return;
    722     char *pszLine = (char *)&pauScanline[cchLine];
    723     RTCPTRUNION uSrc;
    724     uSrc.pv              = pvImage;
    725     if (fInvY)
    726         uSrc.pu8 += (cy - 1) * cbScanline;
    727     uint32_t cyLeft = cy;
    728     uint32_t cyLeftInScanline = cyPerChar;
    729     bool     fHitFormatAssert = false;
    730     for (;;)
    731     {
    732         /*
    733          * Process the scanline.  This is tedious because of all the
    734          * different formats.  We generally ignore alpha, unless it's
    735          * all we've got to work with.
    736          * Color to 8-bit grayscale conversion is done by averaging.
    737          */
    738 #define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \
    739             do { \
    740                 for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
    741                 { \
    742                     a_RdExpr; \
    743                     pauScanline[xDst] += (a_AddExpr) & 0xff; \
    744                     Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
    745                     if (--cxLeftInChar == 0) \
    746                     { \
    747                         xDst++; \
    748                         cxLeftInChar = cxPerChar; \
    749                     } \
    750                 } \
    751             } while (0)
    752 
    753         switch (enmFormat)
    754         {
    755             /* Unsigned RGB and super/subsets. */
    756             case SVGA3D_X8R8G8B8:
    757             case SVGA3D_A8R8G8B8:
    758                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    759                                  (  ( u32Tmp        & 0xff) /* B */
    760                                   + ((u32Tmp >>  8) & 0xff) /* G */
    761                                   + ((u32Tmp >> 16) & 0xff) /* R */) / 3);
    762                 break;
    763             case SVGA3D_R5G6B5:
    764                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    765                                  ( ( u16Tmp         & 0x1f) * 8
    766                                  + ((u16Tmp >>  5)  & 0x3f) * 4
    767                                  + ( u16Tmp >> 11)          * 8 ) / 3 );
    768                 break;
    769             case SVGA3D_X1R5G5B5:
    770             case SVGA3D_A1R5G5B5:
    771                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    772                                  (  ( u16Tmp        & 0x1f) * 8
    773                                   + ((u16Tmp >> 5)  & 0x1f) * 8
    774                                   + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );
    775                 break;
    776             case SVGA3D_A4R4G4B4:
    777                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    778                                  (  ( u16Tmp        & 0xf) * 16
    779                                   + ((u16Tmp >> 4)  & 0xf) * 16
    780                                   + ((u16Tmp >> 8)  & 0xf) * 16) / 3 );
    781                 break;
    782             case SVGA3D_A16B16G16R16:
    783                 CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],
    784                                  (  ((u64Tmp >>  8) & 0xff) /* R */
    785                                   + ((u64Tmp >> 24) & 0xff) /* G */
    786                                   + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);
    787                 break;
    788             case SVGA3D_A2R10G10B10:
    789                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    790                                  (  ( u32Tmp        & 0x3ff) /* B */
    791                                   + ((u32Tmp >> 10) & 0x3ff) /* G */
    792                                   + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));
    793                 break;
    794             case SVGA3D_G16R16:
    795                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    796                                  (  (u32Tmp & 0xffff) /* R */
    797                                   + (u32Tmp >>   16 ) /* G */) / 0x200);
    798                 break;
    799 
    800             /* Depth. */
    801             case SVGA3D_Z_D32:
    802                 CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),
    803                                    (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))
    804                                  | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
    805                                  | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
    806                                  | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
    807                                  | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
    808                                  | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
    809                                  | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
    810                                  | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
    811                 break;
    812             case SVGA3D_Z_D16:
    813                 CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],
    814                                    ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))
    815                                  | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))
    816                                  | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))
    817                                  | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))
    818                                  | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))
    819                                  | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))
    820                                  | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))
    821                                  | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );
    822                 break;
    823             case SVGA3D_Z_D24S8:
    824                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    825                                    (  u32Tmp        & 0xff) /* stencile */
    826                                  | ((~u32Tmp >> 18) & 0x3f));
    827                 break;
    828             case SVGA3D_Z_D15S1:
    829                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    830                                    ( (u16Tmp & 0x01) << 7) /* stencile */
    831                                  | ((~u16Tmp >> 8) & 0x7f));
    832                 break;
    833 
    834             /* Pure alpha. */
    835             case SVGA3D_ALPHA8:
    836                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
    837                 break;
    838 
    839             /* Luminance */
    840             case SVGA3D_LUMINANCE8:
    841                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
    842                 break;
    843             case SVGA3D_LUMINANCE4_ALPHA4:
    844                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);
    845                 break;
    846             case SVGA3D_LUMINANCE16:
    847                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
    848                 break;
    849             case SVGA3D_LUMINANCE8_ALPHA8:
    850                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
    851                 break;
    852 
    853             /* Not supported. */
    854             case SVGA3D_DXT1:
    855             case SVGA3D_DXT2:
    856             case SVGA3D_DXT3:
    857             case SVGA3D_DXT4:
    858             case SVGA3D_DXT5:
    859             case SVGA3D_BUFFER:
    860                 AssertFailedBreak();
    861 
    862             /* Not considered for implementation yet. */
    863             case SVGA3D_BUMPU8V8:
    864             case SVGA3D_BUMPL6V5U5:
    865             case SVGA3D_BUMPX8L8V8U8:
    866             case SVGA3D_BUMPL8V8U8:
    867             case SVGA3D_ARGB_S10E5:
    868             case SVGA3D_ARGB_S23E8:
    869             case SVGA3D_V8U8:
    870             case SVGA3D_Q8W8V8U8:
    871             case SVGA3D_CxV8U8:
    872             case SVGA3D_X8L8V8U8:
    873             case SVGA3D_A2W10V10U10:
    874             case SVGA3D_R_S10E5:
    875             case SVGA3D_R_S23E8:
    876             case SVGA3D_RG_S10E5:
    877             case SVGA3D_RG_S23E8:
    878             case SVGA3D_Z_D24X8:
    879             case SVGA3D_V16U16:
    880             case SVGA3D_UYVY:
    881             case SVGA3D_YUY2:
    882             case SVGA3D_NV12:
    883             case SVGA3D_AYUV:
    884             case SVGA3D_BC4_UNORM:
    885             case SVGA3D_BC5_UNORM:
    886             case SVGA3D_Z_DF16:
    887             case SVGA3D_Z_DF24:
    888             case SVGA3D_Z_D24S8_INT:
    889                 if (!fHitFormatAssert)
    890                 {
    891                     AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));
    892                     fHitFormatAssert = true;
    893                 }
    894                 /* fall thru */
    895             default:
    896                 /* Lazy programmer fallbacks. */
    897                 if (cbSrcPixel == 4)
    898                     CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    899                                      (  ( u32Tmp        & 0xff)
    900                                       + ((u32Tmp >>  8) & 0xff)
    901                                       + ((u32Tmp >> 16) & 0xff)
    902                                       + ((u32Tmp >> 24) & 0xff) ) / 4);
    903                 else if (cbSrcPixel == 3)
    904                     CONVERT_SCANLINE(RT_NOTHING,
    905                                      (  (uint32_t)uSrc.pu8[xSrc * 4]
    906                                       + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
    907                                       + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
    908                 else if (cbSrcPixel == 2)
    909                     CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    910                                      (  ( u16Tmp        & 0xf)
    911                                       + ((u16Tmp >>  4) & 0xf)
    912                                       + ((u16Tmp >>  8) & 0xf)
    913                                       + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );
    914                 else if (cbSrcPixel == 1)
    915                     CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
    916                 else
    917                     AssertFailed();
    918                 break;
    919 
    920         }
    921 
    922         /*
    923          * Print we've reached the end of a block in y direction or if we're at
    924          * the end of the image.
    925          */
    926         cyLeft--;
    927         if (--cyLeftInScanline == 0 || cyLeft == 0)
    928         {
    929             for (uint32_t i = 0; i < cchLine; i++)
    930             {
    931                 uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
    932                 pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
    933             }
    934             pszLine[cchLine] = '\0';
    935             pfnPrintLine(pszLine, pvUser);
    936 
    937             if (!cyLeft)
    938                 break;
    939             cyLeftInScanline = cyPerChar;
    940             RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
    941         }
    942 
    943         /*
    944          * Advance.
    945          */
    946         if (!fInvY)
    947             uSrc.pu8 += cbScanline;
    948         else
    949             uSrc.pu8 -= cbScanline;
    950     }
    951 }
    952 
    953 
    954 /**
    955  * List of render state names with type prefix.
    956  *
    957  * First char in the name is a type indicator:
    958  *      - '*' = requires special handling.
    959  *      - 'f' = SVGA3dbool
    960  *      - 'd' = uint32_t
    961  *      - 'r' = float
    962  *      - 'b' = SVGA3dBlendOp
    963  *      - 'c' = SVGA3dColor, SVGA3dColorMask
    964  *      - 'e' = SVGA3dBlendEquation
    965  *      - 'm' = SVGA3dColorMask
    966  *      - 'p' = SVGA3dCmpFunc
    967  *      - 's' = SVGA3dStencilOp
    968  *      - 'v' = SVGA3dVertexMaterial
    969  *      - 'w' = SVGA3dWrapFlags
    970  */
    971 static const char * const g_apszRenderStateNamesAndType[] =
    972 {
    973    "*" "INVALID",                       /*  invalid  */
    974    "f" "ZENABLE",                       /*  SVGA3dBool  */
    975    "f" "ZWRITEENABLE",                  /*  SVGA3dBool  */
    976    "f" "ALPHATESTENABLE",               /*  SVGA3dBool  */
    977    "f" "DITHERENABLE",                  /*  SVGA3dBool  */
    978    "f" "BLENDENABLE",                   /*  SVGA3dBool  */
    979    "f" "FOGENABLE",                     /*  SVGA3dBool  */
    980    "f" "SPECULARENABLE",                /*  SVGA3dBool  */
    981    "f" "STENCILENABLE",                 /*  SVGA3dBool  */
    982    "f" "LIGHTINGENABLE",                /*  SVGA3dBool  */
    983    "f" "NORMALIZENORMALS",              /*  SVGA3dBool  */
    984    "f" "POINTSPRITEENABLE",             /*  SVGA3dBool  */
    985    "f" "POINTSCALEENABLE",              /*  SVGA3dBool  */
    986    "x" "STENCILREF",                    /*  uint32_t  */
    987    "x" "STENCILMASK",                   /*  uint32_t  */
    988    "x" "STENCILWRITEMASK",              /*  uint32_t  */
    989    "r" "FOGSTART",                      /*  float  */
    990    "r" "FOGEND",                        /*  float  */
    991    "r" "FOGDENSITY",                    /*  float  */
    992    "r" "POINTSIZE",                     /*  float  */
    993    "r" "POINTSIZEMIN",                  /*  float  */
    994    "r" "POINTSIZEMAX",                  /*  float  */
    995    "r" "POINTSCALE_A",                  /*  float  */
    996    "r" "POINTSCALE_B",                  /*  float  */
    997    "r" "POINTSCALE_C",                  /*  float  */
    998    "c" "FOGCOLOR",                      /*  SVGA3dColor  */
    999    "c" "AMBIENT",                       /*  SVGA3dColor  */
    1000    "*" "CLIPPLANEENABLE",               /*  SVGA3dClipPlanes  */
    1001    "*" "FOGMODE",                       /*  SVGA3dFogMode  */
    1002    "*" "FILLMODE",                      /*  SVGA3dFillMode  */
    1003    "*" "SHADEMODE",                     /*  SVGA3dShadeMode  */
    1004    "*" "LINEPATTERN",                   /*  SVGA3dLinePattern  */
    1005    "b" "SRCBLEND",                      /*  SVGA3dBlendOp  */
    1006    "b" "DSTBLEND",                      /*  SVGA3dBlendOp  */
    1007    "e" "BLENDEQUATION",                 /*  SVGA3dBlendEquation  */
    1008    "*" "CULLMODE",                      /*  SVGA3dFace  */
    1009    "p" "ZFUNC",                         /*  SVGA3dCmpFunc  */
    1010    "p" "ALPHAFUNC",                     /*  SVGA3dCmpFunc  */
    1011    "p" "STENCILFUNC",                   /*  SVGA3dCmpFunc  */
    1012    "s" "STENCILFAIL",                   /*  SVGA3dStencilOp  */
    1013    "s" "STENCILZFAIL",                  /*  SVGA3dStencilOp  */
    1014    "s" "STENCILPASS",                   /*  SVGA3dStencilOp  */
    1015    "r" "ALPHAREF",                      /*  float  */
    1016    "*" "FRONTWINDING",                  /*  SVGA3dFrontWinding  */
    1017    "*" "COORDINATETYPE",                /*  SVGA3dCoordinateType  */
    1018    "r" "ZBIAS",                         /*  float  */
    1019    "f" "RANGEFOGENABLE",                /*  SVGA3dBool  */
    1020    "c" "COLORWRITEENABLE",              /*  SVGA3dColorMask  */
    1021    "f" "VERTEXMATERIALENABLE",          /*  SVGA3dBool  */
    1022    "v" "DIFFUSEMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
    1023    "v" "SPECULARMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
    1024    "v" "AMBIENTMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
    1025    "v" "EMISSIVEMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
    1026    "c" "TEXTUREFACTOR",                 /*  SVGA3dColor  */
    1027    "f" "LOCALVIEWER",                   /*  SVGA3dBool  */
    1028    "f" "SCISSORTESTENABLE",             /*  SVGA3dBool  */
    1029    "c" "BLENDCOLOR",                    /*  SVGA3dColor  */
    1030    "f" "STENCILENABLE2SIDED",           /*  SVGA3dBool  */
    1031    "p" "CCWSTENCILFUNC",                /*  SVGA3dCmpFunc  */
    1032    "s" "CCWSTENCILFAIL",                /*  SVGA3dStencilOp  */
    1033    "s" "CCWSTENCILZFAIL",               /*  SVGA3dStencilOp  */
    1034    "s" "CCWSTENCILPASS",                /*  SVGA3dStencilOp  */
    1035    "*" "VERTEXBLEND",                   /*  SVGA3dVertexBlendFlags  */
    1036    "r" "SLOPESCALEDEPTHBIAS",           /*  float  */
    1037    "r" "DEPTHBIAS",                     /*  float  */
    1038    "r" "OUTPUTGAMMA",                   /*  float  */
    1039    "f" "ZVISIBLE",                      /*  SVGA3dBool  */
    1040    "f" "LASTPIXEL",                     /*  SVGA3dBool  */
    1041    "f" "CLIPPING",                      /*  SVGA3dBool  */
    1042    "w" "WRAP0",                         /*  SVGA3dWrapFlags  */
    1043    "w" "WRAP1",                         /*  SVGA3dWrapFlags  */
    1044    "w" "WRAP2",                         /*  SVGA3dWrapFlags  */
    1045    "w" "WRAP3",                         /*  SVGA3dWrapFlags  */
    1046    "w" "WRAP4",                         /*  SVGA3dWrapFlags  */
    1047    "w" "WRAP5",                         /*  SVGA3dWrapFlags  */
    1048    "w" "WRAP6",                         /*  SVGA3dWrapFlags  */
    1049    "w" "WRAP7",                         /*  SVGA3dWrapFlags  */
    1050    "w" "WRAP8",                         /*  SVGA3dWrapFlags  */
    1051    "w" "WRAP9",                         /*  SVGA3dWrapFlags  */
    1052    "w" "WRAP10",                        /*  SVGA3dWrapFlags  */
    1053    "w" "WRAP11",                        /*  SVGA3dWrapFlags  */
    1054    "w" "WRAP12",                        /*  SVGA3dWrapFlags  */
    1055    "w" "WRAP13",                        /*  SVGA3dWrapFlags  */
    1056    "w" "WRAP14",                        /*  SVGA3dWrapFlags  */
    1057    "w" "WRAP15",                        /*  SVGA3dWrapFlags  */
    1058    "f" "MULTISAMPLEANTIALIAS",          /*  SVGA3dBool  */
    1059    "x" "MULTISAMPLEMASK",               /*  uint32_t  */
    1060    "f" "INDEXEDVERTEXBLENDENABLE",      /*  SVGA3dBool  */
    1061    "r" "TWEENFACTOR",                   /*  float  */
    1062    "f" "ANTIALIASEDLINEENABLE",         /*  SVGA3dBool  */
    1063    "c" "COLORWRITEENABLE1",             /*  SVGA3dColorMask  */
    1064    "c" "COLORWRITEENABLE2",             /*  SVGA3dColorMask  */
    1065    "c" "COLORWRITEENABLE3",             /*  SVGA3dColorMask  */
    1066    "f" "SEPARATEALPHABLENDENABLE",      /*  SVGA3dBool  */
    1067    "b" "SRCBLENDALPHA",                 /*  SVGA3dBlendOp  */
    1068    "b" "DSTBLENDALPHA",                 /*  SVGA3dBlendOp  */
    1069    "e" "BLENDEQUATIONALPHA",            /*  SVGA3dBlendEquation  */
    1070    "*" "TRANSPARENCYANTIALIAS",         /*  SVGA3dTransparencyAntialiasType  */
    1071    "f" "LINEAA",                        /*  SVGA3dBool  */
    1072    "r" "LINEWIDTH",                     /*  float  */
    1073 };
    1074 
    1075 
    1076 /**
    1077  * Formats a SVGA3dRenderState structure as a string.
    1078  *
    1079  * @returns pszBuffer.
    1080  * @param   pszBuffer       Output string buffer.
    1081  * @param   cbBuffer        Size of output buffer.
    1082  * @param   pRenderState    The SVGA3d render state to format.
    1083  */
    1084 char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
    1085 {
    1086     uint32_t iState = pRenderState->state;
    1087     if (iState != SVGA3D_RS_INVALID)
    1088     {
    1089         if (iState < RT_ELEMENTS(g_apszRenderStateNamesAndType))
    1090         {
    1091             const char *pszName = g_apszRenderStateNamesAndType[iState];
    1092             char const  chType  = *pszName++;
    1093 
    1094             union
    1095             {
    1096                uint32_t  u;
    1097                float     r;
    1098                SVGA3dColorMask Color;
    1099             } uValue;
    1100             uValue.u = pRenderState->uintValue;
    1101 
    1102             switch (chType)
    1103             {
    1104                 case 'f':
    1105                     if (uValue.u == 0)
    1106                         RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
    1107                     else if (uValue.u == 1)
    1108                         RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
    1109                     else
    1110                         RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
    1111                     break;
    1112                 case 'x':
    1113                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
    1114                     break;
    1115                 case 'r':
    1116                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
    1117                                 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
    1118                     break;
    1119                 case 'c': //SVGA3dColor, SVGA3dColorMask
    1120                     RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
    1121                                 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
    1122                     break;
    1123                 case 'w': //SVGA3dWrapFlags
    1124                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
    1125                                 uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
    1126                     break;
    1127                 default:
    1128                     AssertFailed();
    1129                 case 'b': //SVGA3dBlendOp
    1130                 case 'e': //SVGA3dBlendEquation
    1131                 case 'p': //SVGA3dCmpFunc
    1132                 case 's': //SVGA3dStencilOp
    1133                 case 'v': //SVGA3dVertexMaterial
    1134                 case '*':
    1135                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
    1136                     break;
    1137             }
    1138         }
    1139         else
    1140             RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
    1141     }
    1142     else
    1143         RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
    1144     return pszBuffer;
    1145 }
    1146 
    1147 /**
    1148  * Texture state names with type prefix.
    1149  */
    1150 static const char * const g_apszTextureStateNamesAndType[] =
    1151 {
    1152     "*" "INVALID",                      /*  invalid  */
    1153     "x" "BIND_TEXTURE",                 /*  SVGA3dSurfaceId  */
    1154     "m" "COLOROP",                      /*  SVGA3dTextureCombiner  */
    1155     "a" "COLORARG1",                    /*  SVGA3dTextureArgData  */
    1156     "a" "COLORARG2",                    /*  SVGA3dTextureArgData  */
    1157     "m" "ALPHAOP",                      /*  SVGA3dTextureCombiner  */
    1158     "a" "ALPHAARG1",                    /*  SVGA3dTextureArgData  */
    1159     "a" "ALPHAARG2",                    /*  SVGA3dTextureArgData  */
    1160     "e" "ADDRESSU",                     /*  SVGA3dTextureAddress  */
    1161     "e" "ADDRESSV",                     /*  SVGA3dTextureAddress  */
    1162     "l" "MIPFILTER",                    /*  SVGA3dTextureFilter  */
    1163     "l" "MAGFILTER",                    /*  SVGA3dTextureFilter  */
    1164     "m" "MINFILTER",                    /*  SVGA3dTextureFilter  */
    1165     "c" "BORDERCOLOR",                  /*  SVGA3dColor  */
    1166     "r" "TEXCOORDINDEX",                /*  uint32_t  */
    1167     "t" "TEXTURETRANSFORMFLAGS",        /*  SVGA3dTexTransformFlags  */
    1168     "g" "TEXCOORDGEN",                  /*  SVGA3dTextureCoordGen  */
    1169     "r" "BUMPENVMAT00",                 /*  float  */
    1170     "r" "BUMPENVMAT01",                 /*  float  */
    1171     "r" "BUMPENVMAT10",                 /*  float  */
    1172     "r" "BUMPENVMAT11",                 /*  float  */
    1173     "x" "TEXTURE_MIPMAP_LEVEL",         /*  uint32_t  */
    1174     "r" "TEXTURE_LOD_BIAS",             /*  float  */
    1175     "x" "TEXTURE_ANISOTROPIC_LEVEL",    /*  uint32_t  */
    1176     "e" "ADDRESSW",                     /*  SVGA3dTextureAddress  */
    1177     "r" "GAMMA",                        /*  float  */
    1178     "r" "BUMPENVLSCALE",                /*  float  */
    1179     "r" "BUMPENVLOFFSET",               /*  float  */
    1180     "a" "COLORARG0",                    /*  SVGA3dTextureArgData  */
    1181     "a" "ALPHAARG0"                     /*  SVGA3dTextureArgData */
    1182 };
    1183 
    1184 /**
    1185  * Formats a SVGA3dTextureState structure as a string.
    1186  *
    1187  * @returns pszBuffer.
    1188  * @param   pszBuffer       Output string buffer.
    1189  * @param   cbBuffer        Size of output buffer.
    1190  * @param   pTextureState   The SVGA3d texture state to format.
    1191  */
    1192 char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
    1193 {
    1194     /*
    1195      * Format the stage first.
    1196      */
    1197     char  *pszRet    = pszBuffer;
    1198     size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
    1199     if (cchPrefix < cbBuffer)
    1200     {
    1201         cbBuffer  -= cchPrefix;
    1202         pszBuffer += cchPrefix;
    1203     }
    1204     else
    1205         cbBuffer = 0;
    1206 
    1207     /*
    1208      * Format the name and value.
    1209      */
    1210     uint32_t iName = pTextureState->name;
    1211     if (iName != SVGA3D_TS_INVALID)
    1212     {
    1213         if (iName < RT_ELEMENTS(g_apszTextureStateNamesAndType))
    1214         {
    1215             const char *pszName = g_apszTextureStateNamesAndType[iName];
    1216             char        chType  = *pszName++;
    1217 
    1218             union
    1219             {
    1220                uint32_t  u;
    1221                float     r;
    1222                SVGA3dColorMask Color;
    1223             } uValue;
    1224             uValue.u = pTextureState->value;
    1225 
    1226             switch (chType)
    1227             {
    1228                 case 'x':
    1229                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
    1230                     break;
    1231 
    1232                 case 'r':
    1233                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
    1234                                 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
    1235                     break;
    1236 
    1237                 case 'a': //SVGA3dTextureArgData
    1238                 {
    1239                     static const char * const s_apszValues[] =
    1240                     {
    1241                         "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
    1242                     };
    1243                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1244                                           "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1245                     break;
    1246                 }
    1247 
    1248                 case 'c': //SVGA3dColor, SVGA3dColorMask
    1249                     RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
    1250                                 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
    1251                     break;
    1252 
    1253                 case 'e': //SVGA3dTextureAddress
    1254                 {
    1255                     static const char * const s_apszValues[] =
    1256                     {
    1257                         "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
    1258                     };
    1259                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1260                                           "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1261                     break;
    1262                 }
    1263 
    1264                 case 'l': //SVGA3dTextureFilter
    1265                 {
    1266                     static const char * const s_apszValues[] =
    1267                     {
    1268                         "NONE", "NEAREST", "LINEAR",  "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
    1269                     };
    1270                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1271                                           "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1272                     break;
    1273                 }
    1274 
    1275                 case 'g': //SVGA3dTextureCoordGen
    1276                 {
    1277                     static const char * const s_apszValues[] =
    1278                     {
    1279                         "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
    1280                     };
    1281                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1282                                           "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1283                     break;
    1284                 }
    1285 
    1286                 case 'm': //SVGA3dTextureCombiner
    1287                 {
    1288                     static const char * const s_apszValues[] =
    1289                     {
    1290                         "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
    1291                         "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
    1292                         "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
    1293                         "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
    1294                         "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
    1295                     };
    1296                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1297                                           "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1298                     break;
    1299                 }
    1300 
    1301                 default:
    1302                     AssertFailed();
    1303                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
    1304                     break;
    1305             }
    1306         }
    1307         else
    1308             RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
    1309     }
    1310     else
    1311         RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
    1312     return pszRet;
    1313 }
    1314 
    1315 
    1316 
    1317 static const char * const g_apszTransformTypes[] =
    1318 {
    1319     "SVGA3D_TRANSFORM_INVALID",
    1320     "SVGA3D_TRANSFORM_WORLD",
    1321     "SVGA3D_TRANSFORM_VIEW",
    1322     "SVGA3D_TRANSFORM_PROJECTION",
    1323     "SVGA3D_TRANSFORM_TEXTURE0",
    1324     "SVGA3D_TRANSFORM_TEXTURE1",
    1325     "SVGA3D_TRANSFORM_TEXTURE2",
    1326     "SVGA3D_TRANSFORM_TEXTURE3",
    1327     "SVGA3D_TRANSFORM_TEXTURE4",
    1328     "SVGA3D_TRANSFORM_TEXTURE5",
    1329     "SVGA3D_TRANSFORM_TEXTURE6",
    1330     "SVGA3D_TRANSFORM_TEXTURE7",
    1331     "SVGA3D_TRANSFORM_WORLD1",
    1332     "SVGA3D_TRANSFORM_WORLD2",
    1333     "SVGA3D_TRANSFORM_WORLD3",
    1334 };
    1335 
    1336 static const char * const g_apszFaces[] =
    1337 {
    1338     "SVGA3D_FACE_INVALID",
    1339     "SVGA3D_FACE_NONE",
    1340     "SVGA3D_FACE_FRONT",
    1341     "SVGA3D_FACE_BACK",
    1342     "SVGA3D_FACE_FRONT_BACK",
    1343 };
    1344 
    1345 static const char * const g_apszLightTypes[] =
    1346 {
    1347     "SVGA3D_LIGHTTYPE_INVALID",
    1348     "SVGA3D_LIGHTTYPE_POINT",
    1349     "SVGA3D_LIGHTTYPE_SPOT1",
    1350     "SVGA3D_LIGHTTYPE_SPOT2",
    1351     "SVGA3D_LIGHTTYPE_DIRECTIONAL",
    1352 };
    1353 
    1354 static const char * const g_apszRenderTargets[] =
    1355 {
    1356     "SVGA3D_RT_DEPTH",
    1357     "SVGA3D_RT_STENCIL",
    1358     "SVGA3D_RT_COLOR0",
    1359     "SVGA3D_RT_COLOR1",
    1360     "SVGA3D_RT_COLOR2",
    1361     "SVGA3D_RT_COLOR3",
    1362     "SVGA3D_RT_COLOR4",
    1363     "SVGA3D_RT_COLOR5",
    1364     "SVGA3D_RT_COLOR6",
    1365     "SVGA3D_RT_COLOR7",
    1366 };
    1367 
    1368 static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
    1369 {
    1370     char szTmp[128];
    1371 
    1372     pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
    1373 #ifdef RT_OS_WINDOWS
    1374     pHlp->pfnPrintf(pHlp, "hwnd:                    %p\n", pContext->hwnd);
    1375     if (fVerbose)
    1376         vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
    1377 # ifdef VMSVGA3D_DIRECT3D
    1378     pHlp->pfnPrintf(pHlp, "pDevice:                 %p\n", pContext->pDevice);
    1379 # else
    1380     pHlp->pfnPrintf(pHlp, "hdc:                     %p\n", pContext->hdc);
    1381     pHlp->pfnPrintf(pHlp, "hglrc:                   %p\n", pContext->hglrc);
    1382 # endif
    1383 #else
    1384 /** @todo Other hosts... */
    1385 #endif
    1386     pHlp->pfnPrintf(pHlp, "sidRenderTarget:         %#x\n", pContext->sidRenderTarget);
    1387 
    1388     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
    1389         if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
    1390             pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]:    %#x\n", i, pContext->aSidActiveTexture[i]);
    1391 
    1392     pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
    1393 
    1394     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
    1395         if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
    1396             pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
    1397                             vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
    1398 
    1399     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
    1400         for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
    1401             if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
    1402                 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
    1403                                 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
    1404 
    1405     AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
    1406     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
    1407         if (pContext->state.aTransformState[i].fValid)
    1408         {
    1409             pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
    1410             for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
    1411                 pHlp->pfnPrintf(pHlp,
    1412                                 (j % 4) == 0 ? "    [ " FLOAT_FMT_STR : (j % 4) < 3  ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
    1413                                 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
    1414         }
    1415 
    1416     AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
    1417     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
    1418         if (pContext->state.aMaterial[i].fValid)
    1419         {
    1420             pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
    1421                             g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
    1422             pHlp->pfnPrintf(pHlp, "    diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1423                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
    1424                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
    1425                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
    1426                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
    1427             pHlp->pfnPrintf(pHlp, "    ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1428                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
    1429                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
    1430                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
    1431                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
    1432             pHlp->pfnPrintf(pHlp, "    specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1433                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
    1434                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
    1435                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
    1436                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
    1437             pHlp->pfnPrintf(pHlp, "    emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1438                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
    1439                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
    1440                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
    1441                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
    1442         }
    1443 
    1444     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
    1445         if (pContext->state.aClipPlane[i].fValid)
    1446             pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1447                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
    1448                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
    1449                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
    1450                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
    1451 
    1452     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
    1453         if (pContext->state.aLightData[i].fValidData)
    1454         {
    1455             pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
    1456                             i,
    1457                             pContext->state.aLightData[i].fEnabled,
    1458                             pContext->state.aLightData[i].data.inWorldSpace,
    1459                             (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
    1460                             ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
    1461                             pContext->state.aLightData[i].data.type);
    1462             pHlp->pfnPrintf(pHlp, "    diffuse  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1463                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
    1464                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
    1465                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
    1466                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
    1467             pHlp->pfnPrintf(pHlp, "    specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1468                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
    1469                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
    1470                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
    1471                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
    1472             pHlp->pfnPrintf(pHlp, "    ambient  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1473                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
    1474                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
    1475                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
    1476                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
    1477             pHlp->pfnPrintf(pHlp, "    position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1478                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
    1479                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
    1480                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
    1481                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
    1482             pHlp->pfnPrintf(pHlp, "    direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1483                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
    1484                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
    1485                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
    1486                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
    1487             pHlp->pfnPrintf(pHlp, "    range=" FLOAT_FMT_STR "  falloff=" FLOAT_FMT_STR "\n",
    1488                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
    1489                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
    1490             pHlp->pfnPrintf(pHlp, "    attenuation0=" FLOAT_FMT_STR "  attenuation1=" FLOAT_FMT_STR "  attenuation2=" FLOAT_FMT_STR "\n",
    1491                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
    1492                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
    1493                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
    1494             pHlp->pfnPrintf(pHlp, "    theta=" FLOAT_FMT_STR "  phi=" FLOAT_FMT_STR "\n",
    1495                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
    1496                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
    1497         }
    1498 
    1499     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
    1500         if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
    1501             pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
    1502                             i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
    1503                             pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
    1504 
    1505     pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
    1506                     pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
    1507                     pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
    1508     pHlp->pfnPrintf(pHlp, "zRange:        (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
    1509                     FLOAT_FMT_ARGS(pContext->state.zRange.min),
    1510                     FLOAT_FMT_ARGS(pContext->state.zRange.max));
    1511     pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
    1512     pHlp->pfnPrintf(pHlp, "shidPixel:               %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
    1513     pHlp->pfnPrintf(pHlp, "shidVertex:              %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
    1514 
    1515     for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
    1516     {
    1517         uint32_t            cConsts  = iWhich == 0 ? pContext->state.cPixelShaderConst   : pContext->state.cVertexShaderConst;
    1518         PVMSVGASHADERCONST  paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst  : pContext->state.paVertexShaderConst;
    1519         const char         *pszName  = iWhich      ?                "paPixelShaderConst" :                "paVertexShaderConst";
    1520 
    1521         for (uint32_t i = 0; i < cConsts; i++)
    1522             if (paConsts[i].fValid)
    1523             {
    1524                 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
    1525                     pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
    1526                                     pszName, i, i,
    1527                                     FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
    1528                                     FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
    1529                 else
    1530                     pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
    1531                                     pszName, i, i,
    1532                                     paConsts[i].value[0], paConsts[i].value[1],
    1533                                     paConsts[i].value[2], paConsts[i].value[3],
    1534                                     paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
    1535                                     : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
    1536             }
    1537     }
    1538 
    1539     for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
    1540     {
    1541         uint32_t        cShaders  = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
    1542         PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
    1543         const char     *pszName   = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
    1544         for (uint32_t i = 0; i < cShaders; i++)
    1545             if (paShaders[i].id == i)
    1546             {
    1547                 pHlp->pfnPrintf(pHlp, "%s[%u]:   id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
    1548                                 pszName, i,
    1549                                 paShaders[i].id,
    1550                                 paShaders[i].cid,
    1551                                 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
    1552                                 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
    1553                                 paShaders[i].type,
    1554                                 paShaders[i].cbData,
    1555                                 paShaders[i].pShaderProgram);
    1556             }
    1557     }
    1558 }
    1559 
    1560 
    1561 void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
    1562 {
    1563     /* Warning! This code is currently racing papContexts reallocation! */
    1564     /* Warning! This code is currently racing papContexts reallocation! */
    1565     /* Warning! This code is currently racing papContexts reallocation! */
    1566     VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
    1567     if (pState)
    1568     {
    1569         /*
    1570          * Deal with a specific request first.
    1571          */
    1572         if (cid != UINT32_MAX)
    1573         {
    1574             if (cid < pState->cContexts)
    1575             {
    1576                 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    1577                 if (pContext && pContext->id == cid)
    1578                 {
    1579                     vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
    1580                     return;
    1581                 }
    1582             }
    1583             pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
    1584         }
    1585         else
    1586         {
    1587             /*
    1588              * Dump all.
    1589              */
    1590             uint32_t cContexts = pState->cContexts;
    1591             pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
    1592             for (cid = 0; cid < cContexts; cid++)
    1593             {
    1594                 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    1595                 if (pContext && pContext->id == cid)
    1596                 {
    1597                     pHlp->pfnPrintf(pHlp, "\n");
    1598                     vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
    1599                 }
    1600             }
    1601         }
    1602     }
    1603 }
    1604101
    1605102/** Values for SVGA3dTextureFilter, prefix SVGA3D_TEX_FILTER_. */
     
    1748245};
    1749246
    1750 
     247#endif /* VMSVGA3D_DIRECT3D */
     248
     249
     250/**
     251 * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.
     252 *
     253 * This will allocate heap buffers if necessary, thus increasing the memory
     254 * usage of the process.
     255 *
     256 * @todo Would be interesting to share this code with the saved state code.
     257 *
     258 * @returns VBox status code.
     259 * @param   pState              The 3D state structure.
     260 * @param   pSurface            The surface to refresh the heap buffers for.
     261 */
     262static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
     263{
     264    /*
     265     * Currently we've got trouble retreving bit for DEPTHSTENCIL
     266     * surfaces both for OpenGL and D3D, so skip these here (don't
     267     * wast memory on them).
     268     */
     269    uint32_t const fSwitchFlags = pSurface->flags
     270                                & (  SVGA3D_SURFACE_HINT_INDEXBUFFER  | SVGA3D_SURFACE_HINT_VERTEXBUFFER
     271                                   | SVGA3D_SURFACE_HINT_TEXTURE      | SVGA3D_SURFACE_HINT_RENDERTARGET
     272                                   | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);
     273    if (   fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL
     274        && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))
     275    {
     276
     277#ifdef VMSVGA3D_OPENGL
     278        /*
     279         * Change OpenGL context to the one the surface is associated with.
     280         */
     281        PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
     282        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
     283#endif
     284
     285        /*
     286         * Work thru each mipmap level for each face.
     287         */
     288        for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
     289        {
     290            Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
     291            PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
     292            for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
     293            {
     294#ifdef VMSVGA3D_DIRECT3D
     295                if (pSurface->u.pSurface)
     296#else
     297                if (pSurface->oglId.texture != OPENGL_INVALID_ID)
     298#endif
     299                {
     300                    Assert(pMipmapLevel->cbSurface);
     301                    Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */
     302
     303                    /*
     304                     * Make sure we've got surface memory buffer.
     305                     */
     306                    uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;
     307                    if (!pbDst)
     308                    {
     309                        pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);
     310                        AssertReturn(pbDst, VERR_NO_MEMORY);
     311                    }
     312
     313#ifdef VMSVGA3D_DIRECT3D
     314                    /*
     315                     * D3D specifics.
     316                     */
     317                    HRESULT  hr;
     318                    switch (fSwitchFlags)
     319                    {
     320                        case SVGA3D_SURFACE_HINT_TEXTURE:
     321                        case SVGA3D_SURFACE_HINT_RENDERTARGET:
     322                        case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
     323                        {
     324                            /*
     325                             * Lock the buffer and make it accessible to memcpy.
     326                             */
     327                            D3DLOCKED_RECT LockedRect;
     328                            if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
     329                            {
     330                                if (pSurface->bounce.pTexture)
     331                                {
     332                                    if (    !pSurface->fDirty
     333                                        &&  fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)
     334                                        &&  i == 0 /* only the first time */)
     335                                    {
     336                                        /** @todo stricter checks for associated context */
     337                                        uint32_t cid = pSurface->idAssociatedContext;
     338                                        if (   cid >= pState->cContexts
     339                                            || pState->papContexts[cid]->id != cid)
     340                                        {
     341                                            Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
     342                                            AssertFailedReturn(VERR_INVALID_PARAMETER);
     343                                        }
     344                                        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
     345
     346                                        IDirect3DSurface9 *pDst = NULL;
     347                                        hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);
     348                                        AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
     349
     350                                        IDirect3DSurface9 *pSrc = NULL;
     351                                        hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
     352                                        AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
     353
     354                                        hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);
     355                                        AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);
     356
     357                                        pSrc->Release();
     358                                        pDst->Release();
     359                                    }
     360
     361                                    hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
     362                                                                             &LockedRect,
     363                                                                             NULL,
     364                                                                             D3DLOCK_READONLY);
     365                                }
     366                                else
     367                                    hr = pSurface->u.pTexture->LockRect(i, /* texture level */
     368                                                                        &LockedRect,
     369                                                                        NULL,
     370                                                                        D3DLOCK_READONLY);
     371                            }
     372                            else
     373                                hr = pSurface->u.pSurface->LockRect(&LockedRect,
     374                                                                    NULL,
     375                                                                    D3DLOCK_READONLY);
     376                            AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
     377
     378                            /*
     379                             * Copy the data.  Take care in case the pitch differs.
     380                             */
     381                            if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)
     382                                memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);
     383                            else
     384                                for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
     385                                    memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,
     386                                           (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,
     387                                           pMipmapLevel->cbSurfacePitch);
     388
     389                            /*
     390                             * Release the buffer.
     391                             */
     392                            if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
     393                            {
     394                                if (pSurface->bounce.pTexture)
     395                                {
     396                                    hr = pSurface->bounce.pTexture->UnlockRect(i);
     397                                    AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
     398                                }
     399                                else
     400                                    hr = pSurface->u.pTexture->UnlockRect(i);
     401                            }
     402                            else
     403                                hr = pSurface->u.pSurface->UnlockRect();
     404                            AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
     405                            break;
     406                        }
     407
     408                        case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
     409                        {
     410                            void *pvD3DData = NULL;
     411                            hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
     412                            AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);
     413
     414                            memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
     415
     416                            hr = pSurface->u.pVertexBuffer->Unlock();
     417                            AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));
     418                            break;
     419                        }
     420
     421                        case SVGA3D_SURFACE_HINT_INDEXBUFFER:
     422                        {
     423                            void *pvD3DData = NULL;
     424                            hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
     425                            AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);
     426
     427                            memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
     428
     429                            hr = pSurface->u.pIndexBuffer->Unlock();
     430                            AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));
     431                            break;
     432                        }
     433
     434                        default:
     435                            AssertMsgFailed(("%#x\n", fSwitchFlags));
     436                    }
     437
     438#elif defined(VMSVGA3D_OPENGL)
     439                    /*
     440                     * OpenGL specifics.
     441                     */
     442                    switch (fSwitchFlags)
     443                    {
     444                        case SVGA3D_SURFACE_HINT_TEXTURE:
     445                        case SVGA3D_SURFACE_HINT_RENDERTARGET:
     446                        case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
     447                        {
     448                            GLint activeTexture;
     449                            glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
     450                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
     451
     452                            glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
     453                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
     454
     455                            /* Set row length and alignment of the output data. */
     456                            VMSVGAPACKPARAMS SavedParams;
     457                            vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);
     458
     459                            glGetTexImage(GL_TEXTURE_2D,
     460                                          i,
     461                                          pSurface->formatGL,
     462                                          pSurface->typeGL,
     463                                          pbDst);
     464                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
     465
     466                            vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);
     467
     468                            /* Restore the old active texture. */
     469                            glBindTexture(GL_TEXTURE_2D, activeTexture);
     470                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
     471                            break;
     472                        }
     473
     474                        case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
     475                        case SVGA3D_SURFACE_HINT_INDEXBUFFER:
     476                        {
     477                            pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
     478                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     479
     480                            void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
     481                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     482                            if (RT_VALID_PTR(pvSrc))
     483                                memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);
     484                            else
     485                                AssertPtr(pvSrc);
     486
     487                            pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
     488                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     489
     490                            pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
     491                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     492                            break;
     493                        }
     494
     495                        default:
     496                            AssertMsgFailed(("%#x\n", fSwitchFlags));
     497                    }
     498#else
     499# error "misconfigured"
     500#endif
     501                }
     502                /* else: There is no data in hardware yet, so whatever we got is already current. */
     503            }
     504        }
     505    }
     506
     507    return VINF_SUCCESS;
     508}
     509
     510
     511/**
     512 * Updates the heap buffers for all surfaces or one specific one.
     513 *
     514 * @param   pThis               The VGA device instance data.
     515 * @param   sid                 The surface ID, UINT32_MAX if all.
     516 * @thread  VMSVGAFIFO
     517 */
     518void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)
     519{
     520    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     521    AssertReturnVoid(pState);
     522
     523    if (sid == UINT32_MAX)
     524    {
     525        uint32_t cSurfaces = pState->cSurfaces;
     526        for (sid = 0; sid < cSurfaces; sid++)
     527        {
     528            PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
     529            if (pSurface && pSurface->id == sid)
     530                vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
     531        }
     532    }
     533    else if (sid < pState->cSurfaces)
     534    {
     535        PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
     536        if (pSurface && pSurface->id == sid)
     537            vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
     538    }
     539}
     540
     541
     542
     543
     544void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)
     545{
     546    for (uint32_t i = 0; i < cFlags; i++)
     547        if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)
     548        {
     549            Assert(paFlags[i].fFlags);
     550            pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);
     551            fFlags &= ~paFlags[i].fFlags;
     552            if (!fFlags)
     553                return;
     554        }
     555    if (fFlags)
     556        pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);
     557}
     558
     559
     560/**
     561 * Worker for vmsvgaR3Info that display details of a host window.
     562 *
     563 * @param   pHlp            The output methods.
     564 * @param   idHostWindow    The host window handle/id/whatever.
     565 */
     566void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)
     567{
     568#ifdef RT_OS_WINDOWS
     569    HWND hwnd = (HWND)(uintptr_t)idHostWindow;
     570    Assert((uintptr_t)hwnd == idHostWindow);
     571    if (hwnd != NULL)
     572    {
     573        WINDOWINFO Info;
     574        RT_ZERO(Info);
     575        Info.cbSize = sizeof(Info);
     576        if (GetWindowInfo(hwnd, &Info))
     577        {
     578            pHlp->pfnPrintf(pHlp, "     Window rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
     579                            Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,
     580                            Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);
     581            pHlp->pfnPrintf(pHlp, "     Client rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
     582                            Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,
     583                            Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);
     584            pHlp->pfnPrintf(pHlp, "     Style:         %#x", Info.dwStyle);
     585            static const VMSVGAINFOFLAGS32 g_aStyles[] =
     586            {
     587                { WS_POPUP        , "POPUP" },
     588                { WS_CHILD        , "CHILD" },
     589                { WS_MINIMIZE     , "MINIMIZE" },
     590                { WS_VISIBLE      , "VISIBLE" },
     591                { WS_DISABLED     , "DISABLED" },
     592                { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },
     593                { WS_CLIPCHILDREN , "CLIPCHILDREN" },
     594                { WS_MAXIMIZE     , "MAXIMIZE" },
     595                { WS_BORDER       , "BORDER" },
     596                { WS_DLGFRAME     , "DLGFRAME" },
     597                { WS_VSCROLL      , "VSCROLL" },
     598                { WS_HSCROLL      , "HSCROLL" },
     599                { WS_SYSMENU      , "SYSMENU" },
     600                { WS_THICKFRAME   , "THICKFRAME" },
     601                { WS_GROUP        , "GROUP" },
     602                { WS_TABSTOP      , "TABSTOP" },
     603            };
     604            vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));
     605            pHlp->pfnPrintf(pHlp, "\n");
     606
     607            pHlp->pfnPrintf(pHlp, "     ExStyle:       %#x", Info.dwExStyle);
     608            static const VMSVGAINFOFLAGS32 g_aExStyles[] =
     609            {
     610                { WS_EX_DLGMODALFRAME,   "DLGMODALFRAME" },
     611                { 0x00000002,            "DRAGDETECT" },
     612                { WS_EX_NOPARENTNOTIFY,  "NOPARENTNOTIFY" },
     613                { WS_EX_TOPMOST,         "TOPMOST" },
     614                { WS_EX_ACCEPTFILES,     "ACCEPTFILES" },
     615                { WS_EX_TRANSPARENT,     "TRANSPARENT" },
     616                { WS_EX_MDICHILD,        "MDICHILD" },
     617                { WS_EX_TOOLWINDOW,      "TOOLWINDOW" },
     618                { WS_EX_WINDOWEDGE,      "WINDOWEDGE" },
     619                { WS_EX_CLIENTEDGE,      "CLIENTEDGE" },
     620                { WS_EX_CONTEXTHELP,     "CONTEXTHELP" },
     621                { WS_EX_RIGHT,           "RIGHT" },
     622                /*{ WS_EX_LEFT,            "LEFT" }, = 0 */
     623                { WS_EX_RTLREADING,      "RTLREADING" },
     624                /*{ WS_EX_LTRREADING,      "LTRREADING" }, = 0 */
     625                { WS_EX_LEFTSCROLLBAR,   "LEFTSCROLLBAR" },
     626                /*{ WS_EX_RIGHTSCROLLBAR,  "RIGHTSCROLLBAR" }, = 0 */
     627                { WS_EX_CONTROLPARENT,   "CONTROLPARENT" },
     628                { WS_EX_STATICEDGE,      "STATICEDGE" },
     629                { WS_EX_APPWINDOW,       "APPWINDOW" },
     630                { WS_EX_LAYERED,         "LAYERED" },
     631                { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },
     632                { WS_EX_LAYOUTRTL,       "LAYOUTRTL" },
     633                { WS_EX_COMPOSITED,      "COMPOSITED" },
     634                { WS_EX_NOACTIVATE,      "NOACTIVATE" },
     635            };
     636            vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));
     637            pHlp->pfnPrintf(pHlp, "\n");
     638
     639            pHlp->pfnPrintf(pHlp, "     Window Status: %#x\n", Info.dwWindowStatus);
     640            if (Info.cxWindowBorders || Info.cyWindowBorders)
     641                pHlp->pfnPrintf(pHlp, "     Borders:       cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);
     642            pHlp->pfnPrintf(pHlp, "     Window Type:   %#x\n", Info.atomWindowType);
     643            pHlp->pfnPrintf(pHlp, "     Creator Ver:   %#x\n", Info.wCreatorVersion);
     644        }
     645        else
     646            pHlp->pfnPrintf(pHlp, "     GetWindowInfo: last error %d\n", GetLastError());
     647    }
     648#else
     649    pHlp->pfnPrintf(pHlp, "    Windows info:   Not implemented on this platform\n");
     650#endif
     651
     652}
     653
     654
     655/**
     656 * Looks up an enum value in a translation table.
     657 *
     658 * @returns The value name.
     659 * @param   iValue              The value to name.
     660 * @param   pEnumMap            Enum value to string mapping.
     661 */
     662const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)
     663{
     664    PCVMSVGAINFOENUM paValues = pEnumMap->paValues;
     665
     666#ifdef VBOX_STRICT
     667    /*
     668     * Check that it's really sorted, or the binary lookup won't work right.
     669     */
     670    if (!*pEnumMap->pfAsserted)
     671    {
     672        *pEnumMap->pfAsserted = true;
     673        for (uint32_t i = 1; i < pEnumMap->cValues; i++)
     674            Assert(paValues[i - 1].iValue <= paValues[i].iValue);
     675    }
     676#endif
     677
     678    /*
     679     * Binary search
     680     */
     681    uint32_t iStart = 0;
     682    uint32_t iEnd   = (uint32_t)pEnumMap->cValues;
     683    for (;;)
     684    {
     685        uint32_t i = iStart + (iEnd - iStart) / 2;
     686        if (iValue < paValues[i].iValue)
     687        {
     688            if (i > iStart)
     689                iEnd = i;
     690            else
     691                break;
     692        }
     693        else if (iValue > paValues[i].iValue)
     694        {
     695            i++;
     696            if (i < iEnd)
     697                iStart = i;
     698            else
     699                break;
     700        }
     701        else
     702            return paValues[i].pszName;
     703    }
     704    return NULL;
     705}
     706
     707
     708/**
     709 * Formats an enum value as a string, sparse mapping table.
     710 *
     711 * @returns pszBuffer.
     712 * @param   pszBuffer           The output buffer.
     713 * @param   cbBuffer            The size of the output buffer.
     714 * @param   pszName             The variable name, optional.
     715 * @param   iValue              The enum value.
     716 * @param   fPrefix             Whether to prepend the prefix or not.
     717 * @param   pEnumMap            Enum value to string mapping.
     718 */
     719char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
     720                              bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)
     721{
     722    const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);
     723    const char *pszPrefix    = fPrefix ? pEnumMap->pszPrefix : "";
     724    if (pszValueName)
     725    {
     726        if (pszName)
     727            RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);
     728        else
     729            RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);
     730        return pszBuffer;
     731    }
     732
     733    if (pszName)
     734        RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
     735    else
     736        RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
     737    return pszBuffer;
     738}
     739
     740
     741/**
     742 * Formats an enum value as a string.
     743 *
     744 * @returns pszBuffer.
     745 * @param   pszBuffer           The output buffer.
     746 * @param   cbBuffer            The size of the output buffer.
     747 * @param   pszName             The variable name, optional.
     748 * @param   uValue              The enum value.
     749 * @param   pszPrefix           The prefix of the enum values.  Empty string if
     750 *                              none.  This helps reduce the memory footprint
     751 *                              as well as the source code size.
     752 * @param   papszValues         One to one string mapping of the enum values.
     753 * @param   cValues             The number of values in the mapping.
     754 */
     755char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
     756                            const char *pszPrefix, const char * const *papszValues, size_t cValues)
     757{
     758    if (uValue < cValues)
     759    {
     760        if (pszName)
     761            RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
     762        else
     763            RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
     764    }
     765    else
     766    {
     767        if (pszName)
     768            RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
     769        else
     770            RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
     771    }
     772    return pszBuffer;
     773}
     774
     775
     776/**
     777 * DBGF info printer for vmsvga3dAsciiPrint.
     778 *
     779 * @param   pszLine             The line to print.
     780 * @param   pvUser              The debug info helpers.
     781 */
     782DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
     783{
     784    PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
     785    pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
     786}
     787
     788
     789/**
     790 * Log printer for vmsvga3dAsciiPrint.
     791 *
     792 * @param   pszLine             The line to print.
     793 * @param   pvUser              Ignored.
     794 */
     795DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
     796{
     797    size_t cch = strlen(pszLine);
     798    while (cch > 0 && pszLine[cch - 1] == ' ')
     799        cch--;
     800    RTLogPrintf("%.*s\n", cch, pszLine);
     801    NOREF(pvUser);
     802}
     803
     804
     805void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
     806                        uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
     807                        uint32_t cchMaxX, uint32_t cchMaxY)
     808{
     809    /*
     810     * Skip stuff we can't or won't need to handle.
     811     */
     812    if (!cx || !cy)
     813        return;
     814    switch (enmFormat)
     815    {
     816        /* Compressed. */
     817        case SVGA3D_DXT1:
     818        case SVGA3D_DXT2:
     819        case SVGA3D_DXT3:
     820        case SVGA3D_DXT4:
     821        case SVGA3D_DXT5:
     822            return;
     823        /* Generic. */
     824        case SVGA3D_BUFFER:
     825            return;
     826        default:
     827            break; /* ok */
     828    }
     829
     830    /*
     831     * Figure the pixel conversion factors.
     832     */
     833    uint32_t cxPerChar = cx / cchMaxX + 1;
     834    uint32_t cyPerChar = cy / cchMaxY + 1;
     835    /** @todo try keep aspect...   */
     836    uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
     837    uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
     838
     839    /*
     840     * The very simple conversion we're doing in this function is based on
     841     * mapping a block of converted pixels to an ASCII character of similar
     842     * weigth.  We do that by summing up all the 8-bit gray scale pixels in
     843     * that block, applying a conversion factor and getting an index into an
     844     * array of increasingly weighty characters.
     845     */
     846    static const char       s_szPalette[] = "   ..`',:;icodxkO08XNWM";
     847    static const uint32_t   s_cchPalette  = sizeof(s_szPalette) - 1;
     848    uint32_t const          cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
     849
     850    /*
     851     * Do the work
     852     */
     853    uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
     854    if (!pauScanline)
     855        return;
     856    char *pszLine = (char *)&pauScanline[cchLine];
     857    RTCPTRUNION uSrc;
     858    uSrc.pv              = pvImage;
     859    if (fInvY)
     860        uSrc.pu8 += (cy - 1) * cbScanline;
     861    uint32_t cyLeft = cy;
     862    uint32_t cyLeftInScanline = cyPerChar;
     863    bool     fHitFormatAssert = false;
     864    for (;;)
     865    {
     866        /*
     867         * Process the scanline.  This is tedious because of all the
     868         * different formats.  We generally ignore alpha, unless it's
     869         * all we've got to work with.
     870         * Color to 8-bit grayscale conversion is done by averaging.
     871         */
     872#define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \
     873            do { \
     874                for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
     875                { \
     876                    a_RdExpr; \
     877                    pauScanline[xDst] += (a_AddExpr) & 0xff; \
     878                    Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
     879                    if (--cxLeftInChar == 0) \
     880                    { \
     881                        xDst++; \
     882                        cxLeftInChar = cxPerChar; \
     883                    } \
     884                } \
     885            } while (0)
     886
     887        switch (enmFormat)
     888        {
     889            /* Unsigned RGB and super/subsets. */
     890            case SVGA3D_X8R8G8B8:
     891            case SVGA3D_A8R8G8B8:
     892                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     893                                 (  ( u32Tmp        & 0xff) /* B */
     894                                  + ((u32Tmp >>  8) & 0xff) /* G */
     895                                  + ((u32Tmp >> 16) & 0xff) /* R */) / 3);
     896                break;
     897            case SVGA3D_R5G6B5:
     898                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     899                                 ( ( u16Tmp         & 0x1f) * 8
     900                                 + ((u16Tmp >>  5)  & 0x3f) * 4
     901                                 + ( u16Tmp >> 11)          * 8 ) / 3 );
     902                break;
     903            case SVGA3D_X1R5G5B5:
     904            case SVGA3D_A1R5G5B5:
     905                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     906                                 (  ( u16Tmp        & 0x1f) * 8
     907                                  + ((u16Tmp >> 5)  & 0x1f) * 8
     908                                  + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );
     909                break;
     910            case SVGA3D_A4R4G4B4:
     911                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     912                                 (  ( u16Tmp        & 0xf) * 16
     913                                  + ((u16Tmp >> 4)  & 0xf) * 16
     914                                  + ((u16Tmp >> 8)  & 0xf) * 16) / 3 );
     915                break;
     916            case SVGA3D_A16B16G16R16:
     917                CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],
     918                                 (  ((u64Tmp >>  8) & 0xff) /* R */
     919                                  + ((u64Tmp >> 24) & 0xff) /* G */
     920                                  + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);
     921                break;
     922            case SVGA3D_A2R10G10B10:
     923                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     924                                 (  ( u32Tmp        & 0x3ff) /* B */
     925                                  + ((u32Tmp >> 10) & 0x3ff) /* G */
     926                                  + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));
     927                break;
     928            case SVGA3D_G16R16:
     929                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     930                                 (  (u32Tmp & 0xffff) /* R */
     931                                  + (u32Tmp >>   16 ) /* G */) / 0x200);
     932                break;
     933
     934            /* Depth. */
     935            case SVGA3D_Z_D32:
     936                CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),
     937                                   (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))
     938                                 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
     939                                 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
     940                                 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
     941                                 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
     942                                 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
     943                                 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
     944                                 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
     945                break;
     946            case SVGA3D_Z_D16:
     947                CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],
     948                                   ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))
     949                                 | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))
     950                                 | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))
     951                                 | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))
     952                                 | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))
     953                                 | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))
     954                                 | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))
     955                                 | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );
     956                break;
     957            case SVGA3D_Z_D24S8:
     958                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     959                                   (  u32Tmp        & 0xff) /* stencile */
     960                                 | ((~u32Tmp >> 18) & 0x3f));
     961                break;
     962            case SVGA3D_Z_D15S1:
     963                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     964                                   ( (u16Tmp & 0x01) << 7) /* stencile */
     965                                 | ((~u16Tmp >> 8) & 0x7f));
     966                break;
     967
     968            /* Pure alpha. */
     969            case SVGA3D_ALPHA8:
     970                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
     971                break;
     972
     973            /* Luminance */
     974            case SVGA3D_LUMINANCE8:
     975                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
     976                break;
     977            case SVGA3D_LUMINANCE4_ALPHA4:
     978                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);
     979                break;
     980            case SVGA3D_LUMINANCE16:
     981                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
     982                break;
     983            case SVGA3D_LUMINANCE8_ALPHA8:
     984                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
     985                break;
     986
     987            /* Not supported. */
     988            case SVGA3D_DXT1:
     989            case SVGA3D_DXT2:
     990            case SVGA3D_DXT3:
     991            case SVGA3D_DXT4:
     992            case SVGA3D_DXT5:
     993            case SVGA3D_BUFFER:
     994                AssertFailedBreak();
     995
     996            /* Not considered for implementation yet. */
     997            case SVGA3D_BUMPU8V8:
     998            case SVGA3D_BUMPL6V5U5:
     999            case SVGA3D_BUMPX8L8V8U8:
     1000            case SVGA3D_BUMPL8V8U8:
     1001            case SVGA3D_ARGB_S10E5:
     1002            case SVGA3D_ARGB_S23E8:
     1003            case SVGA3D_V8U8:
     1004            case SVGA3D_Q8W8V8U8:
     1005            case SVGA3D_CxV8U8:
     1006            case SVGA3D_X8L8V8U8:
     1007            case SVGA3D_A2W10V10U10:
     1008            case SVGA3D_R_S10E5:
     1009            case SVGA3D_R_S23E8:
     1010            case SVGA3D_RG_S10E5:
     1011            case SVGA3D_RG_S23E8:
     1012            case SVGA3D_Z_D24X8:
     1013            case SVGA3D_V16U16:
     1014            case SVGA3D_UYVY:
     1015            case SVGA3D_YUY2:
     1016            case SVGA3D_NV12:
     1017            case SVGA3D_AYUV:
     1018            case SVGA3D_BC4_UNORM:
     1019            case SVGA3D_BC5_UNORM:
     1020            case SVGA3D_Z_DF16:
     1021            case SVGA3D_Z_DF24:
     1022            case SVGA3D_Z_D24S8_INT:
     1023                if (!fHitFormatAssert)
     1024                {
     1025                    AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));
     1026                    fHitFormatAssert = true;
     1027                }
     1028                /* fall thru */
     1029            default:
     1030                /* Lazy programmer fallbacks. */
     1031                if (cbSrcPixel == 4)
     1032                    CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     1033                                     (  ( u32Tmp        & 0xff)
     1034                                      + ((u32Tmp >>  8) & 0xff)
     1035                                      + ((u32Tmp >> 16) & 0xff)
     1036                                      + ((u32Tmp >> 24) & 0xff) ) / 4);
     1037                else if (cbSrcPixel == 3)
     1038                    CONVERT_SCANLINE(RT_NOTHING,
     1039                                     (  (uint32_t)uSrc.pu8[xSrc * 4]
     1040                                      + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
     1041                                      + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
     1042                else if (cbSrcPixel == 2)
     1043                    CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     1044                                     (  ( u16Tmp        & 0xf)
     1045                                      + ((u16Tmp >>  4) & 0xf)
     1046                                      + ((u16Tmp >>  8) & 0xf)
     1047                                      + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );
     1048                else if (cbSrcPixel == 1)
     1049                    CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
     1050                else
     1051                    AssertFailed();
     1052                break;
     1053
     1054        }
     1055
     1056        /*
     1057         * Print we've reached the end of a block in y direction or if we're at
     1058         * the end of the image.
     1059         */
     1060        cyLeft--;
     1061        if (--cyLeftInScanline == 0 || cyLeft == 0)
     1062        {
     1063            for (uint32_t i = 0; i < cchLine; i++)
     1064            {
     1065                uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
     1066                pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
     1067            }
     1068            pszLine[cchLine] = '\0';
     1069            pfnPrintLine(pszLine, pvUser);
     1070
     1071            if (!cyLeft)
     1072                break;
     1073            cyLeftInScanline = cyPerChar;
     1074            RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
     1075        }
     1076
     1077        /*
     1078         * Advance.
     1079         */
     1080        if (!fInvY)
     1081            uSrc.pu8 += cbScanline;
     1082        else
     1083            uSrc.pu8 -= cbScanline;
     1084    }
     1085}
     1086
     1087
     1088
     1089/**
     1090 * Formats a SVGA3dRenderState structure as a string.
     1091 *
     1092 * @returns pszBuffer.
     1093 * @param   pszBuffer       Output string buffer.
     1094 * @param   cbBuffer        Size of output buffer.
     1095 * @param   pRenderState    The SVGA3d render state to format.
     1096 */
     1097char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
     1098{
     1099    /*
     1100     * List of render state names with type prefix.
     1101     *
     1102     * First char in the name is a type indicator:
     1103     *      - '*' = requires special handling.
     1104     *      - 'f' = SVGA3dbool
     1105     *      - 'd' = uint32_t
     1106     *      - 'r' = float
     1107     *      - 'b' = SVGA3dBlendOp
     1108     *      - 'c' = SVGA3dColor, SVGA3dColorMask
     1109     *      - 'e' = SVGA3dBlendEquation
     1110     *      - 'm' = SVGA3dColorMask
     1111     *      - 'p' = SVGA3dCmpFunc
     1112     *      - 's' = SVGA3dStencilOp
     1113     *      - 'v' = SVGA3dVertexMaterial
     1114     *      - 'w' = SVGA3dWrapFlags
     1115     */
     1116    static const char * const s_apszRenderStateNamesAndType[] =
     1117    {
     1118       "*" "INVALID",                       /*  invalid  */
     1119       "f" "ZENABLE",                       /*  SVGA3dBool  */
     1120       "f" "ZWRITEENABLE",                  /*  SVGA3dBool  */
     1121       "f" "ALPHATESTENABLE",               /*  SVGA3dBool  */
     1122       "f" "DITHERENABLE",                  /*  SVGA3dBool  */
     1123       "f" "BLENDENABLE",                   /*  SVGA3dBool  */
     1124       "f" "FOGENABLE",                     /*  SVGA3dBool  */
     1125       "f" "SPECULARENABLE",                /*  SVGA3dBool  */
     1126       "f" "STENCILENABLE",                 /*  SVGA3dBool  */
     1127       "f" "LIGHTINGENABLE",                /*  SVGA3dBool  */
     1128       "f" "NORMALIZENORMALS",              /*  SVGA3dBool  */
     1129       "f" "POINTSPRITEENABLE",             /*  SVGA3dBool  */
     1130       "f" "POINTSCALEENABLE",              /*  SVGA3dBool  */
     1131       "x" "STENCILREF",                    /*  uint32_t  */
     1132       "x" "STENCILMASK",                   /*  uint32_t  */
     1133       "x" "STENCILWRITEMASK",              /*  uint32_t  */
     1134       "r" "FOGSTART",                      /*  float  */
     1135       "r" "FOGEND",                        /*  float  */
     1136       "r" "FOGDENSITY",                    /*  float  */
     1137       "r" "POINTSIZE",                     /*  float  */
     1138       "r" "POINTSIZEMIN",                  /*  float  */
     1139       "r" "POINTSIZEMAX",                  /*  float  */
     1140       "r" "POINTSCALE_A",                  /*  float  */
     1141       "r" "POINTSCALE_B",                  /*  float  */
     1142       "r" "POINTSCALE_C",                  /*  float  */
     1143       "c" "FOGCOLOR",                      /*  SVGA3dColor  */
     1144       "c" "AMBIENT",                       /*  SVGA3dColor  */
     1145       "*" "CLIPPLANEENABLE",               /*  SVGA3dClipPlanes  */
     1146       "*" "FOGMODE",                       /*  SVGA3dFogMode  */
     1147       "*" "FILLMODE",                      /*  SVGA3dFillMode  */
     1148       "*" "SHADEMODE",                     /*  SVGA3dShadeMode  */
     1149       "*" "LINEPATTERN",                   /*  SVGA3dLinePattern  */
     1150       "b" "SRCBLEND",                      /*  SVGA3dBlendOp  */
     1151       "b" "DSTBLEND",                      /*  SVGA3dBlendOp  */
     1152       "e" "BLENDEQUATION",                 /*  SVGA3dBlendEquation  */
     1153       "*" "CULLMODE",                      /*  SVGA3dFace  */
     1154       "p" "ZFUNC",                         /*  SVGA3dCmpFunc  */
     1155       "p" "ALPHAFUNC",                     /*  SVGA3dCmpFunc  */
     1156       "p" "STENCILFUNC",                   /*  SVGA3dCmpFunc  */
     1157       "s" "STENCILFAIL",                   /*  SVGA3dStencilOp  */
     1158       "s" "STENCILZFAIL",                  /*  SVGA3dStencilOp  */
     1159       "s" "STENCILPASS",                   /*  SVGA3dStencilOp  */
     1160       "r" "ALPHAREF",                      /*  float  */
     1161       "*" "FRONTWINDING",                  /*  SVGA3dFrontWinding  */
     1162       "*" "COORDINATETYPE",                /*  SVGA3dCoordinateType  */
     1163       "r" "ZBIAS",                         /*  float  */
     1164       "f" "RANGEFOGENABLE",                /*  SVGA3dBool  */
     1165       "c" "COLORWRITEENABLE",              /*  SVGA3dColorMask  */
     1166       "f" "VERTEXMATERIALENABLE",          /*  SVGA3dBool  */
     1167       "v" "DIFFUSEMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
     1168       "v" "SPECULARMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
     1169       "v" "AMBIENTMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
     1170       "v" "EMISSIVEMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
     1171       "c" "TEXTUREFACTOR",                 /*  SVGA3dColor  */
     1172       "f" "LOCALVIEWER",                   /*  SVGA3dBool  */
     1173       "f" "SCISSORTESTENABLE",             /*  SVGA3dBool  */
     1174       "c" "BLENDCOLOR",                    /*  SVGA3dColor  */
     1175       "f" "STENCILENABLE2SIDED",           /*  SVGA3dBool  */
     1176       "p" "CCWSTENCILFUNC",                /*  SVGA3dCmpFunc  */
     1177       "s" "CCWSTENCILFAIL",                /*  SVGA3dStencilOp  */
     1178       "s" "CCWSTENCILZFAIL",               /*  SVGA3dStencilOp  */
     1179       "s" "CCWSTENCILPASS",                /*  SVGA3dStencilOp  */
     1180       "*" "VERTEXBLEND",                   /*  SVGA3dVertexBlendFlags  */
     1181       "r" "SLOPESCALEDEPTHBIAS",           /*  float  */
     1182       "r" "DEPTHBIAS",                     /*  float  */
     1183       "r" "OUTPUTGAMMA",                   /*  float  */
     1184       "f" "ZVISIBLE",                      /*  SVGA3dBool  */
     1185       "f" "LASTPIXEL",                     /*  SVGA3dBool  */
     1186       "f" "CLIPPING",                      /*  SVGA3dBool  */
     1187       "w" "WRAP0",                         /*  SVGA3dWrapFlags  */
     1188       "w" "WRAP1",                         /*  SVGA3dWrapFlags  */
     1189       "w" "WRAP2",                         /*  SVGA3dWrapFlags  */
     1190       "w" "WRAP3",                         /*  SVGA3dWrapFlags  */
     1191       "w" "WRAP4",                         /*  SVGA3dWrapFlags  */
     1192       "w" "WRAP5",                         /*  SVGA3dWrapFlags  */
     1193       "w" "WRAP6",                         /*  SVGA3dWrapFlags  */
     1194       "w" "WRAP7",                         /*  SVGA3dWrapFlags  */
     1195       "w" "WRAP8",                         /*  SVGA3dWrapFlags  */
     1196       "w" "WRAP9",                         /*  SVGA3dWrapFlags  */
     1197       "w" "WRAP10",                        /*  SVGA3dWrapFlags  */
     1198       "w" "WRAP11",                        /*  SVGA3dWrapFlags  */
     1199       "w" "WRAP12",                        /*  SVGA3dWrapFlags  */
     1200       "w" "WRAP13",                        /*  SVGA3dWrapFlags  */
     1201       "w" "WRAP14",                        /*  SVGA3dWrapFlags  */
     1202       "w" "WRAP15",                        /*  SVGA3dWrapFlags  */
     1203       "f" "MULTISAMPLEANTIALIAS",          /*  SVGA3dBool  */
     1204       "x" "MULTISAMPLEMASK",               /*  uint32_t  */
     1205       "f" "INDEXEDVERTEXBLENDENABLE",      /*  SVGA3dBool  */
     1206       "r" "TWEENFACTOR",                   /*  float  */
     1207       "f" "ANTIALIASEDLINEENABLE",         /*  SVGA3dBool  */
     1208       "c" "COLORWRITEENABLE1",             /*  SVGA3dColorMask  */
     1209       "c" "COLORWRITEENABLE2",             /*  SVGA3dColorMask  */
     1210       "c" "COLORWRITEENABLE3",             /*  SVGA3dColorMask  */
     1211       "f" "SEPARATEALPHABLENDENABLE",      /*  SVGA3dBool  */
     1212       "b" "SRCBLENDALPHA",                 /*  SVGA3dBlendOp  */
     1213       "b" "DSTBLENDALPHA",                 /*  SVGA3dBlendOp  */
     1214       "e" "BLENDEQUATIONALPHA",            /*  SVGA3dBlendEquation  */
     1215       "*" "TRANSPARENCYANTIALIAS",         /*  SVGA3dTransparencyAntialiasType  */
     1216       "f" "LINEAA",                        /*  SVGA3dBool  */
     1217       "r" "LINEWIDTH",                     /*  float  */
     1218    };
     1219
     1220    uint32_t iState = pRenderState->state;
     1221    if (iState != SVGA3D_RS_INVALID)
     1222    {
     1223        if (iState < RT_ELEMENTS(s_apszRenderStateNamesAndType))
     1224        {
     1225            const char *pszName = s_apszRenderStateNamesAndType[iState];
     1226            char const  chType  = *pszName++;
     1227
     1228            union
     1229            {
     1230               uint32_t  u;
     1231               float     r;
     1232               SVGA3dColorMask Color;
     1233            } uValue;
     1234            uValue.u = pRenderState->uintValue;
     1235
     1236            switch (chType)
     1237            {
     1238                case 'f':
     1239                    if (uValue.u == 0)
     1240                        RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
     1241                    else if (uValue.u == 1)
     1242                        RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
     1243                    else
     1244                        RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
     1245                    break;
     1246                case 'x':
     1247                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
     1248                    break;
     1249                case 'r':
     1250                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
     1251                                pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
     1252                    break;
     1253                case 'c': //SVGA3dColor, SVGA3dColorMask
     1254                    RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
     1255                                uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
     1256                    break;
     1257                case 'w': //SVGA3dWrapFlags
     1258                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
     1259                                uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
     1260                    break;
     1261                default:
     1262                    AssertFailed();
     1263                case 'b': //SVGA3dBlendOp
     1264                case 'e': //SVGA3dBlendEquation
     1265                case 'p': //SVGA3dCmpFunc
     1266                case 's': //SVGA3dStencilOp
     1267                case 'v': //SVGA3dVertexMaterial
     1268                case '*':
     1269                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
     1270                    break;
     1271            }
     1272        }
     1273        else
     1274            RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
     1275    }
     1276    else
     1277        RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
     1278    return pszBuffer;
     1279}
     1280
     1281
     1282/**
     1283 * Formats a SVGA3dTextureState structure as a string.
     1284 *
     1285 * @returns pszBuffer.
     1286 * @param   pszBuffer       Output string buffer.
     1287 * @param   cbBuffer        Size of output buffer.
     1288 * @param   pTextureState   The SVGA3d texture state to format.
     1289 */
     1290char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
     1291{
     1292    static const char * const s_apszTextureStateNamesAndType[] =
     1293    {
     1294        "*" "INVALID",                      /*  invalid  */
     1295        "x" "BIND_TEXTURE",                 /*  SVGA3dSurfaceId  */
     1296        "m" "COLOROP",                      /*  SVGA3dTextureCombiner  */
     1297        "a" "COLORARG1",                    /*  SVGA3dTextureArgData  */
     1298        "a" "COLORARG2",                    /*  SVGA3dTextureArgData  */
     1299        "m" "ALPHAOP",                      /*  SVGA3dTextureCombiner  */
     1300        "a" "ALPHAARG1",                    /*  SVGA3dTextureArgData  */
     1301        "a" "ALPHAARG2",                    /*  SVGA3dTextureArgData  */
     1302        "e" "ADDRESSU",                     /*  SVGA3dTextureAddress  */
     1303        "e" "ADDRESSV",                     /*  SVGA3dTextureAddress  */
     1304        "l" "MIPFILTER",                    /*  SVGA3dTextureFilter  */
     1305        "l" "MAGFILTER",                    /*  SVGA3dTextureFilter  */
     1306        "m" "MINFILTER",                    /*  SVGA3dTextureFilter  */
     1307        "c" "BORDERCOLOR",                  /*  SVGA3dColor  */
     1308        "r" "TEXCOORDINDEX",                /*  uint32_t  */
     1309        "t" "TEXTURETRANSFORMFLAGS",        /*  SVGA3dTexTransformFlags  */
     1310        "g" "TEXCOORDGEN",                  /*  SVGA3dTextureCoordGen  */
     1311        "r" "BUMPENVMAT00",                 /*  float  */
     1312        "r" "BUMPENVMAT01",                 /*  float  */
     1313        "r" "BUMPENVMAT10",                 /*  float  */
     1314        "r" "BUMPENVMAT11",                 /*  float  */
     1315        "x" "TEXTURE_MIPMAP_LEVEL",         /*  uint32_t  */
     1316        "r" "TEXTURE_LOD_BIAS",             /*  float  */
     1317        "x" "TEXTURE_ANISOTROPIC_LEVEL",    /*  uint32_t  */
     1318        "e" "ADDRESSW",                     /*  SVGA3dTextureAddress  */
     1319        "r" "GAMMA",                        /*  float  */
     1320        "r" "BUMPENVLSCALE",                /*  float  */
     1321        "r" "BUMPENVLOFFSET",               /*  float  */
     1322        "a" "COLORARG0",                    /*  SVGA3dTextureArgData  */
     1323        "a" "ALPHAARG0"                     /*  SVGA3dTextureArgData */
     1324    };
     1325
     1326    /*
     1327     * Format the stage first.
     1328     */
     1329    char  *pszRet    = pszBuffer;
     1330    size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
     1331    if (cchPrefix < cbBuffer)
     1332    {
     1333        cbBuffer  -= cchPrefix;
     1334        pszBuffer += cchPrefix;
     1335    }
     1336    else
     1337        cbBuffer = 0;
     1338
     1339    /*
     1340     * Format the name and value.
     1341     */
     1342    uint32_t iName = pTextureState->name;
     1343    if (iName != SVGA3D_TS_INVALID)
     1344    {
     1345        if (iName < RT_ELEMENTS(s_apszTextureStateNamesAndType))
     1346        {
     1347            const char *pszName = s_apszTextureStateNamesAndType[iName];
     1348            char        chType  = *pszName++;
     1349
     1350            union
     1351            {
     1352               uint32_t  u;
     1353               float     r;
     1354               SVGA3dColorMask Color;
     1355            } uValue;
     1356            uValue.u = pTextureState->value;
     1357
     1358            switch (chType)
     1359            {
     1360                case 'x':
     1361                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
     1362                    break;
     1363
     1364                case 'r':
     1365                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
     1366                                pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
     1367                    break;
     1368
     1369                case 'a': //SVGA3dTextureArgData
     1370                {
     1371                    static const char * const s_apszValues[] =
     1372                    {
     1373                        "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
     1374                    };
     1375                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1376                                          "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1377                    break;
     1378                }
     1379
     1380                case 'c': //SVGA3dColor, SVGA3dColorMask
     1381                    RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
     1382                                uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
     1383                    break;
     1384
     1385                case 'e': //SVGA3dTextureAddress
     1386                {
     1387                    static const char * const s_apszValues[] =
     1388                    {
     1389                        "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
     1390                    };
     1391                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1392                                          "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1393                    break;
     1394                }
     1395
     1396                case 'l': //SVGA3dTextureFilter
     1397                {
     1398                    static const char * const s_apszValues[] =
     1399                    {
     1400                        "NONE", "NEAREST", "LINEAR",  "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
     1401                    };
     1402                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1403                                          "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1404                    break;
     1405                }
     1406
     1407                case 'g': //SVGA3dTextureCoordGen
     1408                {
     1409                    static const char * const s_apszValues[] =
     1410                    {
     1411                        "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
     1412                    };
     1413                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1414                                          "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1415                    break;
     1416                }
     1417
     1418                case 'm': //SVGA3dTextureCombiner
     1419                {
     1420                    static const char * const s_apszValues[] =
     1421                    {
     1422                        "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
     1423                        "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
     1424                        "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
     1425                        "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
     1426                        "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
     1427                    };
     1428                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1429                                          "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1430                    break;
     1431                }
     1432
     1433                default:
     1434                    AssertFailed();
     1435                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
     1436                    break;
     1437            }
     1438        }
     1439        else
     1440            RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
     1441    }
     1442    else
     1443        RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
     1444    return pszRet;
     1445}
     1446
     1447
     1448
     1449static const char * const g_apszTransformTypes[] =
     1450{
     1451    "SVGA3D_TRANSFORM_INVALID",
     1452    "SVGA3D_TRANSFORM_WORLD",
     1453    "SVGA3D_TRANSFORM_VIEW",
     1454    "SVGA3D_TRANSFORM_PROJECTION",
     1455    "SVGA3D_TRANSFORM_TEXTURE0",
     1456    "SVGA3D_TRANSFORM_TEXTURE1",
     1457    "SVGA3D_TRANSFORM_TEXTURE2",
     1458    "SVGA3D_TRANSFORM_TEXTURE3",
     1459    "SVGA3D_TRANSFORM_TEXTURE4",
     1460    "SVGA3D_TRANSFORM_TEXTURE5",
     1461    "SVGA3D_TRANSFORM_TEXTURE6",
     1462    "SVGA3D_TRANSFORM_TEXTURE7",
     1463    "SVGA3D_TRANSFORM_WORLD1",
     1464    "SVGA3D_TRANSFORM_WORLD2",
     1465    "SVGA3D_TRANSFORM_WORLD3",
     1466};
     1467
     1468static const char * const g_apszFaces[] =
     1469{
     1470    "SVGA3D_FACE_INVALID",
     1471    "SVGA3D_FACE_NONE",
     1472    "SVGA3D_FACE_FRONT",
     1473    "SVGA3D_FACE_BACK",
     1474    "SVGA3D_FACE_FRONT_BACK",
     1475};
     1476
     1477static const char * const g_apszLightTypes[] =
     1478{
     1479    "SVGA3D_LIGHTTYPE_INVALID",
     1480    "SVGA3D_LIGHTTYPE_POINT",
     1481    "SVGA3D_LIGHTTYPE_SPOT1",
     1482    "SVGA3D_LIGHTTYPE_SPOT2",
     1483    "SVGA3D_LIGHTTYPE_DIRECTIONAL",
     1484};
     1485
     1486static const char * const g_apszRenderTargets[] =
     1487{
     1488    "SVGA3D_RT_DEPTH",
     1489    "SVGA3D_RT_STENCIL",
     1490    "SVGA3D_RT_COLOR0",
     1491    "SVGA3D_RT_COLOR1",
     1492    "SVGA3D_RT_COLOR2",
     1493    "SVGA3D_RT_COLOR3",
     1494    "SVGA3D_RT_COLOR4",
     1495    "SVGA3D_RT_COLOR5",
     1496    "SVGA3D_RT_COLOR6",
     1497    "SVGA3D_RT_COLOR7",
     1498};
     1499
     1500static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
     1501{
     1502    char szTmp[128];
     1503
     1504    pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
     1505#ifdef RT_OS_WINDOWS
     1506    pHlp->pfnPrintf(pHlp, "hwnd:                    %p\n", pContext->hwnd);
     1507    if (fVerbose)
     1508        vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
     1509# ifdef VMSVGA3D_DIRECT3D
     1510    pHlp->pfnPrintf(pHlp, "pDevice:                 %p\n", pContext->pDevice);
     1511# else
     1512    pHlp->pfnPrintf(pHlp, "hdc:                     %p\n", pContext->hdc);
     1513    pHlp->pfnPrintf(pHlp, "hglrc:                   %p\n", pContext->hglrc);
     1514# endif
     1515#else
     1516/** @todo Other hosts... */
     1517#endif
     1518    pHlp->pfnPrintf(pHlp, "sidRenderTarget:         %#x\n", pContext->sidRenderTarget);
     1519
     1520    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
     1521        if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
     1522            pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]:    %#x\n", i, pContext->aSidActiveTexture[i]);
     1523
     1524    pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
     1525
     1526    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
     1527        if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
     1528            pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
     1529                            vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
     1530
     1531    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
     1532        for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
     1533            if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
     1534                pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
     1535                                vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
     1536
     1537    AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
     1538    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
     1539        if (pContext->state.aTransformState[i].fValid)
     1540        {
     1541            pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
     1542            for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
     1543                pHlp->pfnPrintf(pHlp,
     1544                                (j % 4) == 0 ? "    [ " FLOAT_FMT_STR : (j % 4) < 3  ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
     1545                                FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
     1546        }
     1547
     1548    AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
     1549    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
     1550        if (pContext->state.aMaterial[i].fValid)
     1551        {
     1552            pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
     1553                            g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
     1554            pHlp->pfnPrintf(pHlp, "    diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1555                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
     1556                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
     1557                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
     1558                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
     1559            pHlp->pfnPrintf(pHlp, "    ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1560                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
     1561                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
     1562                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
     1563                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
     1564            pHlp->pfnPrintf(pHlp, "    specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1565                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
     1566                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
     1567                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
     1568                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
     1569            pHlp->pfnPrintf(pHlp, "    emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1570                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
     1571                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
     1572                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
     1573                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
     1574        }
     1575
     1576    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
     1577        if (pContext->state.aClipPlane[i].fValid)
     1578            pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1579                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
     1580                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
     1581                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
     1582                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
     1583
     1584    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
     1585        if (pContext->state.aLightData[i].fValidData)
     1586        {
     1587            pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
     1588                            i,
     1589                            pContext->state.aLightData[i].fEnabled,
     1590                            pContext->state.aLightData[i].data.inWorldSpace,
     1591                            (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
     1592                            ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
     1593                            pContext->state.aLightData[i].data.type);
     1594            pHlp->pfnPrintf(pHlp, "    diffuse  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1595                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
     1596                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
     1597                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
     1598                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
     1599            pHlp->pfnPrintf(pHlp, "    specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1600                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
     1601                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
     1602                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
     1603                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
     1604            pHlp->pfnPrintf(pHlp, "    ambient  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1605                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
     1606                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
     1607                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
     1608                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
     1609            pHlp->pfnPrintf(pHlp, "    position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1610                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
     1611                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
     1612                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
     1613                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
     1614            pHlp->pfnPrintf(pHlp, "    direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
     1615                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
     1616                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
     1617                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
     1618                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
     1619            pHlp->pfnPrintf(pHlp, "    range=" FLOAT_FMT_STR "  falloff=" FLOAT_FMT_STR "\n",
     1620                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
     1621                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
     1622            pHlp->pfnPrintf(pHlp, "    attenuation0=" FLOAT_FMT_STR "  attenuation1=" FLOAT_FMT_STR "  attenuation2=" FLOAT_FMT_STR "\n",
     1623                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
     1624                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
     1625                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
     1626            pHlp->pfnPrintf(pHlp, "    theta=" FLOAT_FMT_STR "  phi=" FLOAT_FMT_STR "\n",
     1627                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
     1628                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
     1629        }
     1630
     1631    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
     1632        if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
     1633            pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
     1634                            i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
     1635                            pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
     1636
     1637    pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
     1638                    pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
     1639                    pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
     1640    pHlp->pfnPrintf(pHlp, "zRange:        (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
     1641                    FLOAT_FMT_ARGS(pContext->state.zRange.min),
     1642                    FLOAT_FMT_ARGS(pContext->state.zRange.max));
     1643    pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
     1644    pHlp->pfnPrintf(pHlp, "shidPixel:               %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
     1645    pHlp->pfnPrintf(pHlp, "shidVertex:              %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
     1646
     1647    for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
     1648    {
     1649        uint32_t            cConsts  = iWhich == 0 ? pContext->state.cPixelShaderConst   : pContext->state.cVertexShaderConst;
     1650        PVMSVGASHADERCONST  paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst  : pContext->state.paVertexShaderConst;
     1651        const char         *pszName  = iWhich      ?                "paPixelShaderConst" :                "paVertexShaderConst";
     1652
     1653        for (uint32_t i = 0; i < cConsts; i++)
     1654            if (paConsts[i].fValid)
     1655            {
     1656                if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
     1657                    pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
     1658                                    pszName, i, i,
     1659                                    FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
     1660                                    FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
     1661                else
     1662                    pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
     1663                                    pszName, i, i,
     1664                                    paConsts[i].value[0], paConsts[i].value[1],
     1665                                    paConsts[i].value[2], paConsts[i].value[3],
     1666                                    paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
     1667                                    : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
     1668            }
     1669    }
     1670
     1671    for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
     1672    {
     1673        uint32_t        cShaders  = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
     1674        PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
     1675        const char     *pszName   = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
     1676        for (uint32_t i = 0; i < cShaders; i++)
     1677            if (paShaders[i].id == i)
     1678            {
     1679                pHlp->pfnPrintf(pHlp, "%s[%u]:   id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
     1680                                pszName, i,
     1681                                paShaders[i].id,
     1682                                paShaders[i].cid,
     1683                                paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
     1684                                : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
     1685                                paShaders[i].type,
     1686                                paShaders[i].cbData,
     1687                                paShaders[i].pShaderProgram);
     1688            }
     1689    }
     1690}
     1691
     1692
     1693void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
     1694{
     1695    /* Warning! This code is currently racing papContexts reallocation! */
     1696    /* Warning! This code is currently racing papContexts reallocation! */
     1697    /* Warning! This code is currently racing papContexts reallocation! */
     1698    VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
     1699    if (pState)
     1700    {
     1701        /*
     1702         * Deal with a specific request first.
     1703         */
     1704        if (cid != UINT32_MAX)
     1705        {
     1706            if (cid < pState->cContexts)
     1707            {
     1708                PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
     1709                if (pContext && pContext->id == cid)
     1710                {
     1711                    vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
     1712                    return;
     1713                }
     1714            }
     1715#ifdef VMSVGA3D_OPENGL
     1716            else if (   cid == VMSVGA3D_SHARED_CTX_ID
     1717                     && pState->SharedCtx.id == cid)
     1718            {
     1719                vmsvga3dInfoContextWorkerOne(pHlp, &((PVMSVGA3DSTATE)pState)->SharedCtx, fVerbose);
     1720                return;
     1721            }
     1722#endif
     1723            pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
     1724        }
     1725        else
     1726        {
     1727#ifdef VMSVGA3D_OPENGL
     1728            /*
     1729             * Dump the shared context.
     1730             */
     1731            if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
     1732            {
     1733                pHlp->pfnPrintf(pHlp, "Shared context:\n");
     1734                vmsvga3dInfoContextWorkerOne(pHlp, &((PVMSVGA3DSTATE)pState)->SharedCtx, fVerbose);
     1735            }
     1736#endif
     1737
     1738            /*
     1739             * Dump the per-screen contexts.
     1740             */
     1741            /** @todo multi screen   */
     1742
     1743            /*
     1744             * Dump all.
     1745             */
     1746            uint32_t cContexts = pState->cContexts;
     1747            pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
     1748            for (cid = 0; cid < cContexts; cid++)
     1749            {
     1750                PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
     1751                if (pContext && pContext->id == cid)
     1752                {
     1753                    pHlp->pfnPrintf(pHlp, "\n");
     1754                    vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
     1755                }
     1756            }
     1757        }
     1758    }
     1759}
     1760
     1761
     1762#ifdef VMSVGA3D_DIRECT3D
    17511763/**
    17521764 * Release all shared surface objects.
     
    17611773    return 0;
    17621774}
    1763 
    1764 #elif defined(VMSVGA3D_OPENGL)
    1765     /** @todo   */
    1766 
    1767 #else
    1768 # error "Build config error."
    1769 #endif
     1775#endif /* VMSVGA3D_DIRECT3D */
    17701776
    17711777
     
    17761782
    17771783    pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : "");
    1778 #if defined(VMSVGA3D_OPENGL) && defined(VMSVGA3D_OGL_WITH_SHARED_CTX)
     1784#ifdef VMSVGA3D_OPENGL
    17791785    pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation);
    17801786#else
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h

    r57151 r57152  
    9090*   Defined Constants And Macros                                                                                                 *
    9191*********************************************************************************************************************************/
    92 /** Experimental: Create a dedicated context for handling surfaces in, thus
    93  * avoiding orphaned surfaces after context destruction.
     92#ifdef VMSVGA3D_OPENGL
     93/** OpenGL: Create a dedicated context for handling surfaces in, thus
     94 *          avoiding orphaned surfaces after context destruction.
    9495 *
    9596 * This cures, for instance, an assertion on fedora 21 that happens in
     
    102103 *          switches context when setting up the surface the first time.  Not sure
    103104 *          if we really need to, but as this is an experiment, I'm playing it safe.
    104  */
    105 #ifdef VMSVGA3D_OPENGL
     105 * @remarks The define has been made default, thus should no longer be used.
     106 */
    106107# define VMSVGA3D_OGL_WITH_SHARED_CTX
    107 #endif
    108 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    109108/** Fake surface ID for the shared context. */
    110109# define VMSVGA3D_SHARED_CTX_ID        UINT32_C(0xffffeeee)
    111 #endif
    112 
    113 #ifdef VMSVGA3D_OPENGL
    114110
    115111/** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
     
    507503{
    508504    uint32_t                id;
    509 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     505#ifdef VMSVGA3D_OPENGL
    510506    uint32_t                idWeakContextAssociation;
    511507#else
     
    572568{
    573569    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, id),
    574 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     570# ifdef VMSVGA3D_OPENGL
    575571    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idWeakContextAssociation),
    576572# else
     
    960956    VBOXVMSVGASHADERIF      ShaderIf;
    961957
    962 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     958# ifdef VMSVGA3D_OPENGL
    963959    /** The shared context. */
    964960    VMSVGA3DCONTEXT         SharedCtx;
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp

    r57151 r57152  
    18181818void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
    18191819{
    1820 #if defined(VMSVGA3D_OGL_WITH_SHARED_CTX)
    18211820    PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    18221821    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1823 #else
    1824     /** @todo stricter checks for associated context */
    1825     PVMSVGA3DCONTEXT pContext;
    1826     uint32_t cid = pSurface->idAssociatedContext;
    1827     if (    cid <= pState->cContexts
    1828         &&  pState->papContexts[cid]->id == cid)
    1829     {
    1830         pContext = pState->papContexts[cid];
    1831         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1832     }
    1833     /* If there is a GL buffer or something associated with the surface, we
    1834        really need something here, so pick any active context. */
    1835     else if (pSurface->oglId.buffer != OPENGL_INVALID_ID)
    1836     {
    1837         for (cid = 0; cid < pState->cContexts; cid++)
    1838         {
    1839             if (pState->papContexts[cid]->id == cid)
    1840             {
    1841                 pContext = pState->papContexts[cid];
    1842                 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1843                 break;
    1844             }
    1845         }
    1846         AssertReturn(pContext, VERR_INTERNAL_ERROR); /* otherwise crashes/fails; create temp context if this ever triggers! */
    1847     }
    1848 #endif
    18491822
    18501823    switch (pSurface->flags & VMSVGA3D_SURFACE_HINT_SWITCH_MASK)
     
    20502023{
    20512024    GLint activeTexture = 0;
    2052 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    20532025    uint32_t idPrevCtx = pState->idActiveContext;
    20542026    pContext = &pState->SharedCtx;
    20552027    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2056 #endif
    20572028
    20582029    glGenTextures(1, &pSurface->oglId.texture);
     
    21132084
    21142085    pSurface->flags              |= SVGA3D_SURFACE_HINT_TEXTURE;
    2115 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    2116     LogFlow(("vmsvga3dBackCreateTexture: sid=%x idAssociatedContext %#x -> %#x; oglId.texture=%#x\n",
    2117              pSurface->id, pSurface->idAssociatedContext, idAssociatedContext, pSurface->oglId.texture));
    2118     pSurface->idAssociatedContext = idAssociatedContext;
    2119 #endif
    2120 
    2121 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     2086
    21222087    if (idPrevCtx < pState->cContexts && pState->papContexts[idPrevCtx]->id == idPrevCtx)
    21232088        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pState->papContexts[idPrevCtx]);
    2124 #endif
    21252089    return VINF_SUCCESS;
    21262090}
     
    24802444                glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &cbStrictBufSize);
    24812445                Assert(VMSVGA3D_GL_IS_SUCCESS(pContext));
    2482 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    24832446                AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,
    24842447                          ("cbStrictBufSize=%#x cbSurface=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pContext->id));
    2485 # else
    2486                 AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,
    2487                           ("cbStrictBufSize=%#x cbSurface=%#x isAssociatedContext=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pSurface->idAssociatedContext, pContext->id));
    2488 # endif
    24892448#endif
    24902449
     
    26282587
    26292588    pSurface = pState->papSurfaces[sid];
    2630 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    2631     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
    2632 #endif
    26332589
    26342590    Assert(filter != SVGA3D_TEX_FILTER_FLATCUBIC);
     
    26382594    Log(("vmsvga3dGenerateMipmaps: sid=%x filter=%d\n", sid, filter));
    26392595
    2640 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    26412596    cid = SVGA3D_INVALID_ID;
    26422597    pContext = &pState->SharedCtx;
    26432598    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2644 #else
    2645     /* @todo stricter checks for associated context */
    2646     cid = pSurface->idAssociatedContext;
    2647 
    2648     if (    cid >= pState->cContexts
    2649         ||  pState->papContexts[cid]->id != cid)
    2650     {
    2651         Log(("vmsvga3dGenerateMipmaps invalid context id!\n"));
    2652         return VERR_INVALID_PARAMETER;
    2653     }
    2654     pContext = pState->papContexts[cid];
    2655     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2656 #endif
    26572599
    26582600    if (pSurface->oglId.texture == OPENGL_INVALID_ID)
     
    27002642
    27012643    pSurface = pState->papSurfaces[sid];
    2702 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    2703     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
    2704 #endif
    2705 
    2706 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     2644
    27072645    /* @todo stricter checks for associated context */
    27082646    Log(("vmsvga3dCommandPresent: sid=%x cRects=%d\n", sid, cRects));
     
    27112649
    27122650    pContext = &pState->SharedCtx;
    2713 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_1
    2714     if (   pSurface->idWeakContextAssociation < pState->cContexts
    2715         && pState->papContexts[pSurface->idWeakContextAssociation]->id == pSurface->idWeakContextAssociation)
    2716         pContext = pState->papContexts[pSurface->idWeakContextAssociation];
    2717 # endif
    27182651    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    27192652    cid = pContext->id;
    2720 #else
    2721     /* @todo stricter checks for associated context */
    2722     cid = pSurface->idAssociatedContext;
    2723     Log(("vmsvga3dCommandPresent: sid=%x cRects=%d cid=%x\n", sid, cRects, cid));
    2724     for (uint32_t i=0; i < cRects; i++)
    2725     {
    2726         Log(("vmsvga3dCommandPresent: rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
    2727     }
    2728 
    2729     if (    cid >= pState->cContexts
    2730         ||  pState->papContexts[cid]->id != cid)
    2731     {
    2732         Log(("vmsvga3dCommandPresent invalid context id!\n"));
    2733         return VERR_INVALID_PARAMETER;
    2734     }
    2735     pContext = pState->papContexts[cid];
    2736     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2737 #endif
    27382653    VMSVGA3D_CLEAR_GL_ERRORS();
    27392654
     
    31093024
    31103025    AssertReturn(pState, VERR_NO_MEMORY);
    3111 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    31123026    AssertReturn(   cid < SVGA3D_MAX_CONTEXT_IDS
    31133027                 || (cid == VMSVGA3D_SHARED_CTX_ID && (fFlags & VMSVGA3D_DEF_CTX_F_SHARED_CTX)), VERR_INVALID_PARAMETER);
    3114 #else
    3115     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
    3116 #endif
    31173028#if !defined(VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE) || !(defined(RT_OS_DARWIN))
    31183029    AssertReturn(!(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE), VERR_INTERNAL_ERROR_3);
     
    31293040#endif
    31303041
    3131 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    31323042    if (cid == VMSVGA3D_SHARED_CTX_ID)
    31333043        pContext = &pState->SharedCtx;
    31343044    else
    3135 #endif
    31363045    {
    31373046        if (cid >= pState->cContexts)
     
    31583067
    31593068    /*
    3160      * Find the shared context (necessary for sharing e.g. textures between contexts).
     3069     * Find or create the shared context if needed (necessary for sharing e.g. textures between contexts).
    31613070     */
    3162 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    31633071    PVMSVGA3DCONTEXT pSharedCtx = NULL;
    31643072    if (!(fFlags & (VMSVGA3D_DEF_CTX_F_INIT | VMSVGA3D_DEF_CTX_F_SHARED_CTX)))
     
    31713079        }
    31723080    }
    3173 #else
    3174     // TODO isn't this default on Linux since OpenGL 1.1?
    3175     /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
    3176     PVMSVGA3DCONTEXT pSharedCtx = NULL;
    3177     for (uint32_t i = 0; i < pState->cContexts; i++)
    3178         if (   pState->papContexts[i]->id != SVGA3D_INVALID_ID
    3179             && i != cid
    3180 # ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    3181             && pState->papContexts[i]->fOtherProfile == RT_BOOL(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE)
    3182 # endif
    3183            )
    3184         {
    3185             Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
    3186             pSharedCtx = pState->papContexts[i];
    3187             break;
    3188         }
    3189 #endif
    31903081
    31913082    /*
     
    32893180    NativeNSViewRef          pHostView    = (NativeNSViewRef)pThis->svga.u64HostWindowId;
    32903181    vmsvga3dCocoaCreateViewAndContext(&pContext->cocoaView, &pContext->cocoaContext,
    3291 # if defined(VMSVGA3D_OGL_WITH_SHARED_CTX) && !defined(VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_1) /* Only attach one subview, the one we'll present in. */
    3292                                       pSharedCtx ? NULL : pHostView, /** @todo screen objects and stuff. */
    3293 # else
    3294                                       pHostView,
    3295 # endif
     3182                                      pSharedCtx ? NULL : pHostView, /* Only attach one subview, the one we'll present in. */ /** @todo screen objects and stuff. */
    32963183                                      pThis->svga.uWidth, pThis->svga.uHeight,
    32973184                                      pShareContext, pContext->fOtherProfile);
     
    34473334    }
    34483335
    3449 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX /* This is done on windows - prevents various assertions at runtime, as well as shutdown & reset assertions when destroying surfaces. */
    3450     /* Check for all surfaces that are associated with this context to remove all dependencies */
    3451     for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
    3452     {
    3453         PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    3454         if (    pSurface->idAssociatedContext == cid
    3455             &&  pSurface->id == sid)
    3456         {
    3457             int rc;
    3458 
    3459             Log(("vmsvga3dContextDestroy: remove all dependencies for surface %x\n", sid));
    3460 
    3461             uint32_t            surfaceFlags = pSurface->flags;
    3462             SVGA3dSurfaceFormat format = pSurface->format;
    3463             SVGA3dSurfaceFace   face[SVGA3D_MAX_SURFACE_FACES];
    3464             uint32_t            multisampleCount = pSurface->multiSampleCount;
    3465             SVGA3dTextureFilter autogenFilter = pSurface->autogenFilter;
    3466             SVGA3dSize         *pMipLevelSize;
    3467             uint32_t            cFaces = pSurface->cFaces;
    3468 
    3469             pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(pSurface->faces[0].numMipLevels * pSurface->cFaces * sizeof(SVGA3dSize));
    3470             AssertReturn(pMipLevelSize, VERR_NO_MEMORY);
    3471 
    3472             for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    3473             {
    3474                 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
    3475                 {
    3476                     uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;
    3477                     memcpy(&pMipLevelSize[idx], &pSurface->pMipmapLevels[idx].size, sizeof(SVGA3dSize));
    3478                 }
    3479             }
    3480             memcpy(face, pSurface->faces, sizeof(pSurface->faces));
    3481 
    3482             /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */
    3483             rc = vmsvga3dSurfaceDestroy(pThis, sid);
    3484             AssertRC(rc);
    3485 
    3486             rc = vmsvga3dSurfaceDefine(pThis, sid, surfaceFlags, format, face, multisampleCount, autogenFilter, face[0].numMipLevels * cFaces, pMipLevelSize);
    3487             AssertRC(rc);
    3488         }
    3489     }
    3490 #endif
    3491 
    34923336    if (pContext->idFramebuffer != OPENGL_INVALID_ID)
    34933337    {
     
    35903434    AssertReturn(pState, VERR_NO_MEMORY);
    35913435
    3592 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    35933436    /* Resize the shared context too. */
    35943437    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    35953438        vmsvga3dChangeModeOneContext(pThis, pState, &pState->SharedCtx);
    3596 #endif
    35973439
    35983440    /* Resize all active contexts. */
     
    47544596        {
    47554597            Log(("vmsvga3dSetRenderTarget: create renderbuffer to be used as render target; surface id=%x type=%d format=%d\n", target.sid, pRenderTarget->flags, pRenderTarget->internalFormatGL));
    4756 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    47574598            pContext = &pState->SharedCtx;
    47584599            VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4759 #endif
     4600
    47604601            pState->ext.glGenRenderbuffers(1, &pRenderTarget->oglId.renderbuffer);
    47614602            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     
    47704611            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    47714612
    4772 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    47734613            pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, OPENGL_INVALID_ID);
    47744614            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     
    47764616            pContext = pState->papContexts[cid];
    47774617            VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4778 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_1
    47794618            pRenderTarget->idWeakContextAssociation = cid;
    4780 # endif
    4781 #else
    4782             LogFlow(("vmsvga3dSetRenderTarget: sid=%x idAssociatedContext %#x -> %#x\n", pRenderTarget->id, pRenderTarget->idAssociatedContext, cid));
    4783             pRenderTarget->idAssociatedContext = cid;
    4784 #endif
    4785         }
    4786 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    4787         else
    4788 #endif
    4789         {
    4790             pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
    4791             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4792         }
    4793 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    4794         Assert(pRenderTarget->idAssociatedContext == cid);
    4795 #endif
     4619        }
     4620
     4621        pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
     4622        VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    47964623        Assert(!pRenderTarget->fDirty);
    47974624        AssertReturn(pRenderTarget->oglId.texture != OPENGL_INVALID_ID, VERR_INVALID_PARAMETER);
     
    51314958                if (pSurface->oglId.texture == OPENGL_INVALID_ID)
    51324959                {
    5133 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    5134                     Assert(pSurface->idAssociatedContext == SVGA3D_INVALID_ID);
    5135 #endif
    51364960                    Log(("CreateTexture (%d,%d) level=%d\n", pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height, pSurface->faces[0].numMipLevels));
    51374961                    int rc = vmsvga3dBackCreateTexture(pState, pContext, cid, pSurface);
     
    58835707    {
    58845708        Log(("vmsvga3dDrawPrimitives: create vertex buffer fDirty=%d size=%x bytes\n", pVertexSurface->fDirty, pVertexSurface->pMipmapLevels[0].cbSurface));
    5885 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    58865709        PVMSVGA3DCONTEXT pSavedCtx = pContext;
    58875710        pContext = &pState->SharedCtx;
    58885711        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    5889 #endif
    58905712
    58915713        pState->ext.glGenBuffers(1, &pVertexSurface->oglId.buffer);
     
    59055727        pVertexSurface->flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
    59065728
    5907 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    59085729        pState->ext.glBindBuffer(GL_ARRAY_BUFFER, OPENGL_INVALID_ID);
    59095730        VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     
    59115732        pContext = pSavedCtx;
    59125733        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    5913 #endif
    5914     }
    5915 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    5916     else
    5917 #endif
    5918     {
    5919         Assert(pVertexSurface->fDirty == false);
    5920         pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer);
    5921         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5922     }
    5923 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    5924     pVertexSurface->idAssociatedContext = pContext->id;
    5925     LogFlow(("vmsvga3dDrawPrimitivesProcessVertexDecls: sid=%x idAssociatedContext %#x -> %#x\n", pVertexSurface->id, pVertexSurface->idAssociatedContext, pContext->id));
    5926 #endif
     5734    }
     5735
     5736    Assert(pVertexSurface->fDirty == false);
     5737    pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer);
     5738    VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    59275739
    59285740    /* Setup the vertex declarations. */
     
    62016013            {
    62026014                Log(("vmsvga3dDrawPrimitives: create index buffer fDirty=%d size=%x bytes\n", pIndexSurface->fDirty, pIndexSurface->pMipmapLevels[0].cbSurface));
    6203 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    62046015                pContext = &pState->SharedCtx;
    62056016                VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6206 #endif
    62076017
    62086018                pState->ext.glGenBuffers(1, &pIndexSurface->oglId.buffer);
     
    62236033                pIndexSurface->flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
    62246034
    6225 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    62266035                pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OPENGL_INVALID_ID);
    62276036                VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     
    62296038                pContext = pState->papContexts[cid];
    62306039                VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6231 #endif
    62326040            }
    6233 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    6234             else
    6235 #endif
    6236             {
    6237                 Assert(pIndexSurface->fDirty == false);
    6238 
    6239                 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer);
    6240                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6241             }
    6242 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    6243             LogFlow(("vmsvga3dDrawPrimitives: sid=%x idAssociatedContext %#x -> %#x\n", pIndexSurface->id, pIndexSurface->idAssociatedContext, pContext->id));
    6244             pIndexSurface->idAssociatedContext = pContext->id;
    6245 #endif
     6041            Assert(pIndexSurface->fDirty == false);
     6042
     6043            pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer);
     6044            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    62466045        }
    62476046
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp

    r57151 r57152  
    184184            LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));
    185185
    186 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     186#ifdef VMSVGA3D_OPENGL
    187187            if (cid == VMSVGA3D_SHARED_CTX_ID)
    188188            {
     
    311311    }
    312312
    313 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     313#ifdef VMSVGA3D_OPENGL
    314314    /* Make the shared context the current one. */
    315315    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
     
    399399    }
    400400
    401 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     401#ifdef VMSVGA3D_OPENGL
    402402    /* Reinitialize the shared context. */
    403403    LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
     
    514514    AssertRCReturn(rc, rc);
    515515
    516 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     516#ifdef VMSVGA3D_OPENGL
    517517    /* Save the shared context. */
    518518    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
     
    745745                        void *pData = NULL;
    746746
    747 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    748747                        PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    749748                        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    750 # else
    751                         /* @todo stricter checks for associated context */
    752                         uint32_t cid = pSurface->idAssociatedContext;
    753                         if (    cid >= pState->cContexts
    754                             ||  pState->papContexts[cid]->id != cid)
    755                         {
    756                             Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    757                             AssertFailedReturn(VERR_INVALID_PARAMETER);
    758                         }
    759                         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    760                         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    761 # endif
    762749
    763750                        Assert(pMipmapLevel->cbSurface);
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp

    r57151 r57152  
    9797    RT_ZERO(*pSurface);
    9898    pSurface->id                    = sid;
    99 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     99#ifdef VMSVGA3D_OPENGL
    100100    pSurface->idWeakContextAssociation = SVGA3D_INVALID_ID;
    101101#else
     
    368368
    369369    PVMSVGA3DCONTEXT pContext;
    370 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     370#ifdef VMSVGA3D_OPENGL
    371371    Log(("vmsvga3dSurfaceStretchBlt: src sid=%x (%d,%d)(%d,%d) dest sid=%x (%d,%d)(%d,%d) mode=%x\n",
    372372         sidSrc, pSrcBox->x, pSrcBox->y, pSrcBox->x + pSrcBox->w, pSrcBox->y + pSrcBox->h,
     
    391391    }
    392392    pContext = pState->papContexts[cid];
    393 # ifdef VMSVGA3D_OPENGL
    394     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    395 # endif
    396393#endif
    397394
     
    534531
    535532#else /* VMSVGA3D_OPENGL */
    536 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    537533        PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    538 # else
    539         /** @todo stricter checks for associated context */
    540         uint32_t cid = pSurface->idAssociatedContext;
    541         if (    cid >= pState->cContexts
    542             ||  pState->papContexts[cid]->id != cid)
    543         {
    544             Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    545             AssertFailedReturn(VERR_INVALID_PARAMETER);
    546         }
    547         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    548 # endif
    549534        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    550535#endif
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette