VirtualBox

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


Ignore:
Timestamp:
Aug 1, 2015 8:18:07 PM (9 years ago)
Author:
vboxsync
Message:

VMSVGA3d: Combining OGL and D3D backend structures and moving associated defines into an DevVGA-SVGA3d-internal.h header file so that it's possible to split up code and write common code without requiring it to be #include'ed. DevVGA-SVGA3d-shared.h got split into DevVGA-SVGA3d-info.cpp and DevVGA-SVGA3d-savedstate.cpp, with a bunch of info related stuff moved from DevVGA-SVGA3d-shared.cpp and into the former.

Location:
trunk/src/VBox/Devices
Files:
6 edited
2 copied
1 moved

Legend:

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

    r57135 r57149  
    32483248
    32493249                    case SVGA_3D_CMD_PRESENT:
     3250                    case SVGA_3D_CMD_PRESENT_READBACK: /** @todo SVGA_3D_CMD_PRESENT_READBACK isn't quite the same as present... */
    32503251                    {
    32513252                        SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)(pHdr + 1);
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp

    r57148 r57149  
    11/* $Id$ */
    22/** @file
    3  * DevVMWare - VMWare SVGA device, shared part.
    4  *
    5  * @remarks This is code that's very similar on both for OpenGL and D3D
    6  *          backends, so instead of moving backend specific structures
    7  *          into header files with #ifdefs and stuff, we just include
    8  *          the code into the backend implementation source file.
     3 * DevSVGA3d - VMWare SVGA device, 3D parts - Introspection and debugging.
    94 */
    105
     
    2116 */
    2217
    23 #ifndef ___DevVGA_SVGA3d_shared_h___
    24 #define ___DevVGA_SVGA3d_shared_h___
     18
     19/*******************************************************************************
     20*   Header Files                                                               *
     21*******************************************************************************/
     22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
     23#include <VBox/vmm/pdmdev.h>
     24#include <VBox/err.h>
     25#include <VBox/log.h>
     26
     27#include <iprt/assert.h>
     28#include <iprt/mem.h>
     29
     30#include <VBox/vmm/pgm.h> /* required by DevVGA.h */
     31#include <VBox/VBoxVideo.h> /* required by DevVGA.h */
     32
     33/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
     34#include "DevVGA.h"
     35
     36#include "DevVGA-SVGA.h"
     37#include "DevVGA-SVGA3d.h"
     38#define VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
     39#include "DevVGA-SVGA3d-internal.h"
     40
    2541
    2642/**
     
    329345
    330346
     347
     348
     349void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)
     350{
     351    for (uint32_t i = 0; i < cFlags; i++)
     352        if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)
     353        {
     354            Assert(paFlags[i].fFlags);
     355            pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);
     356            fFlags &= ~paFlags[i].fFlags;
     357            if (!fFlags)
     358                return;
     359        }
     360    if (fFlags)
     361        pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);
     362}
     363
     364
    331365/**
    332  * Reinitializes an active context.
     366 * Worker for vmsvgaR3Info that display details of a host window.
    333367 *
    334  * @returns VBox status code.
    335  * @param   pThis               The VMSVGA device state.
    336  * @param   pContext            The freshly loaded context to reinitialize.
     368 * @param   pHlp            The output methods.
     369 * @param   idHostWindow    The host window handle/id/whatever.
    337370 */
    338 static int vmsvga3dLoadReinitContext(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext)
    339 {
    340     int      rc;
    341     uint32_t cid = pContext->id;
    342     Assert(cid != SVGA3D_INVALID_ID);
    343 
    344     /* First set the render targets as they change the internal state (reset viewport etc) */
    345     Log(("vmsvga3dLoadReinitContext: Recreate render targets BEGIN [cid=%#x]\n", cid));
    346     for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aRenderTargets); j++)
     371void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)
     372{
     373#ifdef RT_OS_WINDOWS
     374    HWND hwnd = (HWND)(uintptr_t)idHostWindow;
     375    Assert((uintptr_t)hwnd == idHostWindow);
     376    if (hwnd != NULL)
    347377    {
    348         if (pContext->state.aRenderTargets[j] != SVGA3D_INVALID_ID)
    349         {
    350             SVGA3dSurfaceImageId target;
    351 
    352             target.sid      = pContext->state.aRenderTargets[j];
    353             target.face     = 0;
    354             target.mipmap   = 0;
    355             rc = vmsvga3dSetRenderTarget(pThis, cid, (SVGA3dRenderTargetType)j, target);
    356             AssertRCReturn(rc, rc);
    357         }
     378        WINDOWINFO Info;
     379        RT_ZERO(Info);
     380        Info.cbSize = sizeof(Info);
     381        if (GetWindowInfo(hwnd, &Info))
     382        {
     383            pHlp->pfnPrintf(pHlp, "     Window rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
     384                            Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,
     385                            Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);
     386            pHlp->pfnPrintf(pHlp, "     Client rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
     387                            Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,
     388                            Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);
     389            pHlp->pfnPrintf(pHlp, "     Style:         %#x", Info.dwStyle);
     390            static const VMSVGAINFOFLAGS32 g_aStyles[] =
     391            {
     392                { WS_POPUP        , "POPUP" },
     393                { WS_CHILD        , "CHILD" },
     394                { WS_MINIMIZE     , "MINIMIZE" },
     395                { WS_VISIBLE      , "VISIBLE" },
     396                { WS_DISABLED     , "DISABLED" },
     397                { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },
     398                { WS_CLIPCHILDREN , "CLIPCHILDREN" },
     399                { WS_MAXIMIZE     , "MAXIMIZE" },
     400                { WS_BORDER       , "BORDER" },
     401                { WS_DLGFRAME     , "DLGFRAME" },
     402                { WS_VSCROLL      , "VSCROLL" },
     403                { WS_HSCROLL      , "HSCROLL" },
     404                { WS_SYSMENU      , "SYSMENU" },
     405                { WS_THICKFRAME   , "THICKFRAME" },
     406                { WS_GROUP        , "GROUP" },
     407                { WS_TABSTOP      , "TABSTOP" },
     408            };
     409            vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));
     410            pHlp->pfnPrintf(pHlp, "\n");
     411
     412            pHlp->pfnPrintf(pHlp, "     ExStyle:       %#x", Info.dwExStyle);
     413            static const VMSVGAINFOFLAGS32 g_aExStyles[] =
     414            {
     415                { WS_EX_DLGMODALFRAME,   "DLGMODALFRAME" },
     416                { 0x00000002,            "DRAGDETECT" },
     417                { WS_EX_NOPARENTNOTIFY,  "NOPARENTNOTIFY" },
     418                { WS_EX_TOPMOST,         "TOPMOST" },
     419                { WS_EX_ACCEPTFILES,     "ACCEPTFILES" },
     420                { WS_EX_TRANSPARENT,     "TRANSPARENT" },
     421                { WS_EX_MDICHILD,        "MDICHILD" },
     422                { WS_EX_TOOLWINDOW,      "TOOLWINDOW" },
     423                { WS_EX_WINDOWEDGE,      "WINDOWEDGE" },
     424                { WS_EX_CLIENTEDGE,      "CLIENTEDGE" },
     425                { WS_EX_CONTEXTHELP,     "CONTEXTHELP" },
     426                { WS_EX_RIGHT,           "RIGHT" },
     427                /*{ WS_EX_LEFT,            "LEFT" }, = 0 */
     428                { WS_EX_RTLREADING,      "RTLREADING" },
     429                /*{ WS_EX_LTRREADING,      "LTRREADING" }, = 0 */
     430                { WS_EX_LEFTSCROLLBAR,   "LEFTSCROLLBAR" },
     431                /*{ WS_EX_RIGHTSCROLLBAR,  "RIGHTSCROLLBAR" }, = 0 */
     432                { WS_EX_CONTROLPARENT,   "CONTROLPARENT" },
     433                { WS_EX_STATICEDGE,      "STATICEDGE" },
     434                { WS_EX_APPWINDOW,       "APPWINDOW" },
     435                { WS_EX_LAYERED,         "LAYERED" },
     436                { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },
     437                { WS_EX_LAYOUTRTL,       "LAYOUTRTL" },
     438                { WS_EX_COMPOSITED,      "COMPOSITED" },
     439                { WS_EX_NOACTIVATE,      "NOACTIVATE" },
     440            };
     441            vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));
     442            pHlp->pfnPrintf(pHlp, "\n");
     443
     444            pHlp->pfnPrintf(pHlp, "     Window Status: %#x\n", Info.dwWindowStatus);
     445            if (Info.cxWindowBorders || Info.cyWindowBorders)
     446                pHlp->pfnPrintf(pHlp, "     Borders:       cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);
     447            pHlp->pfnPrintf(pHlp, "     Window Type:   %#x\n", Info.atomWindowType);
     448            pHlp->pfnPrintf(pHlp, "     Creator Ver:   %#x\n", Info.wCreatorVersion);
     449        }
     450        else
     451            pHlp->pfnPrintf(pHlp, "     GetWindowInfo: last error %d\n", GetLastError());
    358452    }
    359     Log(("vmsvga3dLoadReinitContext: Recreate render targets END\n"));
    360 
    361     /* Recreate the render state */
    362     Log(("vmsvga3dLoadReinitContext: Recreate render state BEGIN\n"));
    363     for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aRenderState); j++)
     453#else
     454    pHlp->pfnPrintf(pHlp, "    Windows info:   Not implemented on this platform\n");
     455#endif
     456
     457}
     458
     459
     460/**
     461 * Looks up an enum value in a translation table.
     462 *
     463 * @returns The value name.
     464 * @param   iValue              The value to name.
     465 * @param   pEnumMap            Enum value to string mapping.
     466 */
     467const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)
     468{
     469    PCVMSVGAINFOENUM paValues = pEnumMap->paValues;
     470
     471#ifdef VBOX_STRICT
     472    /*
     473     * Check that it's really sorted, or the binary lookup won't work right.
     474     */
     475    if (!*pEnumMap->pfAsserted)
    364476    {
    365         SVGA3dRenderState *pRenderState = &pContext->state.aRenderState[j];
    366 
    367         if (pRenderState->state != SVGA3D_RS_INVALID)
    368             vmsvga3dSetRenderState(pThis, pContext->id, 1, pRenderState);
    369     }
    370     Log(("vmsvga3dLoadReinitContext: Recreate render state END\n"));
    371 
    372     /* Recreate the texture state */
    373     Log(("vmsvga3dLoadReinitContext: Recreate texture state BEGIN\n"));
    374     for (uint32_t iStage = 0; iStage < SVGA3D_MAX_TEXTURE_STAGE; iStage++)
    375     {
    376         for (uint32_t j = 0; j < SVGA3D_TS_MAX; j++)
    377         {
    378             SVGA3dTextureState *pTextureState = &pContext->state.aTextureState[iStage][j];
    379 
    380             if (pTextureState->name != SVGA3D_TS_INVALID)
    381                 vmsvga3dSetTextureState(pThis, pContext->id, 1, pTextureState);
    382         }
    383     }
    384     Log(("vmsvga3dLoadReinitContext: Recreate texture state END\n"));
    385 
    386     /* Reprogram the clip planes. */
    387     for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aClipPlane); j++)
    388     {
    389         if (pContext->state.aClipPlane[j].fValid == true)
    390             vmsvga3dSetClipPlane(pThis, cid, j, pContext->state.aClipPlane[j].plane);
    391     }
    392 
    393     /* Reprogram the light data. */
    394     for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aLightData); j++)
    395     {
    396         if (pContext->state.aLightData[j].fValidData == true)
    397             vmsvga3dSetLightData(pThis, cid, j, &pContext->state.aLightData[j].data);
    398         if (pContext->state.aLightData[j].fEnabled)
    399             vmsvga3dSetLightEnabled(pThis, cid, j, true);
    400     }
    401 
    402     /* Recreate the transform state. */
    403     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_TRANSFORM)
    404     {
    405         for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState); j++)
    406         {
    407             if (pContext->state.aTransformState[j].fValid == true)
    408                 vmsvga3dSetTransform(pThis, cid, (SVGA3dTransformType)j, pContext->state.aTransformState[j].matrix);
    409         }
    410     }
    411 
    412     /* Reprogram the material data. */
    413     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_MATERIAL)
    414     {
    415         for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aMaterial); j++)
    416         {
    417             if (pContext->state.aMaterial[j].fValid == true)
    418                 vmsvga3dSetMaterial(pThis, cid, (SVGA3dFace)j, &pContext->state.aMaterial[j].material);
    419         }
    420     }
    421 
    422     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_SCISSORRECT)
    423         vmsvga3dSetScissorRect(pThis, cid, &pContext->state.RectScissor);
    424     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_ZRANGE)
    425         vmsvga3dSetZRange(pThis, cid, pContext->state.zRange);
    426     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VIEWPORT)
    427         vmsvga3dSetViewPort(pThis, cid, &pContext->state.RectViewPort);
    428     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VERTEXSHADER)
    429         vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, pContext->state.shidVertex);
    430     if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_PIXELSHADER)
    431         vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, pContext->state.shidPixel);
    432 
    433     Log(("vmsvga3dLoadReinitContext: returns [cid=%#x]\n", cid));
    434     return VINF_SUCCESS;
    435 }
    436 
    437 int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    438 {
    439     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    440     AssertReturn(pState, VERR_NO_MEMORY);
    441     int            rc;
    442     uint32_t       cContexts, cSurfaces;
    443     LogFlow(("vmsvga3dLoadExec:\n"));
    444 
    445 #ifndef RT_OS_DARWIN /** @todo r=bird: this is normally done on the EMT, so for DARWIN we do that when loading saved state too now. See DevVGA-SVGA.cpp */
    446     /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
    447     vmsvga3dPowerOn(pThis);
    448 #endif
    449 
    450     /* Get the generic 3d state first. */
    451     rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
    452     AssertRCReturn(rc, rc);
    453 
    454     cContexts                           = pState->cContexts;
    455     cSurfaces                           = pState->cSurfaces;
    456     pState->cContexts                   = 0;
    457     pState->cSurfaces                   = 0;
    458 
    459     /* Fetch all active contexts. */
    460     for (uint32_t i = 0; i < cContexts; i++)
    461     {
    462         PVMSVGA3DCONTEXT pContext;
    463         uint32_t         cid;
    464 
    465         /* Get the context id */
    466         rc = SSMR3GetU32(pSSM, &cid);
    467         AssertRCReturn(rc, rc);
    468 
    469         if (cid != SVGA3D_INVALID_ID)
    470         {
    471             uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
    472             LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));
    473 
    474 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    475             if (cid == VMSVGA3D_SHARED_CTX_ID)
    476             {
    477                 i--; /* Not included in cContexts. */
    478                 pContext = &pState->SharedCtx;
    479                 if (pContext->id != VMSVGA3D_SHARED_CTX_ID)
    480                 {
    481                     rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
    482                     AssertRCReturn(rc, rc);
    483                 }
    484             }
    485             else
    486 #endif
    487             {
    488                 rc = vmsvga3dContextDefine(pThis, cid);
    489                 AssertRCReturn(rc, rc);
    490 
    491                 pContext = pState->papContexts[i];
    492             }
    493             AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);
    494 
    495             rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
    496             AssertRCReturn(rc, rc);
    497 
    498             cPixelShaders                       = pContext->cPixelShaders;
    499             cVertexShaders                      = pContext->cVertexShaders;
    500             cPixelShaderConst                   = pContext->state.cPixelShaderConst;
    501             cVertexShaderConst                  = pContext->state.cVertexShaderConst;
    502             pContext->cPixelShaders             = 0;
    503             pContext->cVertexShaders            = 0;
    504             pContext->state.cPixelShaderConst   = 0;
    505             pContext->state.cVertexShaderConst  = 0;
    506 
    507             /* Fetch all pixel shaders. */
    508             for (uint32_t j = 0; j < cPixelShaders; j++)
    509             {
    510                 VMSVGA3DSHADER  shader;
    511                 uint32_t        shid;
    512 
    513                 /* Fetch the id first. */
    514                 rc = SSMR3GetU32(pSSM, &shid);
    515                 AssertRCReturn(rc, rc);
    516 
    517                 if (shid != SVGA3D_INVALID_ID)
    518                 {
    519                     uint32_t *pData;
    520 
    521                     /* Fetch a copy of the shader struct. */
    522                     rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
    523                     AssertRCReturn(rc, rc);
    524 
    525                     pData = (uint32_t *)RTMemAlloc(shader.cbData);
    526                     AssertReturn(pData, VERR_NO_MEMORY);
    527 
    528                     rc = SSMR3GetMem(pSSM, pData, shader.cbData);
    529                     AssertRCReturn(rc, rc);
    530 
    531                     rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
    532                     AssertRCReturn(rc, rc);
    533 
    534                     RTMemFree(pData);
    535                 }
    536             }
    537 
    538             /* Fetch all vertex shaders. */
    539             for (uint32_t j = 0; j < cVertexShaders; j++)
    540             {
    541                 VMSVGA3DSHADER  shader;
    542                 uint32_t        shid;
    543 
    544                 /* Fetch the id first. */
    545                 rc = SSMR3GetU32(pSSM, &shid);
    546                 AssertRCReturn(rc, rc);
    547 
    548                 if (shid != SVGA3D_INVALID_ID)
    549                 {
    550                     uint32_t *pData;
    551 
    552                     /* Fetch a copy of the shader struct. */
    553                     rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
    554                     AssertRCReturn(rc, rc);
    555 
    556                     pData = (uint32_t *)RTMemAlloc(shader.cbData);
    557                     AssertReturn(pData, VERR_NO_MEMORY);
    558 
    559                     rc = SSMR3GetMem(pSSM, pData, shader.cbData);
    560                     AssertRCReturn(rc, rc);
    561 
    562                     rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
    563                     AssertRCReturn(rc, rc);
    564 
    565                     RTMemFree(pData);
    566                 }
    567             }
    568 
    569             /* Fetch pixel shader constants. */
    570             for (uint32_t j = 0; j < cPixelShaderConst; j++)
    571             {
    572                 VMSVGASHADERCONST ShaderConst;
    573 
    574                 rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
    575                 AssertRCReturn(rc, rc);
    576 
    577                 if (ShaderConst.fValid)
    578                 {
    579                     rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
    580                     AssertRCReturn(rc, rc);
    581                 }
    582             }
    583 
    584             /* Fetch vertex shader constants. */
    585             for (uint32_t j = 0; j < cVertexShaderConst; j++)
    586             {
    587                 VMSVGASHADERCONST ShaderConst;
    588 
    589                 rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
    590                 AssertRCReturn(rc, rc);
    591 
    592                 if (ShaderConst.fValid)
    593                 {
    594                     rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
    595                     AssertRCReturn(rc, rc);
    596                 }
    597             }
    598         }
    599     }
    600 
    601 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    602     /* Make the shared context the current one. */
    603     if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    604         VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
    605 #endif
    606 
    607     /* Fetch all surfaces. */
    608     for (uint32_t i = 0; i < cSurfaces; i++)
    609     {
    610         uint32_t sid;
    611 
    612         /* Fetch the id first. */
    613         rc = SSMR3GetU32(pSSM, &sid);
    614         AssertRCReturn(rc, rc);
    615 
    616         if (sid != SVGA3D_INVALID_ID)
    617         {
    618             VMSVGA3DSURFACE  surface;
    619             LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));
    620 
    621             /* Fetch the surface structure first. */
    622             rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
    623             AssertRCReturn(rc, rc);
    624 
    625             {
    626                 uint32_t             cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
    627                 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
    628                 AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
    629                 SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
    630                 AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);
    631 
    632                 /* Load the mip map level info. */
    633                 for (uint32_t face=0; face < surface.cFaces; face++)
    634                 {
    635                     for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
    636                     {
    637                         uint32_t idx = j + face * surface.faces[0].numMipLevels;
    638                         /* Load the mip map level struct. */
    639                         rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
    640                         AssertRCReturn(rc, rc);
    641 
    642                         pMipmapLevelSize[idx] = pMipmapLevel[idx].size;
    643                     }
    644                 }
    645 
    646                 rc = vmsvga3dSurfaceDefine(pThis, sid, surface.flags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
    647                 AssertRCReturn(rc, rc);
    648 
    649                 RTMemFree(pMipmapLevelSize);
    650                 RTMemFree(pMipmapLevel);
    651             }
    652 
    653             PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    654             Assert(pSurface->id == sid);
    655 
    656             pSurface->fDirty = false;
    657 
    658             /* Load the mip map level data. */
    659             for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
    660             {
    661                 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
    662                 bool fDataPresent = false;
    663 
    664                 Assert(pMipmapLevel->cbSurface);
    665                 pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface);
    666                 AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);
    667 
    668                 /* Fetch the data present boolean first. */
    669                 rc = SSMR3GetBool(pSSM, &fDataPresent);
    670                 AssertRCReturn(rc, rc);
    671 
    672                 Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));
    673 
    674                 if (fDataPresent)
    675                 {
    676                     rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
    677                     AssertRCReturn(rc, rc);
    678                     pMipmapLevel->fDirty = true;
    679                     pSurface->fDirty     = true;
    680                 }
    681                 else
    682                 {
    683                     pMipmapLevel->fDirty = false;
    684                 }
    685             }
    686         }
    687     }
    688 
    689 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    690     /* Reinitialize the shared context. */
    691     LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
    692     if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    693     {
    694         rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
    695         AssertRCReturn(rc, rc);
     477        *pEnumMap->pfAsserted = true;
     478        for (uint32_t i = 1; i < pEnumMap->cValues; i++)
     479            Assert(paValues[i - 1].iValue <= paValues[i].iValue);
    696480    }
    697481#endif
    698482
    699     /* Reinitialize all active contexts. */
    700     for (uint32_t i = 0; i < pState->cContexts; i++)
     483    /*
     484     * Binary search
     485     */
     486    uint32_t iStart = 0;
     487    uint32_t iEnd   = (uint32_t)pEnumMap->cValues;
     488    for (;;)
    701489    {
    702         PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
    703         if (pContext->id != SVGA3D_INVALID_ID)
    704         {
    705             rc = vmsvga3dLoadReinitContext(pThis, pContext);
    706             AssertRCReturn(rc, rc);
    707         }
     490        uint32_t i = iStart + (iEnd - iStart) / 2;
     491        if (iValue < paValues[i].iValue)
     492        {
     493            if (i > iStart)
     494                iEnd = i;
     495            else
     496                break;
     497        }
     498        else if (iValue > paValues[i].iValue)
     499        {
     500            i++;
     501            if (i < iEnd)
     502                iStart = i;
     503            else
     504                break;
     505        }
     506        else
     507            return paValues[i].pszName;
    708508    }
    709 
    710     LogFlow(("vmsvga3dLoadExec: return success\n"));
    711     return VINF_SUCCESS;
     509    return NULL;
    712510}
    713511
    714512
    715 static int vmsvga3dSaveContext(PVGASTATE pThis, PSSMHANDLE pSSM, PVMSVGA3DCONTEXT pContext)
    716 {
    717     uint32_t cid = pContext->id;
    718 
    719     /* Save the id first. */
    720     int rc = SSMR3PutU32(pSSM, cid);
    721     AssertRCReturn(rc, rc);
    722 
    723     if (cid != SVGA3D_INVALID_ID)
     513/**
     514 * Formats an enum value as a string, sparse mapping table.
     515 *
     516 * @returns pszBuffer.
     517 * @param   pszBuffer           The output buffer.
     518 * @param   cbBuffer            The size of the output buffer.
     519 * @param   pszName             The variable name, optional.
     520 * @param   iValue              The enum value.
     521 * @param   fPrefix             Whether to prepend the prefix or not.
     522 * @param   pEnumMap            Enum value to string mapping.
     523 */
     524char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
     525                              bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)
     526{
     527    const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);
     528    const char *pszPrefix    = fPrefix ? pEnumMap->pszPrefix : "";
     529    if (pszValueName)
    724530    {
    725         /* Save a copy of the context structure first. */
    726         rc = SSMR3PutStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
    727         AssertRCReturn(rc, rc);
    728 
    729         /* Save all pixel shaders. */
    730         for (uint32_t j = 0; j < pContext->cPixelShaders; j++)
    731         {
    732             PVMSVGA3DSHADER pShader = &pContext->paPixelShader[j];
    733 
    734             /* Save the id first. */
    735             rc = SSMR3PutU32(pSSM, pShader->id);
    736             AssertRCReturn(rc, rc);
    737 
    738             if (pShader->id != SVGA3D_INVALID_ID)
    739             {
    740                 uint32_t cbData = pShader->cbData;
    741 
    742                 /* Save a copy of the shader struct. */
    743                 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
    744                 AssertRCReturn(rc, rc);
    745 
    746                 Log(("Save pixelshader shid=%d with %x bytes code.\n", pShader->id, cbData));
    747                 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
    748                 AssertRCReturn(rc, rc);
    749             }
    750         }
    751 
    752         /* Save all vertex shaders. */
    753         for (uint32_t j = 0; j < pContext->cVertexShaders; j++)
    754         {
    755             PVMSVGA3DSHADER pShader = &pContext->paVertexShader[j];
    756 
    757             /* Save the id first. */
    758             rc = SSMR3PutU32(pSSM, pShader->id);
    759             AssertRCReturn(rc, rc);
    760 
    761             if (pShader->id != SVGA3D_INVALID_ID)
    762             {
    763                 uint32_t cbData = pShader->cbData;
    764 
    765                 /* Save a copy of the shader struct. */
    766                 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
    767                 AssertRCReturn(rc, rc);
    768 
    769                 Log(("Save vertex shader shid=%d with %x bytes code.\n", pShader->id, cbData));
    770                 /* Fetch the shader code and save it. */
    771                 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
    772                 AssertRCReturn(rc, rc);
    773             }
    774         }
    775 
    776         /* Save pixel shader constants. */
    777         for (uint32_t j = 0; j < pContext->state.cPixelShaderConst; j++)
    778         {
    779             rc = SSMR3PutStructEx(pSSM, &pContext->state.paPixelShaderConst[j], sizeof(pContext->state.paPixelShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
    780             AssertRCReturn(rc, rc);
    781         }
    782 
    783         /* Save vertex shader constants. */
    784         for (uint32_t j = 0; j < pContext->state.cVertexShaderConst; j++)
    785         {
    786             rc = SSMR3PutStructEx(pSSM, &pContext->state.paVertexShaderConst[j], sizeof(pContext->state.paVertexShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
    787             AssertRCReturn(rc, rc);
    788         }
     531        if (pszName)
     532            RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);
     533        else
     534            RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);
     535        return pszBuffer;
    789536    }
    790537
    791     return VINF_SUCCESS;
     538    if (pszName)
     539        RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
     540    else
     541        RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
     542    return pszBuffer;
    792543}
    793544
    794 int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
    795 {
    796     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    797     AssertReturn(pState, VERR_NO_MEMORY);
    798     int            rc;
    799 
    800     /* Save a copy of the generic 3d state first. */
    801     rc = SSMR3PutStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
    802     AssertRCReturn(rc, rc);
    803 
    804 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    805     /* Save the shared context. */
    806     if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
     545
     546/**
     547 * Formats an enum value as a string.
     548 *
     549 * @returns pszBuffer.
     550 * @param   pszBuffer           The output buffer.
     551 * @param   cbBuffer            The size of the output buffer.
     552 * @param   pszName             The variable name, optional.
     553 * @param   uValue              The enum value.
     554 * @param   pszPrefix           The prefix of the enum values.  Empty string if
     555 *                              none.  This helps reduce the memory footprint
     556 *                              as well as the source code size.
     557 * @param   papszValues         One to one string mapping of the enum values.
     558 * @param   cValues             The number of values in the mapping.
     559 */
     560char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
     561                            const char *pszPrefix, const char * const *papszValues, size_t cValues)
     562{
     563    if (uValue < cValues)
    807564    {
    808         rc = vmsvga3dSaveContext(pThis, pSSM, &pState->SharedCtx);
    809         AssertRCReturn(rc, rc);
    810     }
    811 #endif
    812 
    813     /* Save all active contexts. */
    814     for (uint32_t i = 0; i < pState->cContexts; i++)
    815     {
    816         rc = vmsvga3dSaveContext(pThis, pSSM, pState->papContexts[i]);
    817         AssertRCReturn(rc, rc);
    818     }
    819 
    820     /* Save all active surfaces. */
    821     for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
    822     {
    823         PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    824 
    825         /* Save the id first. */
    826         rc = SSMR3PutU32(pSSM, pSurface->id);
    827         AssertRCReturn(rc, rc);
    828 
    829         if (pSurface->id != SVGA3D_INVALID_ID)
    830         {
    831             /* Save a copy of the surface structure first. */
    832             rc = SSMR3PutStructEx(pSSM, pSurface, sizeof(*pSurface), 0, g_aVMSVGA3DSURFACEFields, NULL);
    833             AssertRCReturn(rc, rc);
    834 
    835             /* Save the mip map level info. */
    836             for (uint32_t face=0; face < pSurface->cFaces; face++)
    837             {
    838                 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
    839                 {
    840                     uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
    841                     PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
    842 
    843                     /* Save a copy of the mip map level struct. */
    844                     rc = SSMR3PutStructEx(pSSM, pMipmapLevel, sizeof(*pMipmapLevel), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
    845                     AssertRCReturn(rc, rc);
    846                 }
    847             }
    848 
    849             /* Save the mip map level data. */
    850             for (uint32_t face=0; face < pSurface->cFaces; face++)
    851             {
    852                 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
    853                 {
    854                     uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
    855                     PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
    856 
    857                     Log(("Surface sid=%d: save mipmap level %d with %x bytes data.\n", sid, i, pMipmapLevel->cbSurface));
    858 
    859 #ifdef VMSVGA3D_DIRECT3D
    860                     if (!pSurface->u.pSurface)
    861 #else
    862                     if (pSurface->oglId.texture == OPENGL_INVALID_ID)
    863 #endif
    864                     {
    865                         if (pMipmapLevel->fDirty)
    866                         {
    867                             /* Data follows */
    868                             rc = SSMR3PutBool(pSSM, true);
    869                             AssertRCReturn(rc, rc);
    870 
    871                             Assert(pMipmapLevel->cbSurface);
    872                             rc = SSMR3PutMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
    873                             AssertRCReturn(rc, rc);
    874                         }
    875                         else
    876                         {
    877                             /* No data follows */
    878                             rc = SSMR3PutBool(pSSM, false);
    879                             AssertRCReturn(rc, rc);
    880                         }
    881                     }
    882                     else
    883                     {
    884 #ifdef VMSVGA3D_DIRECT3D
    885                         void            *pData;
    886                         bool             fRenderTargetTexture = false;
    887                         bool             fTexture = false;
    888                         bool             fVertex = false;
    889                         bool             fSkipSave = false;
    890                         HRESULT          hr;
    891 
    892                         Assert(pMipmapLevel->cbSurface);
    893                         pData = RTMemAllocZ(pMipmapLevel->cbSurface);
    894                         AssertReturn(pData, VERR_NO_MEMORY);
    895 
    896                         switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
    897                         {
    898                         case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
    899                         case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
    900                             /* @todo unable to easily fetch depth surface data in d3d 9 */
    901                             fSkipSave = true;
    902                             break;
    903                         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    904                             fRenderTargetTexture = true;
    905                             /* no break */
    906                         case SVGA3D_SURFACE_HINT_TEXTURE:
    907                             fTexture = true;
    908                             /* no break */
    909                         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    910                         {
    911                             D3DLOCKED_RECT LockedRect;
    912 
    913                             if (fTexture)
    914                             {
    915                                 if (pSurface->bounce.pTexture)
    916                                 {
    917                                     if (    !pSurface->fDirty
    918                                         &&  fRenderTargetTexture
    919                                         &&  i == 0 /* only the first time */)
    920                                     {
    921                                         IDirect3DSurface9 *pSrc, *pDest;
    922 
    923                                         /* @todo stricter checks for associated context */
    924                                         uint32_t cid = pSurface->idAssociatedContext;
    925                                         if (    cid >= pState->cContexts
    926                                             ||  pState->papContexts[cid]->id != cid)
    927                                         {
    928                                             Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    929                                             AssertFailedReturn(VERR_INVALID_PARAMETER);
    930                                         }
    931                                         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    932 
    933                                         hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDest);
    934                                         AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
    935 
    936                                         hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
    937                                         AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
    938 
    939                                         hr = pContext->pDevice->GetRenderTargetData(pSrc, pDest);
    940                                         AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetRenderTargetData failed with %x\n", hr), VERR_INTERNAL_ERROR);
    941 
    942                                         pSrc->Release();
    943                                         pDest->Release();
    944                                     }
    945 
    946                                     hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
    947                                                                              &LockedRect,
    948                                                                              NULL,
    949                                                                              D3DLOCK_READONLY);
    950                                 }
    951                                 else
    952                                     hr = pSurface->u.pTexture->LockRect(i, /* texture level */
    953                                                                         &LockedRect,
    954                                                                         NULL,
    955                                                                         D3DLOCK_READONLY);
    956                             }
    957                             else
    958                                 hr = pSurface->u.pSurface->LockRect(&LockedRect,
    959                                                                     NULL,
    960                                                                     D3DLOCK_READONLY);
    961                             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    962 
    963                             /* Copy the data one line at a time in case the internal pitch is different. */
    964                             for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
    965                             {
    966                                 memcpy((uint8_t *)pData + j * pMipmapLevel->cbSurfacePitch, (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch, pMipmapLevel->cbSurfacePitch);
    967                             }
    968 
    969                             if (fTexture)
    970                             {
    971                                 if (pSurface->bounce.pTexture)
    972                                 {
    973                                     hr = pSurface->bounce.pTexture->UnlockRect(i);
    974                                     AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    975                                 }
    976                                 else
    977                                     hr = pSurface->u.pTexture->UnlockRect(i);
    978                             }
    979                             else
    980                                 hr = pSurface->u.pSurface->UnlockRect();
    981                             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    982                             break;
    983                         }
    984 
    985                         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    986                             fVertex = true;
    987                             /* no break */
    988 
    989                         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    990                         {
    991                             uint8_t *pD3DData;
    992 
    993                             if (fVertex)
    994                                 hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
    995                             else
    996                                 hr = pSurface->u.pIndexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
    997                             AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
    998 
    999                             memcpy(pData, pD3DData, pMipmapLevel->cbSurface);
    1000 
    1001                             if (fVertex)
    1002                                 hr = pSurface->u.pVertexBuffer->Unlock();
    1003                             else
    1004                                 hr = pSurface->u.pIndexBuffer->Unlock();
    1005                             AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Unlock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
    1006                             break;
    1007                         }
    1008 
    1009                         default:
    1010                             AssertFailed();
    1011                             break;
    1012                         }
    1013 
    1014                         if (!fSkipSave)
    1015                         {
    1016                             /* Data follows */
    1017                             rc = SSMR3PutBool(pSSM, true);
    1018                             AssertRCReturn(rc, rc);
    1019 
    1020                             /* And write the surface data. */
    1021                             rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
    1022                             AssertRCReturn(rc, rc);
    1023                         }
    1024                         else
    1025                         {
    1026                             /* No data follows */
    1027                             rc = SSMR3PutBool(pSSM, false);
    1028                             AssertRCReturn(rc, rc);
    1029                         }
    1030 
    1031                         RTMemFree(pData);
    1032 #elif defined(VMSVGA3D_OPENGL)
    1033                         void *pData = NULL;
    1034 
    1035 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    1036                         PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    1037                         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1038 # else
    1039                         /* @todo stricter checks for associated context */
    1040                         uint32_t cid = pSurface->idAssociatedContext;
    1041                         if (    cid >= pState->cContexts
    1042                             ||  pState->papContexts[cid]->id != cid)
    1043                         {
    1044                             Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    1045                             AssertFailedReturn(VERR_INVALID_PARAMETER);
    1046                         }
    1047                         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    1048                         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1049 # endif
    1050 
    1051                         Assert(pMipmapLevel->cbSurface);
    1052 
    1053                         switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
    1054                         {
    1055                         default:
    1056                             AssertFailed();
    1057                             /* no break */
    1058                         case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
    1059                         case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
    1060                             /* @todo fetch data from the renderbuffer */
    1061                             /* No data follows */
    1062                             rc = SSMR3PutBool(pSSM, false);
    1063                             AssertRCReturn(rc, rc);
    1064                             break;
    1065 
    1066                         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    1067                         case SVGA3D_SURFACE_HINT_TEXTURE:
    1068                         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    1069                         {
    1070                             GLint activeTexture;
    1071 
    1072                             pData = RTMemAllocZ(pMipmapLevel->cbSurface);
    1073                             AssertReturn(pData, VERR_NO_MEMORY);
    1074 
    1075                             glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    1076                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    1077 
    1078                             glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    1079                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    1080 
    1081                             /* Set row length and alignment of the output data. */
    1082                             VMSVGAPACKPARAMS SavedParams;
    1083                             vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
    1084 
    1085                             glGetTexImage(GL_TEXTURE_2D,
    1086                                           i,
    1087                                           pSurface->formatGL,
    1088                                           pSurface->typeGL,
    1089                                           pData);
    1090                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    1091 
    1092                             vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
    1093 
    1094                             /* Data follows */
    1095                             rc = SSMR3PutBool(pSSM, true);
    1096                             AssertRCReturn(rc, rc);
    1097 
    1098                             /* And write the surface data. */
    1099                             rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
    1100                             AssertRCReturn(rc, rc);
    1101 
    1102                             /* Restore the old active texture. */
    1103                             glBindTexture(GL_TEXTURE_2D, activeTexture);
    1104                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    1105                             break;
    1106                         }
    1107 
    1108                         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    1109                         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    1110                         {
    1111                             uint8_t *pBufferData;
    1112 
    1113                             pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
    1114                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    1115 
    1116                             pBufferData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
    1117                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    1118                             Assert(pBufferData);
    1119 
    1120                             /* Data follows */
    1121                             rc = SSMR3PutBool(pSSM, true);
    1122                             AssertRCReturn(rc, rc);
    1123 
    1124                             /* And write the surface data. */
    1125                             rc = SSMR3PutMem(pSSM, pBufferData, pMipmapLevel->cbSurface);
    1126                             AssertRCReturn(rc, rc);
    1127 
    1128                             pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
    1129                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    1130 
    1131                             pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
    1132                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    1133 
    1134                         }
    1135                         }
    1136                         if (pData)
    1137                             RTMemFree(pData);
    1138 #else
    1139 #error "Unexpected 3d backend"
    1140 #endif
    1141                     }
    1142                 }
    1143             }
    1144         }
    1145     }
    1146     return VINF_SUCCESS;
    1147 }
    1148 
    1149 static uint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
    1150 {
    1151     /* Choose a sane upper limit. */
    1152     AssertReturn(reg < _32K, VERR_INVALID_PARAMETER);
    1153 
    1154     if (type == SVGA3D_SHADERTYPE_VS)
    1155     {
    1156         if (pContext->state.cVertexShaderConst <= reg)
    1157         {
    1158             pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
    1159             AssertReturn(pContext->state.paVertexShaderConst, VERR_NO_MEMORY);
    1160             for (uint32_t i = pContext->state.cVertexShaderConst; i < reg + 1; i++)
    1161                 pContext->state.paVertexShaderConst[i].fValid = false;
    1162             pContext->state.cVertexShaderConst = reg + 1;
    1163         }
    1164 
    1165         pContext->state.paVertexShaderConst[reg].fValid   = true;
    1166         pContext->state.paVertexShaderConst[reg].ctype    = ctype;
    1167         pContext->state.paVertexShaderConst[reg].value[0] = val1;
    1168         pContext->state.paVertexShaderConst[reg].value[1] = val2;
    1169         pContext->state.paVertexShaderConst[reg].value[2] = val3;
    1170         pContext->state.paVertexShaderConst[reg].value[3] = val4;
     565        if (pszName)
     566            RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
     567        else
     568            RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
    1171569    }
    1172570    else
    1173571    {
    1174         Assert(type == SVGA3D_SHADERTYPE_PS);
    1175         if (pContext->state.cPixelShaderConst <= reg)
    1176         {
    1177             pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
    1178             AssertReturn(pContext->state.paPixelShaderConst, VERR_NO_MEMORY);
    1179             for (uint32_t i = pContext->state.cPixelShaderConst; i < reg + 1; i++)
    1180                 pContext->state.paPixelShaderConst[i].fValid = false;
    1181             pContext->state.cPixelShaderConst = reg + 1;
    1182         }
    1183 
    1184         pContext->state.paPixelShaderConst[reg].fValid   = true;
    1185         pContext->state.paPixelShaderConst[reg].ctype    = ctype;
    1186         pContext->state.paPixelShaderConst[reg].value[0] = val1;
    1187         pContext->state.paPixelShaderConst[reg].value[1] = val2;
    1188         pContext->state.paPixelShaderConst[reg].value[2] = val3;
    1189         pContext->state.paPixelShaderConst[reg].value[3] = val4;
     572        if (pszName)
     573            RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
     574        else
     575            RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
    1190576    }
    1191 
    1192     return VINF_SUCCESS;
     577    return pszBuffer;
     578}
     579
     580
     581/**
     582 * DBGF info printer for vmsvga3dAsciiPrint.
     583 *
     584 * @param   pszLine             The line to print.
     585 * @param   pvUser              The debug info helpers.
     586 */
     587DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
     588{
     589    PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
     590    pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
     591}
     592
     593
     594/**
     595 * Log printer for vmsvga3dAsciiPrint.
     596 *
     597 * @param   pszLine             The line to print.
     598 * @param   pvUser              Ignored.
     599 */
     600DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
     601{
     602    size_t cch = strlen(pszLine);
     603    while (cch > 0 && pszLine[cch - 1] == ' ')
     604        cch--;
     605    RTLogPrintf("%.*s\n", cch, pszLine);
     606    NOREF(pvUser);
     607}
     608
     609
     610void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
     611                        uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
     612                        uint32_t cchMaxX, uint32_t cchMaxY)
     613{
     614    /*
     615     * Skip stuff we can't or won't need to handle.
     616     */
     617    if (!cx || !cy)
     618        return;
     619    switch (enmFormat)
     620    {
     621        /* Compressed. */
     622        case SVGA3D_DXT1:
     623        case SVGA3D_DXT2:
     624        case SVGA3D_DXT3:
     625        case SVGA3D_DXT4:
     626        case SVGA3D_DXT5:
     627            return;
     628        /* Generic. */
     629        case SVGA3D_BUFFER:
     630            return;
     631        default:
     632            break; /* ok */
     633    }
     634
     635    /*
     636     * Figure the pixel conversion factors.
     637     */
     638    uint32_t cxPerChar = cx / cchMaxX + 1;
     639    uint32_t cyPerChar = cy / cchMaxY + 1;
     640    /** @todo try keep aspect...   */
     641    uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
     642    uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
     643
     644    /*
     645     * The very simple conversion we're doing in this function is based on
     646     * mapping a block of converted pixels to an ASCII character of similar
     647     * weigth.  We do that by summing up all the 8-bit gray scale pixels in
     648     * that block, applying a conversion factor and getting an index into an
     649     * array of increasingly weighty characters.
     650     */
     651    static const char       s_szPalette[] = "   ..`',:;icodxkO08XNWM";
     652    static const uint32_t   s_cchPalette  = sizeof(s_szPalette) - 1;
     653    uint32_t const          cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
     654
     655    /*
     656     * Do the work
     657     */
     658    uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
     659    if (!pauScanline)
     660        return;
     661    char *pszLine = (char *)&pauScanline[cchLine];
     662    RTCPTRUNION uSrc;
     663    uSrc.pv              = pvImage;
     664    if (fInvY)
     665        uSrc.pu8 += (cy - 1) * cbScanline;
     666    uint32_t cyLeft = cy;
     667    uint32_t cyLeftInScanline = cyPerChar;
     668    bool     fHitFormatAssert = false;
     669    for (;;)
     670    {
     671        /*
     672         * Process the scanline.  This is tedious because of all the
     673         * different formats.  We generally ignore alpha, unless it's
     674         * all we've got to work with.
     675         * Color to 8-bit grayscale conversion is done by averaging.
     676         */
     677#define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \
     678            do { \
     679                for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
     680                { \
     681                    a_RdExpr; \
     682                    pauScanline[xDst] += (a_AddExpr) & 0xff; \
     683                    Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
     684                    if (--cxLeftInChar == 0) \
     685                    { \
     686                        xDst++; \
     687                        cxLeftInChar = cxPerChar; \
     688                    } \
     689                } \
     690            } while (0)
     691
     692        switch (enmFormat)
     693        {
     694            /* Unsigned RGB and super/subsets. */
     695            case SVGA3D_X8R8G8B8:
     696            case SVGA3D_A8R8G8B8:
     697                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     698                                 (  ( u32Tmp        & 0xff) /* B */
     699                                  + ((u32Tmp >>  8) & 0xff) /* G */
     700                                  + ((u32Tmp >> 16) & 0xff) /* R */) / 3);
     701                break;
     702            case SVGA3D_R5G6B5:
     703                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     704                                 ( ( u16Tmp         & 0x1f) * 8
     705                                 + ((u16Tmp >>  5)  & 0x3f) * 4
     706                                 + ( u16Tmp >> 11)          * 8 ) / 3 );
     707                break;
     708            case SVGA3D_X1R5G5B5:
     709            case SVGA3D_A1R5G5B5:
     710                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     711                                 (  ( u16Tmp        & 0x1f) * 8
     712                                  + ((u16Tmp >> 5)  & 0x1f) * 8
     713                                  + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );
     714                break;
     715            case SVGA3D_A4R4G4B4:
     716                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     717                                 (  ( u16Tmp        & 0xf) * 16
     718                                  + ((u16Tmp >> 4)  & 0xf) * 16
     719                                  + ((u16Tmp >> 8)  & 0xf) * 16) / 3 );
     720                break;
     721            case SVGA3D_A16B16G16R16:
     722                CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],
     723                                 (  ((u64Tmp >>  8) & 0xff) /* R */
     724                                  + ((u64Tmp >> 24) & 0xff) /* G */
     725                                  + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);
     726                break;
     727            case SVGA3D_A2R10G10B10:
     728                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     729                                 (  ( u32Tmp        & 0x3ff) /* B */
     730                                  + ((u32Tmp >> 10) & 0x3ff) /* G */
     731                                  + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));
     732                break;
     733            case SVGA3D_G16R16:
     734                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     735                                 (  (u32Tmp & 0xffff) /* R */
     736                                  + (u32Tmp >>   16 ) /* G */) / 0x200);
     737                break;
     738
     739            /* Depth. */
     740            case SVGA3D_Z_D32:
     741                CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),
     742                                   (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))
     743                                 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
     744                                 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
     745                                 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
     746                                 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
     747                                 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
     748                                 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
     749                                 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
     750                break;
     751            case SVGA3D_Z_D16:
     752                CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],
     753                                   ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))
     754                                 | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))
     755                                 | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))
     756                                 | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))
     757                                 | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))
     758                                 | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))
     759                                 | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))
     760                                 | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );
     761                break;
     762            case SVGA3D_Z_D24S8:
     763                CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     764                                   (  u32Tmp        & 0xff) /* stencile */
     765                                 | ((~u32Tmp >> 18) & 0x3f));
     766                break;
     767            case SVGA3D_Z_D15S1:
     768                CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     769                                   ( (u16Tmp & 0x01) << 7) /* stencile */
     770                                 | ((~u16Tmp >> 8) & 0x7f));
     771                break;
     772
     773            /* Pure alpha. */
     774            case SVGA3D_ALPHA8:
     775                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
     776                break;
     777
     778            /* Luminance */
     779            case SVGA3D_LUMINANCE8:
     780                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
     781                break;
     782            case SVGA3D_LUMINANCE4_ALPHA4:
     783                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);
     784                break;
     785            case SVGA3D_LUMINANCE16:
     786                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
     787                break;
     788            case SVGA3D_LUMINANCE8_ALPHA8:
     789                CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
     790                break;
     791
     792            /* Not supported. */
     793            case SVGA3D_DXT1:
     794            case SVGA3D_DXT2:
     795            case SVGA3D_DXT3:
     796            case SVGA3D_DXT4:
     797            case SVGA3D_DXT5:
     798            case SVGA3D_BUFFER:
     799                AssertFailedBreak();
     800
     801            /* Not considered for implementation yet. */
     802            case SVGA3D_BUMPU8V8:
     803            case SVGA3D_BUMPL6V5U5:
     804            case SVGA3D_BUMPX8L8V8U8:
     805            case SVGA3D_BUMPL8V8U8:
     806            case SVGA3D_ARGB_S10E5:
     807            case SVGA3D_ARGB_S23E8:
     808            case SVGA3D_V8U8:
     809            case SVGA3D_Q8W8V8U8:
     810            case SVGA3D_CxV8U8:
     811            case SVGA3D_X8L8V8U8:
     812            case SVGA3D_A2W10V10U10:
     813            case SVGA3D_R_S10E5:
     814            case SVGA3D_R_S23E8:
     815            case SVGA3D_RG_S10E5:
     816            case SVGA3D_RG_S23E8:
     817            case SVGA3D_Z_D24X8:
     818            case SVGA3D_V16U16:
     819            case SVGA3D_UYVY:
     820            case SVGA3D_YUY2:
     821            case SVGA3D_NV12:
     822            case SVGA3D_AYUV:
     823            case SVGA3D_BC4_UNORM:
     824            case SVGA3D_BC5_UNORM:
     825            case SVGA3D_Z_DF16:
     826            case SVGA3D_Z_DF24:
     827            case SVGA3D_Z_D24S8_INT:
     828                if (!fHitFormatAssert)
     829                {
     830                    AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));
     831                    fHitFormatAssert = true;
     832                }
     833                /* fall thru */
     834            default:
     835                /* Lazy programmer fallbacks. */
     836                if (cbSrcPixel == 4)
     837                    CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
     838                                     (  ( u32Tmp        & 0xff)
     839                                      + ((u32Tmp >>  8) & 0xff)
     840                                      + ((u32Tmp >> 16) & 0xff)
     841                                      + ((u32Tmp >> 24) & 0xff) ) / 4);
     842                else if (cbSrcPixel == 3)
     843                    CONVERT_SCANLINE(RT_NOTHING,
     844                                     (  (uint32_t)uSrc.pu8[xSrc * 4]
     845                                      + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
     846                                      + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
     847                else if (cbSrcPixel == 2)
     848                    CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
     849                                     (  ( u16Tmp        & 0xf)
     850                                      + ((u16Tmp >>  4) & 0xf)
     851                                      + ((u16Tmp >>  8) & 0xf)
     852                                      + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );
     853                else if (cbSrcPixel == 1)
     854                    CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
     855                else
     856                    AssertFailed();
     857                break;
     858
     859        }
     860
     861        /*
     862         * Print we've reached the end of a block in y direction or if we're at
     863         * the end of the image.
     864         */
     865        cyLeft--;
     866        if (--cyLeftInScanline == 0 || cyLeft == 0)
     867        {
     868            for (uint32_t i = 0; i < cchLine; i++)
     869            {
     870                uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
     871                pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
     872            }
     873            pszLine[cchLine] = '\0';
     874            pfnPrintLine(pszLine, pvUser);
     875
     876            if (!cyLeft)
     877                break;
     878            cyLeftInScanline = cyPerChar;
     879            RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
     880        }
     881
     882        /*
     883         * Advance.
     884         */
     885        if (!fInvY)
     886            uSrc.pu8 += cbScanline;
     887        else
     888            uSrc.pu8 -= cbScanline;
     889    }
     890}
     891
     892
     893/**
     894 * List of render state names with type prefix.
     895 *
     896 * First char in the name is a type indicator:
     897 *      - '*' = requires special handling.
     898 *      - 'f' = SVGA3dbool
     899 *      - 'd' = uint32_t
     900 *      - 'r' = float
     901 *      - 'b' = SVGA3dBlendOp
     902 *      - 'c' = SVGA3dColor, SVGA3dColorMask
     903 *      - 'e' = SVGA3dBlendEquation
     904 *      - 'm' = SVGA3dColorMask
     905 *      - 'p' = SVGA3dCmpFunc
     906 *      - 's' = SVGA3dStencilOp
     907 *      - 'v' = SVGA3dVertexMaterial
     908 *      - 'w' = SVGA3dWrapFlags
     909 */
     910static const char * const g_apszRenderStateNamesAndType[] =
     911{
     912   "*" "INVALID",                       /*  invalid  */
     913   "f" "ZENABLE",                       /*  SVGA3dBool  */
     914   "f" "ZWRITEENABLE",                  /*  SVGA3dBool  */
     915   "f" "ALPHATESTENABLE",               /*  SVGA3dBool  */
     916   "f" "DITHERENABLE",                  /*  SVGA3dBool  */
     917   "f" "BLENDENABLE",                   /*  SVGA3dBool  */
     918   "f" "FOGENABLE",                     /*  SVGA3dBool  */
     919   "f" "SPECULARENABLE",                /*  SVGA3dBool  */
     920   "f" "STENCILENABLE",                 /*  SVGA3dBool  */
     921   "f" "LIGHTINGENABLE",                /*  SVGA3dBool  */
     922   "f" "NORMALIZENORMALS",              /*  SVGA3dBool  */
     923   "f" "POINTSPRITEENABLE",             /*  SVGA3dBool  */
     924   "f" "POINTSCALEENABLE",              /*  SVGA3dBool  */
     925   "x" "STENCILREF",                    /*  uint32_t  */
     926   "x" "STENCILMASK",                   /*  uint32_t  */
     927   "x" "STENCILWRITEMASK",              /*  uint32_t  */
     928   "r" "FOGSTART",                      /*  float  */
     929   "r" "FOGEND",                        /*  float  */
     930   "r" "FOGDENSITY",                    /*  float  */
     931   "r" "POINTSIZE",                     /*  float  */
     932   "r" "POINTSIZEMIN",                  /*  float  */
     933   "r" "POINTSIZEMAX",                  /*  float  */
     934   "r" "POINTSCALE_A",                  /*  float  */
     935   "r" "POINTSCALE_B",                  /*  float  */
     936   "r" "POINTSCALE_C",                  /*  float  */
     937   "c" "FOGCOLOR",                      /*  SVGA3dColor  */
     938   "c" "AMBIENT",                       /*  SVGA3dColor  */
     939   "*" "CLIPPLANEENABLE",               /*  SVGA3dClipPlanes  */
     940   "*" "FOGMODE",                       /*  SVGA3dFogMode  */
     941   "*" "FILLMODE",                      /*  SVGA3dFillMode  */
     942   "*" "SHADEMODE",                     /*  SVGA3dShadeMode  */
     943   "*" "LINEPATTERN",                   /*  SVGA3dLinePattern  */
     944   "b" "SRCBLEND",                      /*  SVGA3dBlendOp  */
     945   "b" "DSTBLEND",                      /*  SVGA3dBlendOp  */
     946   "e" "BLENDEQUATION",                 /*  SVGA3dBlendEquation  */
     947   "*" "CULLMODE",                      /*  SVGA3dFace  */
     948   "p" "ZFUNC",                         /*  SVGA3dCmpFunc  */
     949   "p" "ALPHAFUNC",                     /*  SVGA3dCmpFunc  */
     950   "p" "STENCILFUNC",                   /*  SVGA3dCmpFunc  */
     951   "s" "STENCILFAIL",                   /*  SVGA3dStencilOp  */
     952   "s" "STENCILZFAIL",                  /*  SVGA3dStencilOp  */
     953   "s" "STENCILPASS",                   /*  SVGA3dStencilOp  */
     954   "r" "ALPHAREF",                      /*  float  */
     955   "*" "FRONTWINDING",                  /*  SVGA3dFrontWinding  */
     956   "*" "COORDINATETYPE",                /*  SVGA3dCoordinateType  */
     957   "r" "ZBIAS",                         /*  float  */
     958   "f" "RANGEFOGENABLE",                /*  SVGA3dBool  */
     959   "c" "COLORWRITEENABLE",              /*  SVGA3dColorMask  */
     960   "f" "VERTEXMATERIALENABLE",          /*  SVGA3dBool  */
     961   "v" "DIFFUSEMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
     962   "v" "SPECULARMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
     963   "v" "AMBIENTMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
     964   "v" "EMISSIVEMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
     965   "c" "TEXTUREFACTOR",                 /*  SVGA3dColor  */
     966   "f" "LOCALVIEWER",                   /*  SVGA3dBool  */
     967   "f" "SCISSORTESTENABLE",             /*  SVGA3dBool  */
     968   "c" "BLENDCOLOR",                    /*  SVGA3dColor  */
     969   "f" "STENCILENABLE2SIDED",           /*  SVGA3dBool  */
     970   "p" "CCWSTENCILFUNC",                /*  SVGA3dCmpFunc  */
     971   "s" "CCWSTENCILFAIL",                /*  SVGA3dStencilOp  */
     972   "s" "CCWSTENCILZFAIL",               /*  SVGA3dStencilOp  */
     973   "s" "CCWSTENCILPASS",                /*  SVGA3dStencilOp  */
     974   "*" "VERTEXBLEND",                   /*  SVGA3dVertexBlendFlags  */
     975   "r" "SLOPESCALEDEPTHBIAS",           /*  float  */
     976   "r" "DEPTHBIAS",                     /*  float  */
     977   "r" "OUTPUTGAMMA",                   /*  float  */
     978   "f" "ZVISIBLE",                      /*  SVGA3dBool  */
     979   "f" "LASTPIXEL",                     /*  SVGA3dBool  */
     980   "f" "CLIPPING",                      /*  SVGA3dBool  */
     981   "w" "WRAP0",                         /*  SVGA3dWrapFlags  */
     982   "w" "WRAP1",                         /*  SVGA3dWrapFlags  */
     983   "w" "WRAP2",                         /*  SVGA3dWrapFlags  */
     984   "w" "WRAP3",                         /*  SVGA3dWrapFlags  */
     985   "w" "WRAP4",                         /*  SVGA3dWrapFlags  */
     986   "w" "WRAP5",                         /*  SVGA3dWrapFlags  */
     987   "w" "WRAP6",                         /*  SVGA3dWrapFlags  */
     988   "w" "WRAP7",                         /*  SVGA3dWrapFlags  */
     989   "w" "WRAP8",                         /*  SVGA3dWrapFlags  */
     990   "w" "WRAP9",                         /*  SVGA3dWrapFlags  */
     991   "w" "WRAP10",                        /*  SVGA3dWrapFlags  */
     992   "w" "WRAP11",                        /*  SVGA3dWrapFlags  */
     993   "w" "WRAP12",                        /*  SVGA3dWrapFlags  */
     994   "w" "WRAP13",                        /*  SVGA3dWrapFlags  */
     995   "w" "WRAP14",                        /*  SVGA3dWrapFlags  */
     996   "w" "WRAP15",                        /*  SVGA3dWrapFlags  */
     997   "f" "MULTISAMPLEANTIALIAS",          /*  SVGA3dBool  */
     998   "x" "MULTISAMPLEMASK",               /*  uint32_t  */
     999   "f" "INDEXEDVERTEXBLENDENABLE",      /*  SVGA3dBool  */
     1000   "r" "TWEENFACTOR",                   /*  float  */
     1001   "f" "ANTIALIASEDLINEENABLE",         /*  SVGA3dBool  */
     1002   "c" "COLORWRITEENABLE1",             /*  SVGA3dColorMask  */
     1003   "c" "COLORWRITEENABLE2",             /*  SVGA3dColorMask  */
     1004   "c" "COLORWRITEENABLE3",             /*  SVGA3dColorMask  */
     1005   "f" "SEPARATEALPHABLENDENABLE",      /*  SVGA3dBool  */
     1006   "b" "SRCBLENDALPHA",                 /*  SVGA3dBlendOp  */
     1007   "b" "DSTBLENDALPHA",                 /*  SVGA3dBlendOp  */
     1008   "e" "BLENDEQUATIONALPHA",            /*  SVGA3dBlendEquation  */
     1009   "*" "TRANSPARENCYANTIALIAS",         /*  SVGA3dTransparencyAntialiasType  */
     1010   "f" "LINEAA",                        /*  SVGA3dBool  */
     1011   "r" "LINEWIDTH",                     /*  float  */
     1012};
     1013
     1014
     1015/**
     1016 * Formats a SVGA3dRenderState structure as a string.
     1017 *
     1018 * @returns pszBuffer.
     1019 * @param   pszBuffer       Output string buffer.
     1020 * @param   cbBuffer        Size of output buffer.
     1021 * @param   pRenderState    The SVGA3d render state to format.
     1022 */
     1023char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
     1024{
     1025    uint32_t iState = pRenderState->state;
     1026    if (iState != SVGA3D_RS_INVALID)
     1027    {
     1028        if (iState < RT_ELEMENTS(g_apszRenderStateNamesAndType))
     1029        {
     1030            const char *pszName = g_apszRenderStateNamesAndType[iState];
     1031            char const  chType  = *pszName++;
     1032
     1033            union
     1034            {
     1035               uint32_t  u;
     1036               float     r;
     1037               SVGA3dColorMask Color;
     1038            } uValue;
     1039            uValue.u = pRenderState->uintValue;
     1040
     1041            switch (chType)
     1042            {
     1043                case 'f':
     1044                    if (uValue.u == 0)
     1045                        RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
     1046                    else if (uValue.u == 1)
     1047                        RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
     1048                    else
     1049                        RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
     1050                    break;
     1051                case 'x':
     1052                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
     1053                    break;
     1054                case 'r':
     1055                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
     1056                                pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
     1057                    break;
     1058                case 'c': //SVGA3dColor, SVGA3dColorMask
     1059                    RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
     1060                                uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
     1061                    break;
     1062                case 'w': //SVGA3dWrapFlags
     1063                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
     1064                                uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
     1065                    break;
     1066                default:
     1067                    AssertFailed();
     1068                case 'b': //SVGA3dBlendOp
     1069                case 'e': //SVGA3dBlendEquation
     1070                case 'p': //SVGA3dCmpFunc
     1071                case 's': //SVGA3dStencilOp
     1072                case 'v': //SVGA3dVertexMaterial
     1073                case '*':
     1074                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
     1075                    break;
     1076            }
     1077        }
     1078        else
     1079            RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
     1080    }
     1081    else
     1082        RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
     1083    return pszBuffer;
     1084}
     1085
     1086/**
     1087 * Texture state names with type prefix.
     1088 */
     1089static const char * const g_apszTextureStateNamesAndType[] =
     1090{
     1091    "*" "INVALID",                      /*  invalid  */
     1092    "x" "BIND_TEXTURE",                 /*  SVGA3dSurfaceId  */
     1093    "m" "COLOROP",                      /*  SVGA3dTextureCombiner  */
     1094    "a" "COLORARG1",                    /*  SVGA3dTextureArgData  */
     1095    "a" "COLORARG2",                    /*  SVGA3dTextureArgData  */
     1096    "m" "ALPHAOP",                      /*  SVGA3dTextureCombiner  */
     1097    "a" "ALPHAARG1",                    /*  SVGA3dTextureArgData  */
     1098    "a" "ALPHAARG2",                    /*  SVGA3dTextureArgData  */
     1099    "e" "ADDRESSU",                     /*  SVGA3dTextureAddress  */
     1100    "e" "ADDRESSV",                     /*  SVGA3dTextureAddress  */
     1101    "l" "MIPFILTER",                    /*  SVGA3dTextureFilter  */
     1102    "l" "MAGFILTER",                    /*  SVGA3dTextureFilter  */
     1103    "m" "MINFILTER",                    /*  SVGA3dTextureFilter  */
     1104    "c" "BORDERCOLOR",                  /*  SVGA3dColor  */
     1105    "r" "TEXCOORDINDEX",                /*  uint32_t  */
     1106    "t" "TEXTURETRANSFORMFLAGS",        /*  SVGA3dTexTransformFlags  */
     1107    "g" "TEXCOORDGEN",                  /*  SVGA3dTextureCoordGen  */
     1108    "r" "BUMPENVMAT00",                 /*  float  */
     1109    "r" "BUMPENVMAT01",                 /*  float  */
     1110    "r" "BUMPENVMAT10",                 /*  float  */
     1111    "r" "BUMPENVMAT11",                 /*  float  */
     1112    "x" "TEXTURE_MIPMAP_LEVEL",         /*  uint32_t  */
     1113    "r" "TEXTURE_LOD_BIAS",             /*  float  */
     1114    "x" "TEXTURE_ANISOTROPIC_LEVEL",    /*  uint32_t  */
     1115    "e" "ADDRESSW",                     /*  SVGA3dTextureAddress  */
     1116    "r" "GAMMA",                        /*  float  */
     1117    "r" "BUMPENVLSCALE",                /*  float  */
     1118    "r" "BUMPENVLOFFSET",               /*  float  */
     1119    "a" "COLORARG0",                    /*  SVGA3dTextureArgData  */
     1120    "a" "ALPHAARG0"                     /*  SVGA3dTextureArgData */
     1121};
     1122
     1123/**
     1124 * Formats a SVGA3dTextureState structure as a string.
     1125 *
     1126 * @returns pszBuffer.
     1127 * @param   pszBuffer       Output string buffer.
     1128 * @param   cbBuffer        Size of output buffer.
     1129 * @param   pTextureState   The SVGA3d texture state to format.
     1130 */
     1131char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
     1132{
     1133    /*
     1134     * Format the stage first.
     1135     */
     1136    char  *pszRet    = pszBuffer;
     1137    size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
     1138    if (cchPrefix < cbBuffer)
     1139    {
     1140        cbBuffer  -= cchPrefix;
     1141        pszBuffer += cchPrefix;
     1142    }
     1143    else
     1144        cbBuffer = 0;
     1145
     1146    /*
     1147     * Format the name and value.
     1148     */
     1149    uint32_t iName = pTextureState->name;
     1150    if (iName != SVGA3D_TS_INVALID)
     1151    {
     1152        if (iName < RT_ELEMENTS(g_apszTextureStateNamesAndType))
     1153        {
     1154            const char *pszName = g_apszTextureStateNamesAndType[iName];
     1155            char        chType  = *pszName++;
     1156
     1157            union
     1158            {
     1159               uint32_t  u;
     1160               float     r;
     1161               SVGA3dColorMask Color;
     1162            } uValue;
     1163            uValue.u = pTextureState->value;
     1164
     1165            switch (chType)
     1166            {
     1167                case 'x':
     1168                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
     1169                    break;
     1170
     1171                case 'r':
     1172                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
     1173                                pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
     1174                    break;
     1175
     1176                case 'a': //SVGA3dTextureArgData
     1177                {
     1178                    static const char * const s_apszValues[] =
     1179                    {
     1180                        "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
     1181                    };
     1182                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1183                                          "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1184                    break;
     1185                }
     1186
     1187                case 'c': //SVGA3dColor, SVGA3dColorMask
     1188                    RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
     1189                                uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
     1190                    break;
     1191
     1192                case 'e': //SVGA3dTextureAddress
     1193                {
     1194                    static const char * const s_apszValues[] =
     1195                    {
     1196                        "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
     1197                    };
     1198                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1199                                          "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1200                    break;
     1201                }
     1202
     1203                case 'l': //SVGA3dTextureFilter
     1204                {
     1205                    static const char * const s_apszValues[] =
     1206                    {
     1207                        "NONE", "NEAREST", "LINEAR",  "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
     1208                    };
     1209                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1210                                          "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1211                    break;
     1212                }
     1213
     1214                case 'g': //SVGA3dTextureCoordGen
     1215                {
     1216                    static const char * const s_apszValues[] =
     1217                    {
     1218                        "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
     1219                    };
     1220                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1221                                          "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1222                    break;
     1223                }
     1224
     1225                case 'm': //SVGA3dTextureCombiner
     1226                {
     1227                    static const char * const s_apszValues[] =
     1228                    {
     1229                        "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
     1230                        "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
     1231                        "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
     1232                        "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
     1233                        "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
     1234                    };
     1235                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
     1236                                          "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
     1237                    break;
     1238                }
     1239
     1240                default:
     1241                    AssertFailed();
     1242                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
     1243                    break;
     1244            }
     1245        }
     1246        else
     1247            RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
     1248    }
     1249    else
     1250        RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
     1251    return pszRet;
    11931252}
    11941253
     
    18051864}
    18061865
    1807 
    1808 #endif /* !___DevVGA_SVGA3d_shared_h___ */
    1809 
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h

    r57148 r57149  
    11/* $Id$ */
    22/** @file
    3  * DevVMWare - VMWare SVGA device
     3 * DevVMWare - VMWare SVGA device - 3D part, internal header.
    44 */
    55
     
    1616 */
    1717
    18 
    19 /*******************************************************************************
    20 *   Header Files                                                               *
    21 *******************************************************************************/
    22 /* Enable to disassemble defined shaders. (Windows host only) */
    23 #if defined(RT_OS_WINDOWS) && defined(DEBUG) && 0 /* Disabled as we don't have the DirectX SDK avaible atm. */
    24 # define DUMP_SHADER_DISASSEMBLY
    25 #endif
    26 #ifdef DEBUG_bird
    27 # define RTMEM_WRAP_TO_EF_APIS
    28 #endif
    29 #define LOG_GROUP LOG_GROUP_DEV_VMSVGA
    30 #include <VBox/vmm/pdmdev.h>
    31 #include <VBox/version.h>
    32 #include <VBox/err.h>
    33 #include <VBox/log.h>
    34 #include <VBox/vmm/pgm.h>
    35 
    36 #include <iprt/assert.h>
    37 #include <iprt/semaphore.h>
    38 #include <iprt/uuid.h>
    39 #include <iprt/mem.h>
    40 #include <iprt/avl.h>
    41 
    42 #include <VBox/VMMDev.h>
    43 #include <VBox/VBoxVideo.h>
    44 #include <VBox/bioslogo.h>
    45 
    46 /* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
    47 #include "DevVGA.h"
    48 
    49 #include "DevVGA-SVGA.h"
     18#ifndef ___DevVGA_SVGA3d_internal_h
     19#define ___DevVGA_SVGA3d_internal_h
     20
     21/*
     22 * Assert sane compilation environment.
     23 */
     24#ifndef IN_RING3
     25# error "VMSVGA3D_INCL_INTERNALS is only for ring-3 code"
     26#endif
     27#ifdef VMSVGA3D_OPENGL
     28# ifdef VMSVGA3D_DIRECT3D
     29#  error "Both VMSVGA3D_DIRECT3D and VMSVGA3D_OPENGL cannot be defined at the same time."
     30# endif
     31#elif !defined(VMSVGA3D_DIRECT3D)
     32# error "Either VMSVGA3D_OPENGL or VMSVGA3D_DIRECT3D must be defined."
     33#endif
     34
     35
     36/*********************************************************************************************************************************
     37*   Header Files                                                                                                                 *
     38*********************************************************************************************************************************/
    5039#include "DevVGA-SVGA3d.h"
    51 #include "vmsvga/svga_reg.h"
    52 #include "vmsvga/svga3d_reg.h"
    53 #include "vmsvga/svga3d_shaderdefs.h"
    5440
    5541#ifdef RT_OS_WINDOWS
    56 # include <GL/gl.h>
    57 # include "vmsvga_glext/wglext.h"
     42# include <Windows.h>
     43# ifdef VMSVGA3D_DIRECT3D
     44#  include <d3d9.h>
     45#  include <iprt/avl.h>
     46# else
     47#  include <GL/gl.h>
     48#  include "vmsvga_glext/wglext.h"
     49# endif
    5850
    5951#elif defined(RT_OS_DARWIN)
     
    7870# define GL_LUMINANCE8_ALPHA8_EXT 0x8045
    7971# define GL_INT_2_10_10_10_REV 0x8D9F
     72
    8073#else
    8174# include <X11/Xlib.h>
     
    8679# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103
    8780#endif
    88 #ifdef DUMP_SHADER_DISASSEMBLY
    89 # include <d3dx9shader.h>
    90 #endif
    91 #include "vmsvga_glext/glext.h"
    92 
    93 #include "shaderlib/shaderlib.h"
    94 
    95 #include <stdlib.h>
    96 #include <math.h>
    97 #include <float.h>
    98 
    99 
    100 /*******************************************************************************
    101 *   Defined Constants And Macros                                               *
    102 *******************************************************************************/
     81
     82#include "vmsvga/svga3d_shaderdefs.h"
     83#ifdef VMSVGA3D_OPENGL
     84# include "vmsvga_glext/glext.h"
     85# include "shaderlib/shaderlib.h"
     86#endif
     87
     88
     89/*********************************************************************************************************************************
     90*   Defined Constants And Macros                                                                                                 *
     91*********************************************************************************************************************************/
    10392/** Experimental: Create a dedicated context for handling surfaces in, thus
    10493 * avoiding orphaned surfaces after context destruction.
     
    114103 *          if we really need to, but as this is an experiment, I'm playing it safe.
    115104 */
    116 #define VMSVGA3D_OGL_WITH_SHARED_CTX
     105#ifdef VMSVGA3D_OPENGL
     106# define VMSVGA3D_OGL_WITH_SHARED_CTX
     107#endif
    117108#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    118109/** Fake surface ID for the shared context. */
    119 # define VMSVGA3D_SHARED_CTX_ID     UINT32_C(0xffffeeee)
    120 #endif
     110# define VMSVGA3D_SHARED_CTX_ID        UINT32_C(0xffffeeee)
     111#endif
     112
     113#ifdef VMSVGA3D_OPENGL
    121114
    122115/** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
     
    127120 * The value is ((x)<<16 | (y))  where x and y are taken from the GL_VERSION_x_y.
    128121 */
    129 #ifndef VBOX_VMSVGA3D_GL_HACK_LEVEL
    130 # define VBOX_VMSVGA3D_GL_HACK_LEVEL   0
    131 #endif
    132 
    133 #ifndef VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE
    134 # define VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE 1.0
    135 #endif
    136 
    137 #ifdef RT_OS_WINDOWS
    138 # define OGLGETPROCADDRESS      wglGetProcAddress
    139 
    140 #elif defined(RT_OS_DARWIN)
    141 # include <dlfcn.h>
    142 # define OGLGETPROCADDRESS      MyNSGLGetProcAddress
    143 /** Resolves an OpenGL symbol.  */
    144 static void *MyNSGLGetProcAddress(const char *pszSymbol)
    145 {
    146     /* Another copy in shaderapi.c. */
    147     static void *s_pvImage = NULL;
    148     if (s_pvImage == NULL)
    149         s_pvImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
    150     return s_pvImage ? dlsym(s_pvImage, pszSymbol) : NULL;
    151 }
    152 
    153 #else
    154 # define OGLGETPROCADDRESS(x)   glXGetProcAddress((const GLubyte *)x)
    155 #endif
    156 
    157 /* Invert y-coordinate for OpenGL's bottom left origin. */
    158 #define D3D_TO_OGL_Y_COORD(ptrSurface, y_coordinate)                (ptrSurface->pMipmapLevels[0].size.height - (y_coordinate))
    159 #define D3D_TO_OGL_Y_COORD_MIPLEVEL(ptrMipLevel, y_coordinate)      (ptrMipLevel->size.height - (y_coordinate))
    160 
    161 #define OPENGL_INVALID_ID               0
    162 
    163 //#define MANUAL_FLIP_SURFACE_DATA
    164 /* Enable to render the result of DrawPrimitive in a seperate window. */
    165 //#define DEBUG_GFX_WINDOW
    166 
    167 
    168 /** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
    169  * @{ */
    170 /** When clear, the  context is created using the default OpenGL profile.
    171  * When set, it's created using the alternative profile.  The latter is only
    172  * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set.  */
    173 #define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE    RT_BIT_32(0)
    174 /** Defining the shared context.  */
    175 #define VMSVGA3D_DEF_CTX_F_SHARED_CTX       RT_BIT_32(1)
    176 /** Defining the init time context (EMT).  */
    177 #define VMSVGA3D_DEF_CTX_F_INIT             RT_BIT_32(2)
    178 /** @} */
    179 
    180 
    181 #define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState)                          \
     122# ifndef VBOX_VMSVGA3D_GL_HACK_LEVEL
     123#  define VBOX_VMSVGA3D_GL_HACK_LEVEL   0
     124# endif
     125
     126/** Invalid OpenGL ID. */
     127# define OPENGL_INVALID_ID              0
     128
     129# define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState)                          \
    182130    do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0)
    183131
     
    187135 * @parm    pContext    The new context.
    188136 */
    189 #ifdef RT_OS_WINDOWS
    190 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
     137# ifdef RT_OS_WINDOWS
     138#  define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
    191139    do {  \
    192140        if ((pState)->idActiveContext != (pContext)->id) \
     
    199147    } while (0)
    200148
    201 #elif defined(RT_OS_DARWIN)
    202 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
     149# elif defined(RT_OS_DARWIN)
     150#  define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
    203151    do {  \
    204152        if ((pState)->idActiveContext != (pContext)->id) \
     
    209157        } \
    210158    } while (0)
    211 #else
    212 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
     159# else
     160#  define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
    213161    do {  \
    214162        if ((pState)->idActiveContext != (pContext)->id) \
     
    222170        } \
    223171    } while (0)
    224 #endif
     172# endif
    225173
    226174/** @def VMSVGA3D_CLEAR_GL_ERRORS
     
    239187 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
    240188 */
    241 #define VMSVGA3D_CLEAR_GL_ERRORS() \
     189# define VMSVGA3D_CLEAR_GL_ERRORS() \
    242190    do { \
    243191        if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \
     
    258206 * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    259207 */
    260 #define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())
     208# define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())
    261209
    262210/** @def VMSVGA3D_GL_SUCCESS
     
    271219 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN
    272220 */
    273 #define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))
     221# define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))
    274222
    275223/** @def VMSVGA3D_GL_COMPLAIN
     
    289237 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
    290238 */
    291 #ifdef VBOX_STRICT
    292 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
     239# ifdef VBOX_STRICT
     240#  define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
    293241    do { \
    294242        AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \
     
    300248        AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \
    301249    } while (0)
    302 #else
    303 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
     250# else
     251#  define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
    304252    do { \
    305253        LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id)); \
     
    309257        LogRelMax(32, a_LogRelDetails); \
    310258    } while (0)
    311 #endif
     259# endif
    312260
    313261/** @def VMSVGA3D_GL_GET_AND_COMPLAIN
     
    322270 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    323271 */
    324 #define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
     272# define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
    325273    do { \
    326274        VMSVGA3D_GET_GL_ERROR(a_pContext); \
     
    341289 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    342290 */
    343 #define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \
     291# define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \
    344292    if (VMSVGA3D_GL_IS_SUCCESS(a_pContext)) \
    345293    { /* likely */ } \
     
    367315 *     VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    368316 */
    369 #define VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, a_LogRelDetails) \
     317# define VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, a_LogRelDetails) \
    370318    do { \
    371319        (a_GlCall); \
     
    389337 *     VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    390338 */
    391 #define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \
     339# define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \
    392340    VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, ("%s\n", #a_GlCall))
    393341
     
    406354 *          release builds.
    407355 */
    408 #ifdef VBOX_STRICT
    409 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do {                   \
     356# ifdef VBOX_STRICT
     357#  define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do {                   \
    410358    Assert((pState)->idActiveContext == (pContext)->id);                    \
    411359    (pContext)->lastError = glGetError();                                   \
     
    414362                    VERR_INTERNAL_ERROR); \
    415363    } while (0)
    416 #else
    417 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext)                        do { } while (0)
    418 #endif
     364# else
     365#  define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext)                        do { } while (0)
     366# endif
    419367
    420368/** @def VMSVGA3D_CHECK_LAST_ERROR_WARN
     
    426374 * @parm    pContext    The new context.
    427375 */
    428 #ifdef VBOX_STRICT
    429 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do {              \
     376# ifdef VBOX_STRICT
     377#  define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do {              \
    430378    Assert((pState)->idActiveContext == (pContext)->id);                    \
    431379    (pContext)->lastError = glGetError();                                   \
    432380    AssertMsg((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError)); \
    433381    } while (0)
    434 #else
    435 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext)                   do { } while (0)
    436 #endif
    437 
    438 
    439 /**
    440  * Macro for doing something and then checking for errors during initialization.
    441  * Uses AssertLogRelMsg.
    442  */
    443 #define VMSVGA3D_INIT_CHECKED(a_Expr) \
    444     do \
    445     { \
    446         a_Expr; \
    447         GLenum iGlError = glGetError(); \
    448         AssertLogRelMsg(iGlError == GL_NO_ERROR, ("VMSVGA3d: %s -> %#x\n", #a_Expr, iGlError)); \
    449     } while (0)
    450 
    451 /**
    452  * Macro for doing something and then checking for errors during initialization,
    453  * doing the same in the other context when enabled.
    454  *
    455  * This will try both profiles in dual profile builds.  Caller must be in the
    456  * default context.
    457  *
    458  * Uses AssertLogRelMsg to indicate trouble.
    459  */
    460 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    461 # define VMSVGA3D_INIT_CHECKED_BOTH(a_pState, a_pContext, a_pOtherCtx, a_Expr) \
    462     do \
    463     { \
    464         for (uint32_t i = 0; i < 64; i++) if (glGetError() == GL_NO_ERROR) break; Assert(glGetError() == GL_NO_ERROR); \
    465         a_Expr; \
    466         GLenum iGlError = glGetError(); \
    467         if (iGlError != GL_NO_ERROR) \
    468         { \
    469             VMSVGA3D_SET_CURRENT_CONTEXT(a_pState, a_pOtherCtx); \
    470             for (uint32_t i = 0; i < 64; i++) if (glGetError() == GL_NO_ERROR) break; Assert(glGetError() == GL_NO_ERROR); \
    471             a_Expr; \
    472             GLenum iGlError2 = glGetError(); \
    473             AssertLogRelMsg(iGlError2 == GL_NO_ERROR, ("VMSVGA3d: %s -> %#x / %#x\n", #a_Expr, iGlError, iGlError2)); \
    474             VMSVGA3D_SET_CURRENT_CONTEXT(a_pState, a_pContext); \
    475         } \
    476     } while (0)
    477 #else
    478 # define VMSVGA3D_INIT_CHECKED_BOTH(a_pState, a_pContext, a_pOtherCtx, a_Expr) VMSVGA3D_INIT_CHECKED(a_Expr)
    479 #endif
    480 
    481 
    482 /*******************************************************************************
    483 *   Structures, Typedefs and Globals.                                          *
    484 *******************************************************************************/
    485 typedef struct
    486 {
     382# else
     383#  define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext)                   do { } while (0)
     384# endif
     385
     386#endif /* VMSVGA3D_OPENGL */
     387
     388#ifdef VMSVGA3D_DIRECT3D
     389/* Enable to use Wine to convert D3D to opengl */
     390//#define VBOX_VMSVGA3D_WITH_WINE_OPENGL
     391#endif
     392
     393
     394/*********************************************************************************************************************************
     395*   Structures and Typedefs                                                                                                      *
     396*********************************************************************************************************************************/
     397/**
     398 * Mipmap level.
     399 */
     400typedef struct VMSVGA3DMIPMAPLEVEL
     401{
     402    /** The mipmap size. */
    487403    SVGA3dSize              size;
     404    /** The size (in bytes) of the mimap data when using the format the surface was
     405     *  defined with. */
    488406    uint32_t                cbSurface;
     407    /** The scanline/pitch size in bytes. */
    489408    uint32_t                cbSurfacePitch;
     409    /** Pointer to the mipmap bytes (cbSurface).  Often NULL.  If the surface has
     410     * been realized in hardware, this may be outdated. */
    490411    void                   *pSurfaceData;
     412    /** Set if pvSurfaceData contains data not realized in hardware or pushed to the
     413     * hardware surface yet. */
    491414    bool                    fDirty;
    492 } VMSVGA3DMIPMAPLEVEL, *PVMSVGA3DMIPMAPLEVEL;
    493 
     415} VMSVGA3DMIPMAPLEVEL;
     416/** Pointer to a mipmap level. */
     417typedef VMSVGA3DMIPMAPLEVEL *PVMSVGA3DMIPMAPLEVEL;
     418
     419
     420#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
    494421/**
    495422 * SSM descriptor table for the VMSVGA3DMIPMAPLEVEL structure.
     
    504431    SSMFIELD_ENTRY_TERM()
    505432};
    506 
     433#endif
     434
     435typedef struct VMSVGATRANSFORMSTATE
     436{
     437    bool        fValid;
     438    float       matrix[16];
     439} VMSVGATRANSFORMSTATE;
     440typedef VMSVGATRANSFORMSTATE *PVMSVGATRANSFORMSTATE;
     441
     442typedef struct VMSVGAMATERIALSTATE
     443{
     444    bool            fValid;
     445    SVGA3dMaterial  material;
     446} VMSVGAMATERIALSTATE;
     447typedef VMSVGAMATERIALSTATE *PVMSVGAMATERIALSTATE;
     448
     449typedef struct VMSVGACLIPPLANESTATE
     450{
     451    bool            fValid;
     452    float           plane[4];
     453} VMSVGACLIPPLANESTATE;
     454typedef VMSVGACLIPPLANESTATE *PVMSVGACLIPPLANESTATE;
     455
     456typedef struct VMSVGALIGHTSTATE
     457{
     458    bool            fEnabled;
     459    bool            fValidData;
     460    SVGA3dLightData data;
     461} VMSVGALIGHTSTATE;
     462typedef VMSVGALIGHTSTATE *PVMSVGALIGHTSTATE;
     463
     464typedef struct VMSVGASHADERCONST
     465{
     466    bool                    fValid;
     467    SVGA3dShaderConstType   ctype;
     468    uint32_t                value[4];
     469} VMSVGASHADERCONST;
     470typedef VMSVGASHADERCONST *PVMSVGASHADERCONST;
     471
     472#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
     473/**
     474 * SSM descriptor table for the VMSVGASHADERCONST structure.
     475 */
     476static SSMFIELD const g_aVMSVGASHADERCONSTFields[] =
     477{
     478    SSMFIELD_ENTRY(                 VMSVGASHADERCONST, fValid),
     479    SSMFIELD_ENTRY(                 VMSVGASHADERCONST, ctype),
     480    SSMFIELD_ENTRY(                 VMSVGASHADERCONST, value),
     481    SSMFIELD_ENTRY_TERM()
     482};
     483#endif
     484
     485#ifdef VMSVGA3D_DIRECT3D
     486/**
     487 *
     488 */
    507489typedef struct
     490{
     491    /** Key is context id. */
     492    AVLU32NODECORE          Core;
     493    union
     494    {
     495        IDirect3DSurface9          *pSurface;
     496        IDirect3DTexture9          *pTexture;
     497        IDirect3DCubeTexture9      *pCubeTexture;
     498    } u;
     499} VMSVGA3DSHAREDSURFACE;
     500typedef VMSVGA3DSHAREDSURFACE *PVMSVGA3DSHAREDSURFACE;
     501#endif /* VMSVGA3D_DIRECT3D  */
     502
     503/**
     504 * VMSVGA3d surface.
     505 */
     506typedef struct VMSVGA3DSURFACE
    508507{
    509508    uint32_t                id;
     
    515514    uint32_t                flags;
    516515    SVGA3dSurfaceFormat     format;
     516#ifdef VMSVGA3D_OPENGL
    517517    GLint                   internalFormatGL;
    518518    GLint                   formatGL;
     
    524524        GLuint              renderbuffer;
    525525    } oglId;
     526#endif
    526527    SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
    527528    uint32_t                cFaces;
     
    529530    uint32_t                multiSampleCount;
    530531    SVGA3dTextureFilter     autogenFilter;
     532#ifdef VMSVGA3D_DIRECT3D
     533    D3DFORMAT               formatD3D;
     534    DWORD                   fUsageD3D;
     535    D3DMULTISAMPLE_TYPE     multiSampleTypeD3D;
     536#endif
     537
    531538    uint32_t                cbBlock;        /* block/pixel size in bytes */
    532539    /* Dirty state; surface was manually updated. */
    533540    bool                    fDirty;
    534 } VMSVGA3DSURFACE, *PVMSVGA3DSURFACE;
    535 
     541
     542#ifdef VMSVGA3D_DIRECT3D
     543    /* Handle for shared objects (currently only textures & render targets). */
     544    HANDLE                  hSharedObject;
     545    /** Event query inserted after each GPU operation that updates or uses this surface. */
     546    IDirect3DQuery9        *pQuery;
     547    union
     548    {
     549        IDirect3DSurface9          *pSurface;
     550        IDirect3DCubeTexture9      *pCubeTexture;
     551        IDirect3DIndexBuffer9      *pIndexBuffer;
     552        IDirect3DTexture9          *pTexture;
     553        IDirect3DVertexBuffer9     *pVertexBuffer;
     554    } u;
     555    union
     556    {
     557        IDirect3DTexture9          *pTexture;
     558    } bounce;
     559    /** AVL tree containing VMSVGA3DSHAREDSURFACE structures. */
     560    AVLU32TREE              pSharedObjectTree;
     561    bool                    fStencilAsTexture;
     562#endif
     563} VMSVGA3DSURFACE;
     564/** Pointer to a 3d surface. */
     565typedef VMSVGA3DSURFACE *PVMSVGA3DSURFACE;
     566
     567#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
    536568/**
    537569 * SSM descriptor table for the VMSVGA3DSURFACE structure.
     
    542574#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    543575    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idWeakContextAssociation),
    544 #else
     576# else
    545577    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idAssociatedContext),
    546 #endif
     578# endif
    547579    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, flags),
    548580    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format),
     581# ifdef VMSVGA3D_OPENGL
    549582    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, internalFormatGL),
    550583    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, formatGL),
    551584    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, typeGL),
    552585    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, id),
     586# endif
    553587    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, faces),
    554588    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cFaces),
     
    556590    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, multiSampleCount),
    557591    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, autogenFilter),
     592# ifdef VMSVGA3D_DIRECT3D
     593    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format), /** @todo format duplicated. */
     594    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, formatD3D),
     595    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fUsageD3D),
     596    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, multiSampleTypeD3D),
     597# endif
    558598    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cbBlock),
    559599    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fDirty),
     600# ifdef VMSVGA3D_DIRECT3D
     601    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, hSharedObject),
     602    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, pQuery),
     603    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, u.pSurface),
     604    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, bounce.pTexture),
     605    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, pSharedObjectTree),
     606    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fStencilAsTexture),
     607# endif
    560608    SSMFIELD_ENTRY_TERM()
    561609};
    562 
    563 typedef struct
     610#endif
     611
     612
     613typedef struct VMSVGA3DSHADER
    564614{
    565615    uint32_t                        id;
     
    570620    union
    571621    {
     622#ifdef VMSVGA3D_DIRECT3D
     623        IDirect3DVertexShader9     *pVertexShader;
     624        IDirect3DPixelShader9      *pPixelShader;
     625#else
    572626        void                       *pVertexShader;
    573627        void                       *pPixelShader;
     628#endif
     629        void                       *pv;
    574630    } u;
    575 } VMSVGA3DSHADER, *PVMSVGA3DSHADER;
    576 
     631} VMSVGA3DSHADER;
     632typedef VMSVGA3DSHADER *PVMSVGA3DSHADER;
     633
     634#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
    577635/**
    578636 * SSM descriptor table for the VMSVGA3DSHADER structure.
     
    585643    SSMFIELD_ENTRY(                 VMSVGA3DSHADER, cbData),
    586644    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, pShaderProgram),
    587     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, u.pVertexShader),
     645    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, u.pv),
    588646    SSMFIELD_ENTRY_TERM()
    589647};
    590 
    591 typedef struct
    592 {
    593     bool        fValid;
    594     float       matrix[16];
    595 } VMSVGATRANSFORMSTATE, *PVMSVGATRANSFORMSTATE;
    596 
    597 typedef struct
    598 {
    599     bool            fValid;
    600     SVGA3dMaterial  material;
    601 } VMSVGAMATERIALSTATE, *PVMSVGAMATERIALSTATE;
    602 
    603 typedef struct
    604 {
    605     bool            fValid;
    606     float           plane[4];
    607 } VMSVGACLIPPLANESTATE, *PVMSVGACLIPPLANESTATE;
    608 
    609 typedef struct
    610 {
    611     bool            fEnabled;
    612     bool            fValidData;
    613     SVGA3dLightData data;
    614 } VMSVGALIGHTSTATE, *PVMSVGALIGHTSTATE;
    615 
    616 typedef struct
    617 {
    618     bool                    fValid;
    619     SVGA3dShaderConstType   ctype;
    620     uint32_t                value[4];
    621 } VMSVGASHADERCONST, *PVMSVGASHADERCONST;
    622 
    623 /**
    624  * SSM descriptor table for the VMSVGASHADERCONST structure.
    625  */
    626 static SSMFIELD const g_aVMSVGASHADERCONSTFields[] =
    627 {
    628     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, fValid),
    629     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, ctype),
    630     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, value),
    631     SSMFIELD_ENTRY_TERM()
    632 };
    633 
    634 #define VMSVGA3D_UPDATE_SCISSORRECT     RT_BIT(0)
    635 #define VMSVGA3D_UPDATE_ZRANGE          RT_BIT(1)
    636 #define VMSVGA3D_UPDATE_VIEWPORT        RT_BIT(2)
    637 #define VMSVGA3D_UPDATE_VERTEXSHADER    RT_BIT(3)
    638 #define VMSVGA3D_UPDATE_PIXELSHADER     RT_BIT(4)
    639 #define VMSVGA3D_UPDATE_TRANSFORM       RT_BIT(5)
    640 #define VMSVGA3D_UPDATE_MATERIAL        RT_BIT(6)
    641 
     648#endif
     649
     650/** @name VMSVGA3D_UPDATE_XXX - ...
     651 * @{ */
     652#define VMSVGA3D_UPDATE_SCISSORRECT    RT_BIT_32(0)
     653#define VMSVGA3D_UPDATE_ZRANGE         RT_BIT_32(1)
     654#define VMSVGA3D_UPDATE_VIEWPORT       RT_BIT_32(2)
     655#define VMSVGA3D_UPDATE_VERTEXSHADER   RT_BIT_32(3)
     656#define VMSVGA3D_UPDATE_PIXELSHADER    RT_BIT_32(4)
     657#define VMSVGA3D_UPDATE_TRANSFORM      RT_BIT_32(5)
     658#define VMSVGA3D_UPDATE_MATERIAL       RT_BIT_32(6)
     659/** @} */
     660
     661/**
     662 * VMSVGA3d context.
     663 */
    642664typedef struct VMSVGA3DCONTEXT
    643665{
    644666    uint32_t                id;
    645667#ifdef RT_OS_WINDOWS
     668# ifdef VMSVGA3D_DIRECT3D
     669#  ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
     670    IDirect3DDevice9       *pDevice;
     671#  else
     672    IDirect3DDevice9Ex     *pDevice;
     673#  endif
     674# else
    646675    /* Device context of the context window. */
    647676    HDC                     hdc;
    648677    /* OpenGL rendering context handle. */
    649678    HGLRC                   hglrc;
     679# endif
    650680    /* Device context window handle. */
    651681    HWND                    hwnd;
     
    663693    bool                    fMapped;
    664694#endif
     695
     696#ifdef VMSVGA3D_OPENGL
    665697    /* Framebuffer object associated with this context. */
    666698    GLuint                  idFramebuffer;
     
    670702    /* Last GL error recorded. */
    671703    GLenum                  lastError;
     704    void                   *pShaderContext;
     705#endif
    672706
    673707    /* Current active render target (if any) */
     
    680714    uint32_t                cVertexShaders;
    681715    PVMSVGA3DSHADER         paVertexShader;
    682     void                   *pShaderContext;
    683716    /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
    684717    struct
    685718    {
     719        /** VMSVGA3D_UPDATE_XXX */
    686720        uint32_t                u32UpdateFlags;
    687721
     
    705739        PVMSVGASHADERCONST      paVertexShaderConst;
    706740    } state;
    707 } VMSVGA3DCONTEXT, *PVMSVGA3DCONTEXT;
    708 
     741} VMSVGA3DCONTEXT;
     742/** Pointer to a VMSVGA3d context. */
     743typedef VMSVGA3DCONTEXT *PVMSVGA3DCONTEXT;
     744
     745#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
    709746/**
    710747 * SSM descriptor table for the VMSVGA3DCONTEXT structure.
     
    713750{
    714751    SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, id),
    715 #ifdef RT_OS_WINDOWS
     752
     753# ifdef RT_OS_WINDOWS
     754#  ifdef VMSVGA3D_DIRECT3D
     755    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, pDevice),
     756#  else
    716757    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hdc),
    717758    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hglrc),
     759#  endif
    718760    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hwnd),
    719 #endif
    720 
     761# elif defined(RT_OS_DARWIN)
     762    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, cocoaContext),
     763    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, cocoaView),
     764    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, fOtherProfile),
     765# else
     766    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, glxContext),
     767    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, window),
     768    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, fMapped),
     769# endif
     770
     771#ifdef VMSVGA3D_OPENGL
    721772    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, idFramebuffer),
    722773    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, idReadFramebuffer),
    723774    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, idDrawFramebuffer),
    724775    SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, lastError),
     776    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, pShaderContext),
     777#endif
    725778
    726779    SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, sidRenderTarget),
     
    730783    SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, cVertexShaders),
    731784    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, paVertexShader),
    732     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, pShaderContext),
    733785    SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.u32UpdateFlags),
    734786
     
    752804    SSMFIELD_ENTRY_TERM()
    753805};
     806#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
     807
    754808
    755809/**
     
    760814typedef struct VMSVGA3DSTATE
    761815{
     816    /** The size of papContexts. */
     817    uint32_t                cContexts;
     818    /** The size of papSurfaces. */
     819    uint32_t                cSurfaces;
     820    /** Contexts indexed by ID.  Grown as needed. */
     821    PVMSVGA3DCONTEXT       *papContexts;
     822    /** Surfaces indexed by ID.  Grown as needed. */
     823    PVMSVGA3DSURFACE       *papSurfaces;
     824
    762825#ifdef RT_OS_WINDOWS
     826# ifdef VMSVGA3D_DIRECT3D
     827#  ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
     828    IDirect3D9             *pD3D9;
     829#  else
     830    IDirect3D9Ex           *pD3D9;
     831#  endif
     832    D3DCAPS9                caps;
     833    bool                    fSupportedSurfaceINTZ;
     834    bool                    fSupportedSurfaceNULL;
     835# endif
    763836    /** Window Thread. */
    764837    R3PTRTYPE(RTTHREAD)     pWindowThread;
     
    767840    /** Window request semaphore. */
    768841    RTSEMEVENT              WndRequestSem;
    769 #elif defined(RT_OS_LINUX)
     842#elif defined(RT_OS_DARWIN)
     843#else
    770844    /* The X display */
    771     Display                 *display;
    772     R3PTRTYPE(RTTHREAD)    pWindowThread;
     845    Display                *display;
     846    R3PTRTYPE(RTTHREAD)     pWindowThread;
    773847    bool                    bTerminate;
    774848#endif
    775849
     850#ifdef VMSVGA3D_OPENGL
    776851    float                   fGLVersion;
    777852    /* Current active context. */
     
    849924    } caps;
    850925
    851     uint32_t                cContexts;
    852     PVMSVGA3DCONTEXT       *papContexts;
    853     uint32_t                cSurfaces;
    854     PVMSVGA3DSURFACE       *papSurfaces;
    855 #ifdef DEBUG_GFX_WINDOW_TEST_CONTEXT
    856     uint32_t                idTestContext;
    857 #endif
    858926    /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
    859927     * Free with RTStrFree. */
     
    873941    VBOXVMSVGASHADERIF      ShaderIf;
    874942
    875 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
     943# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    876944    /** The shared context. */
    877945    VMSVGA3DCONTEXT         SharedCtx;
    878 #endif
     946# endif
     947#endif /* VMSVGA3D_OPENGL */
    879948} VMSVGA3DSTATE;
    880949
     950#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
    881951/**
    882952 * SSM descriptor table for the VMSVGA3DSTATE structure.
     953 *
     954 * @remarks This isn't a complete structure markup, only fields with state.
    883955 */
    884956static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
    885957{
    886 #ifdef RT_OS_WINDOWS
    887     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, pWindowThread),
    888     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, idWindowThread),
    889     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, hInstance),
    890     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, WndRequestSem),
    891 #elif defined(RT_OS_LINUX)
    892     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, display),
    893     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, pWindowThread),
    894     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, bTerminate),
    895 #endif
    896     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, fGLVersion),
    897     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, idActiveContext),
    898 
    899     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, ext),
    900     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, caps),
    901 
     958# ifdef VMSVGA3D_OPENGL
     959    SSMFIELD_ENTRY(                 VMSVGA3DSTATE, fGLVersion), /** @todo Why are we saving the GL version?? */
     960# endif
    902961    SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cContexts),
    903     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papContexts),
    904962    SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cSurfaces),
    905     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papSurfaces),
    906963    SSMFIELD_ENTRY_TERM()
    907964};
    908 
    909 
     965#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
     966
     967
     968#ifdef VMSVGA3D_OPENGL
    910969/** Save and setup everything. */
    911 #define VMSVGA3D_PARANOID_TEXTURE_PACKING
     970# define VMSVGA3D_PARANOID_TEXTURE_PACKING
    912971
    913972/**
     
    932991typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
    933992
    934 
    935 /*******************************************************************************
    936 *   Global Variables                                                           *
    937 *******************************************************************************/
    938 /* Define the default light parameters as specified by MSDN. */
    939 /* @todo move out; fetched from Wine */
    940 const SVGA3dLightData vmsvga3d_default_light =
    941 {
    942     SVGA3D_LIGHTTYPE_DIRECTIONAL,   /* type */
    943     false,                          /* inWorldSpace */
    944     { 1.0f, 1.0f, 1.0f, 0.0f },     /* diffuse r,g,b,a */
    945     { 0.0f, 0.0f, 0.0f, 0.0f },     /* specular r,g,b,a */
    946     { 0.0f, 0.0f, 0.0f, 0.0f },     /* ambient r,g,b,a, */
    947     { 0.0f, 0.0f, 0.0f },           /* position x,y,z */
    948     { 0.0f, 0.0f, 1.0f },           /* direction x,y,z */
    949     0.0f,                           /* range */
    950     0.0f,                           /* falloff */
    951     0.0f, 0.0f, 0.0f,               /* attenuation 0,1,2 */
    952     0.0f,                           /* theta */
    953     0.0f                            /* phi */
    954 };
    955 
    956 
    957 /*******************************************************************************
    958 *   Internal Functions                                                         *
    959 *******************************************************************************/
    960 static int  vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
    961 static int  vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
    962 static int  vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid);
    963 static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha);
    964 static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    965                                   PVMSVGAPACKPARAMS pSave);
    966 static void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    967                                       PCVMSVGAPACKPARAMS pSave);
    968 
    969 /* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */
    970 extern "C" int ExplicitlyLoadVBoxSVGA3D(bool fResolveAllImports, PRTERRINFO pErrInfo);
    971 #ifdef RT_OS_DARWIN
    972 extern "C" int ExplicitlyLoadVBoxSVGA3DObjC(bool fResolveAllImports, PRTERRINFO pErrInfo);
    973 #endif
    974 
    975 
    976 /**
    977  * Checks if the given OpenGL extension is supported.
    978  *
    979  * @returns true if supported, false if not.
    980  * @param   pState              The VMSVGA3d state.
    981  * @param   fActualGLVersion    The actual OpenGL version we're working against.
    982  * @param   fMinGLVersion       The OpenGL version that introduced this feature
    983  *                              into the core.
    984  * @param   pszWantedExtension  The name of the OpenGL extension we want padded
    985  *                              with one space at each end.
    986  * @remarks Init time only.
    987  */
    988 static bool vmsvga3dCheckGLExtension(PVMSVGA3DSTATE pState, float fMinGLVersion, const char *pszWantedExtension)
    989 {
    990     /* check padding. */
    991     Assert(pszWantedExtension[0] == ' ');
    992     Assert(pszWantedExtension[1] != ' ');
    993     Assert(strchr(&pszWantedExtension[1], ' ') + 1 == strchr(pszWantedExtension, '\0'));
    994 
    995     /* Look it up. */
    996     bool fRet = false;
    997     if (strstr(pState->pszExtensions, pszWantedExtension))
    998         fRet = true;
    999 
    1000     /* Temporarily.  Later start if (fMinGLVersion != 0.0 && fActualGLVersion >= fMinGLVersion) return true; */
    1001 #ifdef RT_OS_DARWIN
    1002     AssertMsg(   fMinGLVersion == 0.0
    1003               || fRet == (pState->fGLVersion >= fMinGLVersion)
    1004               || VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE == 2.1,
    1005               ("%s actual:%d min:%d fRet=%d\n",
    1006                pszWantedExtension, (int)(pState->fGLVersion * 10), (int)(fMinGLVersion * 10), fRet));
    1007 #else
    1008     AssertMsg(fMinGLVersion == 0.0 || fRet == (pState->fGLVersion >= fMinGLVersion),
    1009               ("%s actual:%d min:%d fRet=%d\n",
    1010                pszWantedExtension, (int)(pState->fGLVersion * 10), (int)(fMinGLVersion * 10), fRet));
    1011 #endif
    1012     return fRet;
    1013 }
    1014 
    1015 
    1016 /**
    1017  * Outputs GL_EXTENSIONS list to the release log.
    1018  */
    1019 static void vmsvga3dLogRelExtensions(const char *pszPrefix, const char *pszExtensions)
    1020 {
    1021     /* OpenGL 3.0 interface (glGetString(GL_EXTENSIONS) return NULL). */
    1022     bool fBuffered = RTLogRelSetBuffering(true);
    1023 
    1024     /*
    1025      * Determin the column widths first.
    1026      */
    1027     size_t   acchWidths[4] = { 1, 1, 1, 1 };
    1028     uint32_t i;
    1029     const char *psz = pszExtensions;
    1030     for (i = 0; ; i++)
    1031     {
    1032         while (*psz == ' ')
    1033             psz++;
    1034         if (!*psz)
    1035             break;
    1036 
    1037         const char *pszEnd = strchr(psz, ' ');
    1038         AssertBreak(pszEnd);
    1039         size_t cch = pszEnd - psz;
    1040 
    1041         uint32_t iColumn = i % RT_ELEMENTS(acchWidths);
    1042         if (acchWidths[iColumn] < cch)
    1043             acchWidths[iColumn] = cch;
    1044 
    1045         psz = pszEnd;
    1046     }
    1047 
    1048     /*
    1049      * Output it.
    1050      */
    1051     LogRel(("VMSVGA3d: %sOpenGL extensions (%d):", pszPrefix, i));
    1052     psz = pszExtensions;
    1053     for (i = 0; ; i++)
    1054     {
    1055         while (*psz == ' ')
    1056             psz++;
    1057         if (!*psz)
    1058             break;
    1059 
    1060         const char *pszEnd = strchr(psz, ' ');
    1061         AssertBreak(pszEnd);
    1062         size_t cch = pszEnd - psz;
    1063 
    1064         uint32_t iColumn = i % RT_ELEMENTS(acchWidths);
    1065         if (iColumn == 0)
    1066             LogRel(("\nVMSVGA3d:  %-*.*s", acchWidths[iColumn], cch, psz));
    1067         else if (iColumn != RT_ELEMENTS(acchWidths) - 1)
    1068             LogRel((" %-*.*s", acchWidths[iColumn], cch, psz));
    1069         else
    1070             LogRel((" %.*s", cch, psz));
    1071 
    1072         psz = pszEnd;
    1073     }
    1074 
    1075     RTLogRelSetBuffering(fBuffered);
    1076     LogRel(("\n"));
    1077 }
    1078 
    1079 /**
    1080  * Gathers the GL_EXTENSIONS list, storing it as a space padded list at
    1081  * @a ppszExtensions.
    1082  *
    1083  * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY
    1084  * @param   ppszExtensions      Pointer to the string pointer. Free with RTStrFree.
    1085  * @param   fGLProfileVersion   The OpenGL profile version.
    1086  */
    1087 static int vmsvga3dGatherExtensions(char **ppszExtensions, float fGLProfileVersion)
    1088 {
    1089     int rc;
    1090     *ppszExtensions = NULL;
    1091 
    1092     /*
    1093      * Try the old glGetString interface first.
    1094      */
    1095     const char *pszExtensions = (const char *)glGetString(GL_EXTENSIONS);
    1096     if (pszExtensions)
    1097     {
    1098         rc = RTStrAAppendExN(ppszExtensions, 3, " ", (size_t)1, pszExtensions, RTSTR_MAX, " ", (size_t)1);
    1099         AssertLogRelRCReturn(rc, rc);
    1100     }
    1101     else
    1102     {
    1103         /*
    1104          * The new interface where each extension string is retrieved separately.
    1105          * Note! Cannot use VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE here because
    1106          *       the above GL_EXTENSIONS error lingers on darwin. sucks.
    1107          */
    1108 #ifndef GL_NUM_EXTENSIONS
    1109 # define GL_NUM_EXTENSIONS 0x821D
    1110 #endif
    1111         GLint cExtensions = 1024;
    1112         glGetIntegerv(GL_NUM_EXTENSIONS, &cExtensions);
    1113         Assert(cExtensions != 1024);
    1114 
    1115         PFNGLGETSTRINGIPROC pfnGlGetStringi = (PFNGLGETSTRINGIPROC)OGLGETPROCADDRESS("glGetStringi");
    1116         AssertLogRelReturn(pfnGlGetStringi, VERR_NOT_SUPPORTED);
    1117 
    1118         rc = RTStrAAppend(ppszExtensions, " ");
    1119         for (GLint i = 0; RT_SUCCESS(rc) && i < cExtensions; i++)
    1120         {
    1121             const char *pszExt = (const char *)pfnGlGetStringi(GL_EXTENSIONS, i);
    1122             if (pszExt)
    1123                 rc = RTStrAAppendExN(ppszExtensions, 2, pfnGlGetStringi(GL_EXTENSIONS, i), RTSTR_MAX, " ", (size_t)1);
    1124         }
    1125         AssertRCReturn(rc, rc);
    1126     }
    1127 
    1128 #if 1
    1129     /*
    1130      * Add extensions promoted into the core OpenGL profile.
    1131      */
    1132     static const struct
    1133     {
    1134         float fGLVersion;
    1135         const char *pszzExtensions;
    1136     } s_aPromotedExtensions[] =
    1137     {
    1138         {
    1139             1.1f,
    1140             " GL_EXT_vertex_array \0"
    1141             " GL_EXT_polygon_offset \0"
    1142             " GL_EXT_blend_logic_op \0"
    1143             " GL_EXT_texture \0"
    1144             " GL_EXT_copy_texture \0"
    1145             " GL_EXT_subtexture \0"
    1146             " GL_EXT_texture_object \0"
    1147             " GL_ARB_framebuffer_object \0"
    1148             " GL_ARB_map_buffer_range \0"
    1149             " GL_ARB_vertex_array_object \0"
    1150             "\0"
    1151         },
    1152         {
    1153             1.2f,
    1154             " EXT_texture3D \0"
    1155             " EXT_bgra \0"
    1156             " EXT_packed_pixels \0"
    1157             " EXT_rescale_normal \0"
    1158             " EXT_separate_specular_color \0"
    1159             " SGIS_texture_edge_clamp \0"
    1160             " SGIS_texture_lod \0"
    1161             " EXT_draw_range_elements \0"
    1162             "\0"
    1163         },
    1164         {
    1165             1.3f,
    1166             " GL_ARB_texture_compression \0"
    1167             " GL_ARB_texture_cube_map \0"
    1168             " GL_ARB_multisample \0"
    1169             " GL_ARB_multitexture \0"
    1170             " GL_ARB_texture_env_add \0"
    1171             " GL_ARB_texture_env_combine \0"
    1172             " GL_ARB_texture_env_dot3 \0"
    1173             " GL_ARB_texture_border_clamp \0"
    1174             " GL_ARB_transpose_matrix \0"
    1175             "\0"
    1176         },
    1177         {
    1178             1.5f,
    1179             " GL_SGIS_generate_mipmap \0"
    1180             /*" GL_NV_blend_equare \0"*/
    1181             " GL_ARB_depth_texture \0"
    1182             " GL_ARB_shadow \0"
    1183             " GL_EXT_fog_coord \0"
    1184             " GL_EXT_multi_draw_arrays \0"
    1185             " GL_ARB_point_parameters \0"
    1186             " GL_EXT_secondary_color \0"
    1187             " GL_EXT_blend_func_separate \0"
    1188             " GL_EXT_stencil_wrap \0"
    1189             " GL_ARB_texture_env_crossbar \0"
    1190             " GL_EXT_texture_lod_bias \0"
    1191             " GL_ARB_texture_mirrored_repeat \0"
    1192             " GL_ARB_window_pos \0"
    1193             "\0"
    1194         },
    1195         {
    1196             1.6f,
    1197             " GL_ARB_vertex_buffer_object \0"
    1198             " GL_ARB_occlusion_query \0"
    1199             " GL_EXT_shadow_funcs \0"
    1200         },
    1201         {
    1202             2.0f,
    1203             " GL_ARB_shader_objects \0" /*??*/
    1204             " GL_ARB_vertex_shader \0" /*??*/
    1205             " GL_ARB_fragment_shader \0" /*??*/
    1206             " GL_ARB_shading_language_100 \0" /*??*/
    1207             " GL_ARB_draw_buffers \0"
    1208             " GL_ARB_texture_non_power_of_two \0"
    1209             " GL_ARB_point_sprite \0"
    1210             " GL_ATI_separate_stencil \0"
    1211             " GL_EXT_stencil_two_side \0"
    1212             "\0"
    1213         },
    1214         {
    1215             2.1f,
    1216             " GL_ARB_pixel_buffer_object \0"
    1217             " GL_EXT_texture_sRGB \0"
    1218             "\0"
    1219         },
    1220         {
    1221             3.0f,
    1222             " GL_ARB_framebuffer_object \0"
    1223             " GL_ARB_map_buffer_range \0"
    1224             " GL_ARB_vertex_array_object \0"
    1225             "\0"
    1226         },
    1227         {
    1228             3.1f,
    1229             " GL_ARB_copy_buffer \0"
    1230             " GL_ARB_uniform_buffer_object \0"
    1231             "\0"
    1232         },
    1233         {
    1234             3.2f,
    1235             " GL_ARB_vertex_array_bgra \0"
    1236             " GL_ARB_draw_elements_base_vertex \0"
    1237             " GL_ARB_fragment_coord_conventions \0"
    1238             " GL_ARB_provoking_vertex \0"
    1239             " GL_ARB_seamless_cube_map \0"
    1240             " GL_ARB_texture_multisample \0"
    1241             " GL_ARB_depth_clamp \0"
    1242             " GL_ARB_sync \0"
    1243             " GL_ARB_geometry_shader4 \0" /*??*/
    1244             "\0"
    1245         },
    1246         {
    1247             3.3f,
    1248             " GL_ARB_blend_func_extended \0"
    1249             " GL_ARB_sampler_objects \0"
    1250             " GL_ARB_explicit_attrib_location \0"
    1251             " GL_ARB_occlusion_query2 \0"
    1252             " GL_ARB_shader_bit_encoding \0"
    1253             " GL_ARB_texture_rgb10_a2ui \0"
    1254             " GL_ARB_texture_swizzle \0"
    1255             " GL_ARB_timer_query \0"
    1256             " GL_ARB_vertex_type_2_10_10_10_rev \0"
    1257             "\0"
    1258         },
    1259         {
    1260             4.0f,
    1261             " GL_ARB_texture_query_lod \0"
    1262             " GL_ARB_draw_indirect \0"
    1263             " GL_ARB_gpu_shader5 \0"
    1264             " GL_ARB_gpu_shader_fp64 \0"
    1265             " GL_ARB_shader_subroutine \0"
    1266             " GL_ARB_tessellation_shader \0"
    1267             " GL_ARB_texture_buffer_object_rgb32 \0"
    1268             " GL_ARB_texture_cube_map_array \0"
    1269             " GL_ARB_texture_gather \0"
    1270             " GL_ARB_transform_feedback2 \0"
    1271             " GL_ARB_transform_feedback3 \0"
    1272             "\0"
    1273         },
    1274         {
    1275             4.1f,
    1276             " GL_ARB_ES2_compatibility \0"
    1277             " GL_ARB_get_program_binary \0"
    1278             " GL_ARB_separate_shader_objects \0"
    1279             " GL_ARB_shader_precision \0"
    1280             " GL_ARB_vertex_attrib_64bit \0"
    1281             " GL_ARB_viewport_array \0"
    1282             "\0"
    1283         }
    1284     };
    1285 
    1286     uint32_t cPromoted = 0;
    1287     for (uint32_t i = 0; i < RT_ELEMENTS(s_aPromotedExtensions) && s_aPromotedExtensions[i].fGLVersion <= fGLProfileVersion; i++)
    1288     {
    1289         const char *pszExt = s_aPromotedExtensions[i].pszzExtensions;
    1290         while (*pszExt)
    1291         {
    1292             size_t cchExt = strlen(pszExt);
    1293             Assert(cchExt > 3);
    1294             Assert(pszExt[0] == ' ');
    1295             Assert(pszExt[1] != ' ');
    1296             Assert(pszExt[cchExt - 2] != ' ');
    1297             Assert(pszExt[cchExt - 1] == ' ');
    1298 
    1299             if (strstr(*ppszExtensions, pszExt) == NULL)
    1300             {
    1301                 if (cPromoted++ == 0)
    1302                 {
    1303                     rc = RTStrAAppend(ppszExtensions, " <promoted-extensions:> <promoted-extensions:> <promoted-extensions:> ");
    1304                     AssertRCReturn(rc, rc);
    1305                 }
    1306 
    1307                 rc = RTStrAAppend(ppszExtensions, pszExt);
    1308                 AssertRCReturn(rc, rc);
    1309             }
    1310 
    1311             pszExt = strchr(pszExt, '\0') + 1;
    1312         }
    1313     }
    1314 #endif
    1315 
    1316     return VINF_SUCCESS;
    1317 }
    1318 
    1319 /**
    1320  * @interface_method_impl{VBOXVMSVGASHADERIF, pfnSwitchInitProfile}
    1321  */
    1322 static DECLCALLBACK(void) vmsvga3dShaderIfSwitchInitProfile(PVBOXVMSVGASHADERIF pThis, bool fOtherProfile)
    1323 {
    1324 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    1325     PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
    1326     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pState->papContexts[fOtherProfile ? 2 : 1]);
    1327 #else
    1328     NOREF(pThis);
    1329     NOREF(fOtherProfile);
    1330 #endif
    1331 }
    1332 
    1333 
    1334 /**
    1335  * @interface_method_impl{VBOXVMSVGASHADERIF, pfnGetNextExtension}
    1336  */
    1337 static DECLCALLBACK(bool) vmsvga3dShaderIfGetNextExtension(PVBOXVMSVGASHADERIF pThis, void **ppvEnumCtx,
    1338                                                            char *pszBuf, size_t cbBuf, bool fOtherProfile)
    1339 {
    1340     PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
    1341     const char    *pszCur = *ppvEnumCtx ? (const char *)*ppvEnumCtx
    1342                           : fOtherProfile ? pState->pszOtherExtensions : pState->pszExtensions;
    1343     while (*pszCur == ' ')
    1344         pszCur++;
    1345     if (!*pszCur)
    1346         return false;
    1347 
    1348     const char *pszEnd = strchr(pszCur, ' ');
    1349     AssertReturn(pszEnd, false);
    1350     size_t cch = pszEnd - pszCur;
    1351     if (cch < cbBuf)
    1352     {
    1353         memcpy(pszBuf, pszCur, cch);
    1354         pszBuf[cch] = '\0';
    1355     }
    1356     else if (cbBuf > 0)
    1357     {
    1358         memcpy(pszBuf, "<overflow>", RT_MIN(sizeof("<overflow>"), cbBuf));
    1359         pszBuf[cbBuf - 1] = '\0';
    1360     }
    1361 
    1362     *ppvEnumCtx = (void *)pszEnd;
    1363     return true;
    1364 }
    1365 
    1366 
    1367 /**
    1368  * Initializes the VMSVGA3D state during VGA device construction.
    1369  *
    1370  * Failure are generally not fatal, 3D support will just be disabled.
    1371  *
    1372  * @returns VBox status code.
    1373  * @param   pThis   The VGA device state where svga.p3dState will be modified.
    1374  */
    1375 int vmsvga3dInit(PVGASTATE pThis)
    1376 {
    1377     AssertCompile(GL_TRUE == 1);
    1378     AssertCompile(GL_FALSE == 0);
    1379 
    1380     /*
    1381      * Load and resolve imports from the external shared libraries.
    1382      */
    1383     RTERRINFOSTATIC ErrInfo;
    1384     int rc = ExplicitlyLoadVBoxSVGA3D(true /*fResolveAllImports*/, RTErrInfoInitStatic(&ErrInfo));
    1385     if (RT_FAILURE(rc))
    1386     {
    1387         LogRel(("VMSVGA3d: Error loading VBoxSVGA3D and resolving necessary functions: %Rrc - %s\n", rc, ErrInfo.Core.pszMsg));
    1388         return rc;
    1389     }
    1390 #ifdef RT_OS_DARWIN
    1391     rc = ExplicitlyLoadVBoxSVGA3DObjC(true /*fResolveAllImports*/, RTErrInfoInitStatic(&ErrInfo));
    1392     if (RT_FAILURE(rc))
    1393     {
    1394         LogRel(("VMSVGA3d: Error loading VBoxSVGA3DObjC and resolving necessary functions: %Rrc - %s\n", rc, ErrInfo.Core.pszMsg));
    1395         return rc;
    1396     }
    1397 #endif
    1398 
    1399     /*
    1400      * Allocate the state.
    1401      */
    1402     pThis->svga.p3dState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
    1403     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
    1404 
    1405 #ifdef RT_OS_WINDOWS
    1406     /* Create event semaphore and async IO thread. */
    1407     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    1408     rc = RTSemEventCreate(&pState->WndRequestSem);
    1409     if (RT_SUCCESS(rc))
    1410     {
    1411         rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dWindowThread, pState->WndRequestSem, 0, RTTHREADTYPE_GUI, 0,
    1412                             "VMSVGA3DWND");
    1413         if (RT_SUCCESS(rc))
    1414             return VINF_SUCCESS;
    1415 
    1416         /* bail out. */
    1417         LogRel(("VMSVGA3d: RTThreadCreate failed: %Rrc\n", rc));
    1418         RTSemEventDestroy(pState->WndRequestSem);
    1419     }
    1420     else
    1421         LogRel(("VMSVGA3d: RTSemEventCreate failed: %Rrc\n", rc));
    1422     RTMemFree(pThis->svga.p3dState);
    1423     pThis->svga.p3dState = NULL;
    1424     return rc;
    1425 #else
    1426     return VINF_SUCCESS;
    1427 #endif
    1428 }
    1429 
    1430 /* We must delay window creation until the PowerOn phase. Init is too early and will cause failures. */
    1431 int vmsvga3dPowerOn(PVGASTATE pThis)
    1432 {
    1433     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    1434     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
    1435     PVMSVGA3DCONTEXT pContext;
    1436 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    1437     PVMSVGA3DCONTEXT pOtherCtx;
    1438 #endif
    1439     int              rc;
    1440 
    1441     if (pState->fGLVersion != 0.0)
    1442         return VINF_SUCCESS;    /* already initialized (load state) */
    1443 
    1444     /*
    1445      * OpenGL function calls aren't possible without a valid current context, so create a fake one here.
    1446      */
    1447     rc = vmsvga3dContextDefineOgl(pThis, 1, VMSVGA3D_DEF_CTX_F_INIT);
    1448     AssertRCReturn(rc, rc);
    1449 
    1450     pContext = pState->papContexts[1];
    1451     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1452 
    1453     LogRel(("VMSVGA3d: OpenGL version: %s\n"
    1454             "VMSVGA3d: OpenGL Vendor: %s\n"
    1455             "VMSVGA3d: OpenGL Renderer: %s\n"
    1456             "VMSVGA3d: OpenGL shader language version: %s\n",
    1457             glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER),
    1458             glGetString(GL_SHADING_LANGUAGE_VERSION)));
    1459 
    1460     rc = vmsvga3dGatherExtensions(&pState->pszExtensions, VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE);
    1461     AssertRCReturn(rc, rc);
    1462     vmsvga3dLogRelExtensions("", pState->pszExtensions);
    1463 
    1464     pState->fGLVersion = atof((const char *)glGetString(GL_VERSION));
    1465 
    1466 
    1467 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    1468     /*
    1469      * Get the extension list for the alternative profile so we can better
    1470      * figure out the shader model and stuff.
    1471      */
    1472     rc = vmsvga3dContextDefineOgl(pThis, 2, VMSVGA3D_DEF_CTX_F_INIT | VMSVGA3D_DEF_CTX_F_OTHER_PROFILE);
    1473     AssertLogRelRCReturn(rc, rc);
    1474     pContext = pState->papContexts[1]; /* Array may have been reallocated. */
    1475 
    1476     pOtherCtx = pState->papContexts[2];
    1477     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pOtherCtx);
    1478 
    1479     LogRel(("VMSVGA3d: Alternative OpenGL version: %s\n"
    1480             "VMSVGA3d: Alternative OpenGL Vendor: %s\n"
    1481             "VMSVGA3d: Alternative OpenGL Renderer: %s\n"
    1482             "VMSVGA3d: Alternative OpenGL shader language version: %s\n",
    1483             glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER),
    1484             glGetString(GL_SHADING_LANGUAGE_VERSION)));
    1485 
    1486     rc = vmsvga3dGatherExtensions(&pState->pszOtherExtensions, VBOX_VMSVGA3D_OTHER_OGL_PROFILE);
    1487     AssertRCReturn(rc, rc);
    1488     vmsvga3dLogRelExtensions("Alternative ", pState->pszOtherExtensions);
    1489 
    1490     pState->fOtherGLVersion = atof((const char *)glGetString(GL_VERSION));
    1491 
    1492     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1493 #else
    1494     pState->pszOtherExtensions = (char *)"";
    1495     pState->fOtherGLVersion = pState->fGLVersion;
    1496 #endif
    1497 
    1498 
    1499     if (vmsvga3dCheckGLExtension(pState, 3.0f, " GL_ARB_framebuffer_object "))
    1500     {
    1501         pState->ext.glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)OGLGETPROCADDRESS("glIsRenderbuffer");
    1502         pState->ext.glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)OGLGETPROCADDRESS("glBindRenderbuffer");
    1503         pState->ext.glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)OGLGETPROCADDRESS("glDeleteRenderbuffers");
    1504         pState->ext.glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)OGLGETPROCADDRESS("glGenRenderbuffers");
    1505         pState->ext.glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)OGLGETPROCADDRESS("glRenderbufferStorage");
    1506         pState->ext.glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)OGLGETPROCADDRESS("glGetRenderbufferParameteriv");
    1507         pState->ext.glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)OGLGETPROCADDRESS("glIsFramebuffer");
    1508         pState->ext.glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)OGLGETPROCADDRESS("glBindFramebuffer");
    1509         pState->ext.glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)OGLGETPROCADDRESS("glDeleteFramebuffers");
    1510         pState->ext.glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)OGLGETPROCADDRESS("glGenFramebuffers");
    1511         pState->ext.glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)OGLGETPROCADDRESS("glCheckFramebufferStatus");
    1512         pState->ext.glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)OGLGETPROCADDRESS("glFramebufferTexture1D");
    1513         pState->ext.glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)OGLGETPROCADDRESS("glFramebufferTexture2D");
    1514         pState->ext.glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)OGLGETPROCADDRESS("glFramebufferTexture3D");
    1515         pState->ext.glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)OGLGETPROCADDRESS("glFramebufferRenderbuffer");
    1516         pState->ext.glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)OGLGETPROCADDRESS("glGetFramebufferAttachmentParameteriv");
    1517         pState->ext.glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)OGLGETPROCADDRESS("glGenerateMipmap");
    1518         pState->ext.glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)OGLGETPROCADDRESS("glBlitFramebuffer");
    1519         pState->ext.glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)OGLGETPROCADDRESS("glRenderbufferStorageMultisample");
    1520         pState->ext.glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)OGLGETPROCADDRESS("glFramebufferTextureLayer");
    1521     }
    1522     pState->ext.glPointParameterf           = (PFNGLPOINTPARAMETERFPROC)OGLGETPROCADDRESS("glPointParameterf");
    1523     AssertMsgReturn(pState->ext.glPointParameterf, ("glPointParameterf missing"), VERR_NOT_IMPLEMENTED);
    1524 #if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
    1525     pState->ext.glBlendColor                = (PFNGLBLENDCOLORPROC)OGLGETPROCADDRESS("glBlendColor");
    1526     AssertMsgReturn(pState->ext.glBlendColor, ("glBlendColor missing"), VERR_NOT_IMPLEMENTED);
    1527     pState->ext.glBlendEquation             = (PFNGLBLENDEQUATIONPROC)OGLGETPROCADDRESS("glBlendEquation");
    1528     AssertMsgReturn(pState->ext.glBlendEquation, ("glBlendEquation missing"), VERR_NOT_IMPLEMENTED);
    1529 #endif
    1530     pState->ext.glBlendEquationSeparate     = (PFNGLBLENDEQUATIONSEPARATEPROC)OGLGETPROCADDRESS("glBlendEquationSeparate");
    1531     AssertMsgReturn(pState->ext.glBlendEquationSeparate, ("glBlendEquationSeparate missing"), VERR_NOT_IMPLEMENTED);
    1532     pState->ext.glBlendFuncSeparate         = (PFNGLBLENDFUNCSEPARATEPROC)OGLGETPROCADDRESS("glBlendFuncSeparate");
    1533     AssertMsgReturn(pState->ext.glBlendFuncSeparate, ("glBlendFuncSeparate missing"), VERR_NOT_IMPLEMENTED);
    1534     pState->ext.glStencilOpSeparate         = (PFNGLSTENCILOPSEPARATEPROC)OGLGETPROCADDRESS("glStencilOpSeparate");
    1535     AssertMsgReturn(pState->ext.glStencilOpSeparate, ("glStencilOpSeparate missing"), VERR_NOT_IMPLEMENTED);
    1536     pState->ext.glStencilFuncSeparate       = (PFNGLSTENCILFUNCSEPARATEPROC)OGLGETPROCADDRESS("glStencilFuncSeparate");
    1537     AssertMsgReturn(pState->ext.glStencilFuncSeparate, ("glStencilFuncSeparate missing"), VERR_NOT_IMPLEMENTED);
    1538     pState->ext.glBindBuffer                = (PFNGLBINDBUFFERPROC)OGLGETPROCADDRESS("glBindBuffer");
    1539     AssertMsgReturn(pState->ext.glBindBuffer, ("glBindBuffer missing"), VERR_NOT_IMPLEMENTED);
    1540     pState->ext.glDeleteBuffers             = (PFNGLDELETEBUFFERSPROC)OGLGETPROCADDRESS("glDeleteBuffers");
    1541     AssertMsgReturn(pState->ext.glDeleteBuffers, ("glDeleteBuffers missing"), VERR_NOT_IMPLEMENTED);
    1542     pState->ext.glGenBuffers                = (PFNGLGENBUFFERSPROC)OGLGETPROCADDRESS("glGenBuffers");
    1543     AssertMsgReturn(pState->ext.glGenBuffers, ("glGenBuffers missing"), VERR_NOT_IMPLEMENTED);
    1544     pState->ext.glBufferData                = (PFNGLBUFFERDATAPROC)OGLGETPROCADDRESS("glBufferData");
    1545     AssertMsgReturn(pState->ext.glBufferData, ("glBufferData missing"), VERR_NOT_IMPLEMENTED);
    1546     pState->ext.glMapBuffer                 = (PFNGLMAPBUFFERPROC)OGLGETPROCADDRESS("glMapBuffer");
    1547     AssertMsgReturn(pState->ext.glMapBuffer, ("glMapBuffer missing"), VERR_NOT_IMPLEMENTED);
    1548     pState->ext.glUnmapBuffer               = (PFNGLUNMAPBUFFERPROC)OGLGETPROCADDRESS("glUnmapBuffer");
    1549     AssertMsgReturn(pState->ext.glUnmapBuffer, ("glUnmapBuffer missing"), VERR_NOT_IMPLEMENTED);
    1550     pState->ext.glEnableVertexAttribArray   = (PFNGLENABLEVERTEXATTRIBARRAYPROC)OGLGETPROCADDRESS("glEnableVertexAttribArray");
    1551     AssertMsgReturn(pState->ext.glEnableVertexAttribArray, ("glEnableVertexAttribArray missing"), VERR_NOT_IMPLEMENTED);
    1552     pState->ext.glDisableVertexAttribArray  = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)OGLGETPROCADDRESS("glDisableVertexAttribArray");
    1553     AssertMsgReturn(pState->ext.glDisableVertexAttribArray, ("glDisableVertexAttribArray missing"), VERR_NOT_IMPLEMENTED);
    1554     pState->ext.glVertexAttribPointer       = (PFNGLVERTEXATTRIBPOINTERPROC)OGLGETPROCADDRESS("glVertexAttribPointer");
    1555     AssertMsgReturn(pState->ext.glVertexAttribPointer, ("glVertexAttribPointer missing"), VERR_NOT_IMPLEMENTED);
    1556     pState->ext.glFogCoordPointer           = (PFNGLFOGCOORDPOINTERPROC)OGLGETPROCADDRESS("glFogCoordPointer");
    1557     AssertMsgReturn(pState->ext.glFogCoordPointer, ("glFogCoordPointer missing"), VERR_NOT_IMPLEMENTED);
    1558     pState->ext.glActiveTexture             = (PFNGLACTIVETEXTUREPROC)OGLGETPROCADDRESS("glActiveTexture");
    1559     AssertMsgReturn(pState->ext.glActiveTexture, ("glActiveTexture missing"), VERR_NOT_IMPLEMENTED);
    1560 #if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
    1561     pState->ext.glClientActiveTexture       = (PFNGLCLIENTACTIVETEXTUREPROC)OGLGETPROCADDRESS("glClientActiveTexture");
    1562     AssertMsgReturn(pState->ext.glClientActiveTexture, ("glClientActiveTexture missing"), VERR_NOT_IMPLEMENTED);
    1563 #endif
    1564     pState->ext.glGetProgramivARB           = (PFNGLGETPROGRAMIVARBPROC)OGLGETPROCADDRESS("glGetProgramivARB");
    1565     AssertMsgReturn(pState->ext.glGetProgramivARB, ("glGetProgramivARB missing"), VERR_NOT_IMPLEMENTED);
    1566 
    1567     /* OpenGL 3.2 core */
    1568     if (vmsvga3dCheckGLExtension(pState, 3.2f, " GL_ARB_draw_elements_base_vertex "))
    1569     {
    1570         pState->ext.glDrawElementsBaseVertex          = (PFNGLDRAWELEMENTSBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsBaseVertex");
    1571         pState->ext.glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsInstancedBaseVertex");
    1572     }
    1573     else
    1574         LogRel(("VMSVGA3d: missing extension GL_ARB_draw_elements_base_vertex\n"));
    1575 
    1576     /* OpenGL 3.2 core */
    1577     if (vmsvga3dCheckGLExtension(pState, 3.2f, " GL_ARB_provoking_vertex "))
    1578     {
    1579         pState->ext.glProvokingVertex                 = (PFNGLPROVOKINGVERTEXPROC)OGLGETPROCADDRESS("glProvokingVertex");
    1580     }
    1581     else
    1582         LogRel(("VMSVGA3d: missing extension GL_ARB_provoking_vertex\n"));
    1583 
    1584     /* Extension support */
    1585 #if defined(RT_OS_DARWIN)
    1586     /** @todo OpenGL version history suggest this, verify...  */
    1587     pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 2.0f, " GL_EXT_stencil_two_side ");
    1588 #else
    1589     pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 0.0f, " GL_EXT_stencil_two_side ");
    1590 #endif
    1591 
    1592     /*
    1593      * Initialize the capabilities with sensible defaults.
    1594      */
    1595     pState->caps.maxActiveLights               = 1;
    1596     pState->caps.maxTextureBufferSize          = 65536;
    1597     pState->caps.maxTextures                   = 1;
    1598     pState->caps.maxClipDistances              = 4;
    1599     pState->caps.maxColorAttachments           = 1;
    1600     pState->caps.maxRectangleTextureSize       = 2048;
    1601     pState->caps.maxTextureAnisotropy          = 2;
    1602     pState->caps.maxVertexShaderInstructions   = 1024;
    1603     pState->caps.maxFragmentShaderInstructions = 1024;
    1604     pState->caps.vertexShaderVersion           = SVGA3DVSVERSION_NONE;
    1605     pState->caps.fragmentShaderVersion         = SVGA3DPSVERSION_NONE;
    1606     pState->caps.flPointSize[0]                = 1;
    1607     pState->caps.flPointSize[1]                = 1;
    1608 
    1609     /*
    1610      * Query capabilities
    1611      */
    1612     VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_LIGHTS, &pState->caps.maxActiveLights));
    1613     VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &pState->caps.maxTextureBufferSize));
    1614     VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &pState->caps.maxTextures));
    1615 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE /* The alternative profile has a higher number here (ati/darwin). */
    1616     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pOtherCtx);
    1617     VMSVGA3D_INIT_CHECKED_BOTH(pState, pOtherCtx, pContext, glGetIntegerv(GL_MAX_CLIP_DISTANCES, &pState->caps.maxClipDistances));
    1618     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    1619 #else
    1620     VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_CLIP_DISTANCES, &pState->caps.maxClipDistances));
    1621 #endif
    1622     VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &pState->caps.maxColorAttachments));
    1623     VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, &pState->caps.maxRectangleTextureSize));
    1624     VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &pState->caps.maxTextureAnisotropy));
    1625     VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize));
    1626 
    1627     if (pState->ext.glGetProgramivARB)
    1628     {
    1629         VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
    1630                                    pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
    1631                                                                  &pState->caps.maxFragmentShaderTemps));
    1632         VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
    1633                                    pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
    1634                                                                  &pState->caps.maxFragmentShaderInstructions));
    1635         VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
    1636                                    pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
    1637                                                                  &pState->caps.maxVertexShaderTemps));
    1638         VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
    1639                                    pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
    1640                                                                  &pState->caps.maxVertexShaderInstructions));
    1641     }
    1642     pState->caps.fS3TCSupported = vmsvga3dCheckGLExtension(pState, 0.0f, " GL_EXT_texture_compression_s3tc ");
    1643 
    1644     /* http://http://www.opengl.org/wiki/Detecting_the_Shader_Model
    1645      * ARB Assembly Language
    1646      * These are done through testing the presence of extensions. You should test them in this order:
    1647      * GL_NV_gpu_program4: SM 4.0 or better.
    1648      * GL_NV_vertex_program3: SM 3.0 or better.
    1649      * GL_ARB_fragment_program: SM 2.0 or better.
    1650      * ATI does not support higher than SM 2.0 functionality in assembly shaders.
    1651      *
    1652      */
    1653     /** @todo: distinguish between vertex and pixel shaders??? */
    1654     if (   vmsvga3dCheckGLExtension(pState, 0.0f, " GL_NV_gpu_program4 ")
    1655         || strstr(pState->pszOtherExtensions, " GL_NV_gpu_program4 "))
    1656     {
    1657         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_40;
    1658         pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_40;
    1659     }
    1660     else
    1661     if (   vmsvga3dCheckGLExtension(pState, 0.0f, " GL_NV_vertex_program3 ")
    1662         || strstr(pState->pszOtherExtensions, " GL_NV_vertex_program3 ")
    1663         || vmsvga3dCheckGLExtension(pState, 0.0f, " GL_ARB_shader_texture_lod ")  /* Wine claims this suggests SM 3.0 support */
    1664         || strstr(pState->pszOtherExtensions, " GL_ARB_shader_texture_lod ")
    1665         )
    1666     {
    1667         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_30;
    1668         pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_30;
    1669     }
    1670     else
    1671     if (   vmsvga3dCheckGLExtension(pState, 0.0f, " GL_ARB_fragment_program ")
    1672         || strstr(pState->pszOtherExtensions, " GL_ARB_fragment_program "))
    1673     {
    1674         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_20;
    1675         pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_20;
    1676     }
    1677     else
    1678     {
    1679         LogRel(("VMSVGA3D: WARNING: unknown support for assembly shaders!!\n"));
    1680         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_11;
    1681         pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_11;
    1682     }
    1683 
    1684     if (!vmsvga3dCheckGLExtension(pState, 3.2f, " GL_ARB_vertex_array_bgra "))
    1685     {
    1686         /** @todo Intel drivers don't support this extension! */
    1687         LogRel(("VMSVGA3D: WARNING: Missing required extension GL_ARB_vertex_array_bgra (d3dcolor)!!!\n"));
    1688     }
    1689 #if 0
    1690    SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND             = 11,
    1691    SVGA3D_DEVCAP_QUERY_TYPES                       = 15,
    1692    SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING         = 16,
    1693    SVGA3D_DEVCAP_MAX_POINT_SIZE                    = 17,
    1694    SVGA3D_DEVCAP_MAX_SHADER_TEXTURES               = 18,
    1695    SVGA3D_DEVCAP_MAX_VOLUME_EXTENT                 = 21,
    1696    SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT                = 22,
    1697    SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO          = 23,
    1698    SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY            = 24,
    1699    SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT               = 25,
    1700    SVGA3D_DEVCAP_MAX_VERTEX_INDEX                  = 26,
    1701    SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS  = 28,
    1702    SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS           = 29,
    1703    SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS         = 30,
    1704    SVGA3D_DEVCAP_TEXTURE_OPS                       = 31,
    1705    SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8               = 32,
    1706    SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8               = 33,
    1707    SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10            = 34,
    1708    SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5               = 35,
    1709    SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5               = 36,
    1710    SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4               = 37,
    1711    SVGA3D_DEVCAP_SURFACEFMT_R5G6B5                 = 38,
    1712    SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16            = 39,
    1713    SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8      = 40,
    1714    SVGA3D_DEVCAP_SURFACEFMT_ALPHA8                 = 41,
    1715    SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8             = 42,
    1716    SVGA3D_DEVCAP_SURFACEFMT_Z_D16                  = 43,
    1717    SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8                = 44,
    1718    SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8                = 45,
    1719    SVGA3D_DEVCAP_SURFACEFMT_DXT1                   = 46,
    1720    SVGA3D_DEVCAP_SURFACEFMT_DXT2                   = 47,
    1721    SVGA3D_DEVCAP_SURFACEFMT_DXT3                   = 48,
    1722    SVGA3D_DEVCAP_SURFACEFMT_DXT4                   = 49,
    1723    SVGA3D_DEVCAP_SURFACEFMT_DXT5                   = 50,
    1724    SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8           = 51,
    1725    SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10            = 52,
    1726    SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8               = 53,
    1727    SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8               = 54,
    1728    SVGA3D_DEVCAP_SURFACEFMT_CxV8U8                 = 55,
    1729    SVGA3D_DEVCAP_SURFACEFMT_R_S10E5                = 56,
    1730    SVGA3D_DEVCAP_SURFACEFMT_R_S23E8                = 57,
    1731    SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5               = 58,
    1732    SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8               = 59,
    1733    SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5             = 60,
    1734    SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8             = 61,
    1735    SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES        = 63,
    1736    SVGA3D_DEVCAP_SURFACEFMT_V16U16                 = 65,
    1737    SVGA3D_DEVCAP_SURFACEFMT_G16R16                 = 66,
    1738    SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16           = 67,
    1739    SVGA3D_DEVCAP_SURFACEFMT_UYVY                   = 68,
    1740    SVGA3D_DEVCAP_SURFACEFMT_YUY2                   = 69,
    1741    SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES    = 70,
    1742    SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES       = 71,
    1743    SVGA3D_DEVCAP_ALPHATOCOVERAGE                   = 72,
    1744    SVGA3D_DEVCAP_SUPERSAMPLE                       = 73,
    1745    SVGA3D_DEVCAP_AUTOGENMIPMAPS                    = 74,
    1746    SVGA3D_DEVCAP_SURFACEFMT_NV12                   = 75,
    1747    SVGA3D_DEVCAP_SURFACEFMT_AYUV                   = 76,
    1748    SVGA3D_DEVCAP_SURFACEFMT_Z_DF16                 = 79,
    1749    SVGA3D_DEVCAP_SURFACEFMT_Z_DF24                 = 80,
    1750    SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT            = 81,
    1751    SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM              = 82,
    1752    SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM              = 83,
    1753 #endif
    1754 
    1755     LogRel(("VMSVGA3d: Capabilities:\n"));
    1756     LogRel(("VMSVGA3d:   maxActiveLights=%-2d       maxTextures=%-2d           maxTextureBufferSize=%d\n",
    1757             pState->caps.maxActiveLights, pState->caps.maxTextures, pState->caps.maxTextureBufferSize));
    1758     LogRel(("VMSVGA3d:   maxClipDistances=%-2d      maxColorAttachments=%-2d   maxClipDistances=%d\n",
    1759             pState->caps.maxClipDistances, pState->caps.maxColorAttachments, pState->caps.maxClipDistances));
    1760     LogRel(("VMSVGA3d:   maxColorAttachments=%-2d   maxTextureAnisotropy=%-2d  maxRectangleTextureSize=%d\n",
    1761             pState->caps.maxColorAttachments, pState->caps.maxTextureAnisotropy, pState->caps.maxRectangleTextureSize));
    1762     LogRel(("VMSVGA3d:   maxVertexShaderTemps=%-2d  maxVertexShaderInstructions=%d maxFragmentShaderInstructions=%d\n",
    1763             pState->caps.maxVertexShaderTemps, pState->caps.maxVertexShaderInstructions, pState->caps.maxFragmentShaderInstructions));
    1764     LogRel(("VMSVGA3d:   maxFragmentShaderTemps=%d flPointSize={%d.%02u, %d.%02u}\n",
    1765             pState->caps.maxFragmentShaderTemps,
    1766             (int)pState->caps.flPointSize[0], (int)(pState->caps.flPointSize[0] * 100) % 100,
    1767             (int)pState->caps.flPointSize[1], (int)(pState->caps.flPointSize[1] * 100) % 100));
    1768     LogRel(("VMSVGA3d:   fragmentShaderVersion=%-2d vertexShaderVersion=%-2d   fS3TCSupported=%d\n",
    1769             pState->caps.fragmentShaderVersion, pState->caps.vertexShaderVersion, pState->caps.fS3TCSupported));
    1770 
    1771 
    1772     /* Initialize the shader library. */
    1773     pState->ShaderIf.pfnSwitchInitProfile = vmsvga3dShaderIfSwitchInitProfile;
    1774     pState->ShaderIf.pfnGetNextExtension  = vmsvga3dShaderIfGetNextExtension;
    1775     rc = ShaderInitLib(&pState->ShaderIf);
    1776     AssertRC(rc);
    1777 
    1778     /* Cleanup */
    1779     rc = vmsvga3dContextDestroy(pThis, 1);
    1780     AssertRC(rc);
    1781 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    1782     rc = vmsvga3dContextDestroy(pThis, 2);
    1783     AssertRC(rc);
    1784 #endif
    1785 
    1786     if (   pState->fGLVersion < 3.0
    1787         && pState->fOtherGLVersion < 3.0 /* darwin: legacy profile hack */)
    1788     {
    1789         LogRel(("VMSVGA3d: unsupported OpenGL version; minimum is 3.0\n"));
    1790         return VERR_NOT_IMPLEMENTED;
    1791     }
    1792     if (    !pState->ext.glIsRenderbuffer
    1793         ||  !pState->ext.glBindRenderbuffer
    1794         ||  !pState->ext.glDeleteRenderbuffers
    1795         ||  !pState->ext.glGenRenderbuffers
    1796         ||  !pState->ext.glRenderbufferStorage
    1797         ||  !pState->ext.glGetRenderbufferParameteriv
    1798         ||  !pState->ext.glIsFramebuffer
    1799         ||  !pState->ext.glBindFramebuffer
    1800         ||  !pState->ext.glDeleteFramebuffers
    1801         ||  !pState->ext.glGenFramebuffers
    1802         ||  !pState->ext.glCheckFramebufferStatus
    1803         ||  !pState->ext.glFramebufferTexture1D
    1804         ||  !pState->ext.glFramebufferTexture2D
    1805         ||  !pState->ext.glFramebufferTexture3D
    1806         ||  !pState->ext.glFramebufferRenderbuffer
    1807         ||  !pState->ext.glGetFramebufferAttachmentParameteriv
    1808         ||  !pState->ext.glGenerateMipmap
    1809         ||  !pState->ext.glBlitFramebuffer
    1810         ||  !pState->ext.glRenderbufferStorageMultisample
    1811         ||  !pState->ext.glFramebufferTextureLayer)
    1812     {
    1813         LogRel(("VMSVGA3d: missing required OpenGL extension; aborting\n"));
    1814         return VERR_NOT_IMPLEMENTED;
    1815     }
    1816 
    1817 #ifdef DEBUG_DEBUG_GFX_WINDOW_TEST_CONTEXT
    1818     pState->idTestContext = SVGA_ID_INVALID;
    1819 #endif
    1820     return VINF_SUCCESS;
    1821 }
    1822 
    1823 int vmsvga3dReset(PVGASTATE pThis)
    1824 {
    1825     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    1826     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
    1827 
    1828     /* Destroy all leftover surfaces. */
    1829     for (uint32_t i = 0; i < pState->cSurfaces; i++)
    1830     {
    1831         if (pState->papSurfaces[i]->id != SVGA3D_INVALID_ID)
    1832             vmsvga3dSurfaceDestroy(pThis, pState->papSurfaces[i]->id);
    1833     }
    1834 
    1835     /* Destroy all leftover contexts. */
    1836     for (uint32_t i = 0; i < pState->cContexts; i++)
    1837     {
    1838         if (pState->papContexts[i]->id != SVGA3D_INVALID_ID)
    1839             vmsvga3dContextDestroy(pThis, pState->papContexts[i]->id);
    1840     }
    1841 
    1842     if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    1843         vmsvga3dContextDestroyOgl(pThis, &pState->SharedCtx, VMSVGA3D_SHARED_CTX_ID);
    1844 
    1845     return VINF_SUCCESS;
    1846 }
    1847 
    1848 int vmsvga3dTerminate(PVGASTATE pThis)
    1849 {
    1850     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    1851     AssertReturn(pState, VERR_WRONG_ORDER);
    1852     int            rc;
    1853 
    1854     rc = vmsvga3dReset(pThis);
    1855     AssertRCReturn(rc, rc);
    1856 
    1857     /* Terminate the shader library. */
    1858     rc = ShaderDestroyLib();
    1859     AssertRC(rc);
    1860 
    1861 #ifdef RT_OS_WINDOWS
    1862     /* Terminate the window creation thread. */
    1863     rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_EXIT, 0, 0);
    1864     AssertRCReturn(rc, rc);
    1865 
    1866     RTSemEventDestroy(pState->WndRequestSem);
    1867 #elif defined(RT_OS_DARWIN)
    1868 
    1869 #elif defined(RT_OS_LINUX)
    1870     /* signal to the thread that it is supposed to exit */
    1871     pState->bTerminate = true;
    1872     /* wait for it to terminate */
    1873     rc = RTThreadWait(pState->pWindowThread, 10000, NULL);
    1874     AssertRC(rc);
    1875     XCloseDisplay(pState->display);
    1876 #endif
    1877 
    1878     RTStrFree(pState->pszExtensions);
    1879     pState->pszExtensions = NULL;
    1880 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    1881     RTStrFree(pState->pszOtherExtensions);
    1882 #endif
    1883     pState->pszOtherExtensions = NULL;
    1884 
    1885     return VINF_SUCCESS;
    1886 }
    1887 
    1888 /* Shared functions that depend on private structure definitions. */
    1889 #define VMSVGA3D_OPENGL
    1890 #include "DevVGA-SVGA3d-shared.h"
    1891 
    1892 /**
    1893  * Worker for vmsvga3dQueryCaps that figures out supported operations for a
    1894  * given surface format capability.
    1895  *
    1896  * @returns Supported/indented operations (SVGA3DFORMAT_OP_XXX).
    1897  * @param   pState3D        The 3D state.
    1898  * @param   idx3dCaps       The SVGA3D_CAPS_XXX value of the surface format.
    1899  *
    1900  * @remarks See fromat_cap_table in svga_format.c (mesa/gallium) for a reference
    1901  *          of implicit guest expectations:
    1902  *              http://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/svga/svga_format.c
    1903  */
    1904 static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_t idx3dCaps)
    1905 {
    1906     uint32_t result = 0;
    1907 
    1908     /* @todo missing:
    1909      *
    1910      * SVGA3DFORMAT_OP_PIXELSIZE
    1911      */
    1912 
    1913     switch (idx3dCaps)
    1914     {
    1915     case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
    1916     case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
    1917     case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
    1918         result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB
    1919                |  SVGA3DFORMAT_OP_CONVERT_TO_ARGB
    1920                |  SVGA3DFORMAT_OP_DISPLAYMODE           /* Should not be set for alpha formats. */
    1921                |  SVGA3DFORMAT_OP_3DACCELERATION;       /* implies OP_DISPLAYMODE */
    1922         break;
    1923 
    1924     case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
    1925     case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
    1926     case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
    1927     case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
    1928         result |=     SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB
    1929                   |   SVGA3DFORMAT_OP_CONVERT_TO_ARGB
    1930                   |   SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
    1931         break;
    1932     }
    1933 
    1934     /* @todo check hardware caps! */
    1935     switch (idx3dCaps)
    1936     {
    1937     case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
    1938     case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
    1939     case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
    1940     case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
    1941     case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
    1942     case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
    1943     case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
    1944     case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
    1945     case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
    1946     case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
    1947     case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
    1948         result |= SVGA3DFORMAT_OP_TEXTURE
    1949                |  SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET
    1950                |  SVGA3DFORMAT_OP_OFFSCREENPLAIN
    1951                |  SVGA3DFORMAT_OP_SAME_FORMAT_RENDERTARGET
    1952                |  SVGA3DFORMAT_OP_VOLUMETEXTURE
    1953                |  SVGA3DFORMAT_OP_CUBETEXTURE
    1954                |  SVGA3DFORMAT_OP_SRGBREAD
    1955                |  SVGA3DFORMAT_OP_SRGBWRITE;
    1956         break;
    1957 
    1958     case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
    1959     case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
    1960     case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
    1961     case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
    1962     case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
    1963     case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
    1964         result |= SVGA3DFORMAT_OP_ZSTENCIL
    1965                |  SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH
    1966                |  SVGA3DFORMAT_OP_TEXTURE /* Necessary for Ubuntu Unity */;
    1967         break;
    1968 
    1969     case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
    1970     case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
    1971     case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
    1972         result |= SVGA3DFORMAT_OP_TEXTURE
    1973                |  SVGA3DFORMAT_OP_VOLUMETEXTURE
    1974                |  SVGA3DFORMAT_OP_CUBETEXTURE
    1975                |  SVGA3DFORMAT_OP_SRGBREAD;
    1976         break;
    1977 
    1978     case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
    1979     case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
    1980     case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
    1981     case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
    1982     case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
    1983         break;
    1984 
    1985     case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
    1986     case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
    1987     case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
    1988     case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
    1989     case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
    1990     case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
    1991         break;
    1992 
    1993     case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
    1994     case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
    1995     case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
    1996 
    1997     case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
    1998     case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
    1999     case SVGA3D_DEVCAP_SURFACEFMT_NV12:
    2000     case SVGA3D_DEVCAP_SURFACEFMT_AYUV:
    2001         break;
    2002     }
    2003     Log(("CAPS: %s =\n%s\n", vmsvga3dGetCapString(idx3dCaps), vmsvga3dGet3dFormatString(result)));
    2004 
    2005     return result;
    2006 }
    2007 
    2008 static uint32_t vmsvga3dGetDepthFormatSupport(PVMSVGA3DSTATE pState3D, uint32_t idx3dCaps)
    2009 {
    2010     uint32_t result = 0;
    2011 
    2012     /* @todo test this somehow */
    2013     result = SVGA3DFORMAT_OP_ZSTENCIL | SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH;
    2014 
    2015     Log(("CAPS: %s =\n%s\n", vmsvga3dGetCapString(idx3dCaps), vmsvga3dGet3dFormatString(result)));
    2016     return result;
    2017 }
    2018 
    2019 
    2020 int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
    2021 {
    2022     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    2023     AssertReturn(pState, VERR_NO_MEMORY);
    2024     int       rc = VINF_SUCCESS;
    2025 
    2026     *pu32Val = 0;
    2027 
    2028     /*
    2029      * The capabilities access by current (2015-03-01) linux sources (gallium,
    2030      * vmwgfx, xorg-video-vmware) are annotated, caps without xref annotations
    2031      * aren't access.
    2032      */
    2033 
    2034     switch (idx3dCaps)
    2035     {
    2036     /* Linux: vmwgfx_fifo.c in kmod; only used with SVGA_CAP_GBOBJECTS. */
    2037     case SVGA3D_DEVCAP_3D:
    2038         *pu32Val = 1; /* boolean? */
    2039         break;
    2040 
    2041     case SVGA3D_DEVCAP_MAX_LIGHTS:
    2042         *pu32Val = pState->caps.maxActiveLights;
    2043         break;
    2044 
    2045     case SVGA3D_DEVCAP_MAX_TEXTURES:
    2046         *pu32Val = pState->caps.maxTextures;
    2047         break;
    2048 
    2049     case SVGA3D_DEVCAP_MAX_CLIP_PLANES:
    2050         *pu32Val = pState->caps.maxClipDistances;
    2051         break;
    2052 
    2053     /* Linux: svga_screen.c in gallium; 3.0 or later required. */
    2054     case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
    2055         *pu32Val = pState->caps.vertexShaderVersion;
    2056         break;
    2057 
    2058     case SVGA3D_DEVCAP_VERTEX_SHADER:
    2059         /* boolean? */
    2060         *pu32Val = (pState->caps.vertexShaderVersion != SVGA3DVSVERSION_NONE);
    2061         break;
    2062 
    2063     /* Linux: svga_screen.c in gallium; 3.0 or later required. */
    2064     case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
    2065         *pu32Val = pState->caps.fragmentShaderVersion;
    2066         break;
    2067 
    2068     case SVGA3D_DEVCAP_FRAGMENT_SHADER:
    2069         /* boolean? */
    2070         *pu32Val = (pState->caps.fragmentShaderVersion != SVGA3DPSVERSION_NONE);
    2071         break;
    2072 
    2073     case SVGA3D_DEVCAP_S23E8_TEXTURES:
    2074     case SVGA3D_DEVCAP_S10E5_TEXTURES:
    2075         /* Must be obsolete by now; surface format caps specify the same thing. */
    2076         rc = VERR_INVALID_PARAMETER;
    2077         break;
    2078 
    2079     case SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
    2080         break;
    2081 
    2082     /*
    2083      *   2. The BUFFER_FORMAT capabilities are deprecated, and they always
    2084      *      return TRUE. Even on physical hardware that does not support
    2085      *      these formats natively, the SVGA3D device will provide an emulation
    2086      *      which should be invisible to the guest OS.
    2087      */
    2088     case SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
    2089     case SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
    2090     case SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
    2091         *pu32Val = 1;
    2092         break;
    2093 
    2094     case SVGA3D_DEVCAP_QUERY_TYPES:
    2095         break;
    2096 
    2097     case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
    2098         break;
    2099 
    2100     /* Linux: svga_screen.c in gallium; capped at 80.0, default 1.0. */
    2101     case SVGA3D_DEVCAP_MAX_POINT_SIZE:
    2102         AssertCompile(sizeof(uint32_t) == sizeof(float));
    2103         *(float *)pu32Val = pState->caps.flPointSize[1];
    2104         break;
    2105 
    2106     case SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
    2107         /* @todo ?? */
    2108         rc = VERR_INVALID_PARAMETER;
    2109         break;
    2110 
    2111     /* Linux: svga_screen.c in gallium (for PIPE_CAP_MAX_TEXTURE_2D_LEVELS); have default if missing. */
    2112     case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
    2113     case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
    2114         *pu32Val = pState->caps.maxRectangleTextureSize;
    2115         break;
    2116 
    2117     /* Linux: svga_screen.c in gallium (for PIPE_CAP_MAX_TEXTURE_3D_LEVELS); have default if missing. */
    2118     case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
    2119         //*pu32Val = pCaps->MaxVolumeExtent;
    2120         break;
    2121 
    2122     case SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
    2123         *pu32Val = 32768;   /* hardcoded in Wine */
    2124         break;
    2125 
    2126     case SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
    2127         //*pu32Val = pCaps->MaxTextureAspectRatio;
    2128         break;
    2129 
    2130     /* Linux: svga_screen.c in gallium (for PIPE_CAPF_MAX_TEXTURE_ANISOTROPY); defaults to 4.0. */
    2131     case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
    2132         *pu32Val = pState->caps.maxTextureAnisotropy;
    2133         break;
    2134 
    2135     case SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
    2136     case SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
    2137         *pu32Val =  0xFFFFF; /* hardcoded in Wine */
    2138         break;
    2139 
    2140     /* Linux: svga_screen.c in gallium (for PIPE_SHADER_VERTEX/PIPE_SHADER_CAP_MAX_INSTRUCTIONS); defaults to 512. */
    2141     case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
    2142         *pu32Val = pState->caps.maxVertexShaderInstructions;
    2143         break;
    2144 
    2145     case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
    2146         *pu32Val = pState->caps.maxFragmentShaderInstructions;
    2147         break;
    2148 
    2149     /* Linux: svga_screen.c in gallium (for PIPE_SHADER_VERTEX/PIPE_SHADER_CAP_MAX_TEMPS); defaults to 32. */
    2150     case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
    2151         *pu32Val = pState->caps.maxVertexShaderTemps;
    2152         break;
    2153 
    2154     /* Linux: svga_screen.c in gallium (for PIPE_SHADER_FRAGMENT/PIPE_SHADER_CAP_MAX_TEMPS); defaults to 32. */
    2155     case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
    2156         *pu32Val = pState->caps.maxFragmentShaderTemps;
    2157         break;
    2158 
    2159     case SVGA3D_DEVCAP_TEXTURE_OPS:
    2160         break;
    2161 
    2162     case SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES:
    2163         break;
    2164 
    2165     case SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES:
    2166         break;
    2167 
    2168     case SVGA3D_DEVCAP_ALPHATOCOVERAGE:
    2169         break;
    2170 
    2171     case SVGA3D_DEVCAP_SUPERSAMPLE:
    2172         break;
    2173 
    2174     case SVGA3D_DEVCAP_AUTOGENMIPMAPS:
    2175         //*pu32Val = !!(pCaps->Caps2 & D3DCAPS2_CANAUTOGENMIPMAP);
    2176         break;
    2177 
    2178     case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
    2179         break;
    2180 
    2181     case SVGA3D_DEVCAP_MAX_RENDER_TARGETS:  /* @todo same thing? */
    2182     case SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
    2183         *pu32Val = pState->caps.maxColorAttachments;
    2184         break;
    2185 
    2186     /*
    2187      * This is the maximum number of SVGA context IDs that the guest
    2188      * can define using SVGA_3D_CMD_CONTEXT_DEFINE.
    2189      */
    2190     case SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
    2191         *pu32Val = SVGA3D_MAX_CONTEXT_IDS;
    2192         break;
    2193 
    2194     /*
    2195      * This is the maximum number of SVGA surface IDs that the guest
    2196      * can define using SVGA_3D_CMD_SURFACE_DEFINE*.
    2197      */
    2198     case SVGA3D_DEVCAP_MAX_SURFACE_IDS:
    2199         *pu32Val = SVGA3D_MAX_SURFACE_IDS;
    2200         break;
    2201 
    2202 #if 0 /* Appeared more recently, not yet implemented. */
    2203    /* Linux: svga_screen.c in gallium; defaults to FALSE. */
    2204    case SVGA3D_DEVCAP_LINE_AA:
    2205        break;
    2206    /* Linux: svga_screen.c in gallium; defaults to FALSE. */
    2207    case SVGA3D_DEVCAP_LINE_STIPPLE:
    2208        break;
    2209    /* Linux: svga_screen.c in gallium; defaults to 1.0. */
    2210    case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
    2211        break;
    2212    /* Linux: svga_screen.c in gallium; defaults to 1.0. */
    2213    case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
    2214        break;
    2215 #endif
    2216 
    2217     /*
    2218      * Supported surface formats.
    2219      * Linux: svga_format.c in gallium, format_cap_table defines implicit expectations.
    2220      */
    2221     case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
    2222     case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
    2223     case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
    2224     case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
    2225     case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
    2226     case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
    2227     case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
    2228     case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
    2229     case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
    2230     case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
    2231     case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
    2232     case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
    2233     case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
    2234     case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
    2235     case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
    2236     case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
    2237     case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
    2238     case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
    2239         *pu32Val = vmsvga3dGetSurfaceFormatSupport(pState, idx3dCaps);
    2240         break;
    2241 
    2242     case SVGA3D_DEVCAP_SURFACEFMT_DXT2:
    2243     case SVGA3D_DEVCAP_SURFACEFMT_DXT4:
    2244         *pu32Val = 0;   /* apparently not supported in OpenGL */
    2245         break;
    2246 
    2247     case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
    2248     case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
    2249     case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
    2250     case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
    2251     case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
    2252     case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
    2253     case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
    2254     case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
    2255     case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
    2256     case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
    2257     case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
    2258     case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
    2259     case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
    2260     case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
    2261     case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
    2262     case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
    2263     case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
    2264     case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
    2265     case SVGA3D_DEVCAP_SURFACEFMT_NV12:
    2266     case SVGA3D_DEVCAP_SURFACEFMT_AYUV:
    2267         *pu32Val = vmsvga3dGetSurfaceFormatSupport(pState, idx3dCaps);
    2268         break;
    2269 
    2270     /* Linux: Not referenced in current sources. */
    2271     case SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM:
    2272     case SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM:
    2273         Log(("CAPS: Unknown CAP %s\n", vmsvga3dGetCapString(idx3dCaps)));
    2274         rc = VERR_INVALID_PARAMETER;
    2275         *pu32Val = 0;
    2276         break;
    2277 
    2278     default:
    2279         Log(("CAPS: Unexpected CAP %d\n", idx3dCaps));
    2280         rc = VERR_INVALID_PARAMETER;
    2281         break;
    2282     }
    2283 
    2284     Log(("CAPS: %s - %x\n", vmsvga3dGetCapString(idx3dCaps), *pu32Val));
    2285     return rc;
    2286 }
    2287 
    2288 /**
    2289  * Convert SVGA format value to its OpenGL equivalent
    2290  *
    2291  * @remarks  Clues to be had in format_texture_info table (wined3d/utils.c) with
    2292  *           help from wined3dformat_from_d3dformat().
    2293  */
    2294 static void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFormat format)
    2295 {
    2296     switch (format)
    2297     {
    2298     case SVGA3D_X8R8G8B8:               /* D3DFMT_X8R8G8B8 - WINED3DFMT_B8G8R8X8_UNORM */
    2299         pSurface->internalFormatGL = GL_RGB8;
    2300         pSurface->formatGL = GL_BGRA;
    2301         pSurface->typeGL = GL_UNSIGNED_INT_8_8_8_8_REV;
    2302         break;
    2303     case SVGA3D_A8R8G8B8:               /* D3DFMT_A8R8G8B8 - WINED3DFMT_B8G8R8A8_UNORM */
    2304         pSurface->internalFormatGL = GL_RGBA8;
    2305         pSurface->formatGL = GL_BGRA;
    2306         pSurface->typeGL = GL_UNSIGNED_INT_8_8_8_8_REV;
    2307         break;
    2308     case SVGA3D_R5G6B5:                 /* D3DFMT_R5G6B5 - WINED3DFMT_B5G6R5_UNORM */
    2309         pSurface->internalFormatGL = GL_RGB5;
    2310         pSurface->formatGL = GL_RGB;
    2311         pSurface->typeGL = GL_UNSIGNED_SHORT_5_6_5;
    2312         AssertMsgFailed(("Test me - SVGA3D_R5G6B5\n"));
    2313         break;
    2314     case SVGA3D_X1R5G5B5:               /* D3DFMT_X1R5G5B5 - WINED3DFMT_B5G5R5X1_UNORM */
    2315         pSurface->internalFormatGL = GL_RGB5;
    2316         pSurface->formatGL = GL_BGRA;
    2317         pSurface->typeGL = GL_UNSIGNED_SHORT_1_5_5_5_REV;
    2318         AssertMsgFailed(("Test me - SVGA3D_X1R5G5B5\n"));
    2319         break;
    2320     case SVGA3D_A1R5G5B5:               /* D3DFMT_A1R5G5B5 - WINED3DFMT_B5G5R5A1_UNORM */
    2321         pSurface->internalFormatGL = GL_RGB5_A1;
    2322         pSurface->formatGL = GL_BGRA;
    2323         pSurface->typeGL = GL_UNSIGNED_SHORT_1_5_5_5_REV;
    2324         AssertMsgFailed(("Test me - SVGA3D_A1R5G5B5\n"));
    2325         break;
    2326     case SVGA3D_A4R4G4B4:               /* D3DFMT_A4R4G4B4 - WINED3DFMT_B4G4R4A4_UNORM */
    2327         pSurface->internalFormatGL = GL_RGBA4;
    2328         pSurface->formatGL = GL_BGRA;
    2329         pSurface->typeGL = GL_UNSIGNED_SHORT_4_4_4_4_REV;
    2330         AssertMsgFailed(("Test me - SVGA3D_A4R4G4B4\n"));
    2331         break;
    2332 
    2333     case SVGA3D_Z_D32:                  /* D3DFMT_D32 - WINED3DFMT_D32_UNORM */
    2334         pSurface->internalFormatGL = GL_DEPTH_COMPONENT32;
    2335         pSurface->formatGL = GL_DEPTH_COMPONENT;
    2336         pSurface->typeGL = GL_UNSIGNED_INT;
    2337         break;
    2338     case SVGA3D_Z_D16:                  /* D3DFMT_D16 - WINED3DFMT_D16_UNORM */
    2339         pSurface->internalFormatGL = GL_DEPTH_COMPONENT16; /** @todo Wine suggests GL_DEPTH_COMPONENT24. */
    2340         pSurface->formatGL = GL_DEPTH_COMPONENT;
    2341         pSurface->typeGL = GL_UNSIGNED_SHORT;
    2342         //AssertMsgFailed(("Test me - SVGA3D_Z_D16\n"));
    2343         break;
    2344     case SVGA3D_Z_D24S8:                /* D3DFMT_D24S8 - WINED3DFMT_D24_UNORM_S8_UINT */
    2345         pSurface->internalFormatGL = GL_DEPTH24_STENCIL8;
    2346         pSurface->formatGL = GL_DEPTH_STENCIL;
    2347         pSurface->typeGL = GL_UNSIGNED_INT;
    2348         break;
    2349     case SVGA3D_Z_D15S1:                /* D3DFMT_D15S1 - WINED3DFMT_S1_UINT_D15_UNORM */
    2350         pSurface->internalFormatGL = GL_DEPTH_COMPONENT16;  /* @todo ??? */
    2351         pSurface->formatGL = GL_DEPTH_STENCIL;
    2352         pSurface->typeGL = GL_UNSIGNED_SHORT;
    2353         /** @todo Wine sources hints at no hw support for this, so test this one! */
    2354         AssertMsgFailed(("Test me - SVGA3D_Z_D15S1\n"));
    2355         break;
    2356     case SVGA3D_Z_D24X8:                /* D3DFMT_D24X8 - WINED3DFMT_X8D24_UNORM */
    2357         pSurface->internalFormatGL = GL_DEPTH_COMPONENT24;
    2358         pSurface->formatGL = GL_DEPTH_COMPONENT;
    2359         pSurface->typeGL = GL_UNSIGNED_INT;
    2360         break;
    2361 
    2362     /* Advanced D3D9 depth formats. */
    2363     case SVGA3D_Z_DF16:                 /* D3DFMT_DF16? - not supported */
    2364         pSurface->internalFormatGL = GL_DEPTH_COMPONENT16;
    2365         pSurface->formatGL = GL_DEPTH_COMPONENT;
    2366         pSurface->typeGL = GL_FLOAT;
    2367         break;
    2368 
    2369     case SVGA3D_Z_DF24:                 /* D3DFMT_DF24? - not supported */
    2370         pSurface->internalFormatGL = GL_DEPTH_COMPONENT24;
    2371         pSurface->formatGL = GL_DEPTH_COMPONENT;
    2372         pSurface->typeGL = GL_FLOAT;        /* ??? */
    2373         break;
    2374 
    2375     case SVGA3D_Z_D24S8_INT:            /* D3DFMT_??? - not supported */
    2376         pSurface->internalFormatGL = GL_DEPTH24_STENCIL8;
    2377         pSurface->formatGL = GL_DEPTH_STENCIL;
    2378         pSurface->typeGL = GL_INT;        /* ??? */
    2379         break;
    2380 
    2381     case SVGA3D_DXT1:                   /* D3DFMT_DXT1 - WINED3DFMT_DXT1 */
    2382         pSurface->internalFormatGL = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
    2383 #if 0
    2384         pSurface->formatGL = GL_RGBA_S3TC;          /* ??? */
    2385         pSurface->typeGL = GL_UNSIGNED_INT;         /* ??? */
    2386 #else   /* wine suggests: */
    2387         pSurface->formatGL = GL_RGBA;
    2388         pSurface->typeGL = GL_UNSIGNED_BYTE;
    2389         AssertMsgFailed(("Test me - SVGA3D_DXT1\n"));
    2390 #endif
    2391         break;
    2392 
    2393     case SVGA3D_DXT3:                   /* D3DFMT_DXT3 - WINED3DFMT_DXT3 */
    2394         pSurface->internalFormatGL = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
    2395 #if 0 /** @todo this needs testing... */
    2396         pSurface->formatGL = GL_RGBA_S3TC;          /* ??? */
    2397         pSurface->typeGL = GL_UNSIGNED_INT;         /* ??? */
    2398 #else   /* wine suggests: */
    2399         pSurface->formatGL = GL_RGBA;
    2400         pSurface->typeGL = GL_UNSIGNED_BYTE;
    2401         AssertMsgFailed(("Test me - SVGA3D_DXT3\n"));
    2402 #endif
    2403         break;
    2404 
    2405     case SVGA3D_DXT5:                   /* D3DFMT_DXT5 - WINED3DFMT_DXT5 */
    2406         pSurface->internalFormatGL = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
    2407 #if 0 /** @todo this needs testing... */
    2408         pSurface->formatGL = GL_RGBA_S3TC;
    2409         pSurface->typeGL = GL_UNSIGNED_INT;
    2410 #else   /* wine suggests: */
    2411         pSurface->formatGL = GL_RGBA;
    2412         pSurface->typeGL = GL_UNSIGNED_BYTE;
    2413         AssertMsgFailed(("Test me - SVGA3D_DXT5\n"));
    2414 #endif
    2415         break;
    2416 
    2417     case SVGA3D_LUMINANCE8:             /* D3DFMT_? - ? */
    2418         pSurface->internalFormatGL = GL_LUMINANCE8_EXT;
    2419         pSurface->formatGL = GL_LUMINANCE;
    2420         pSurface->typeGL = GL_UNSIGNED_BYTE;
    2421         break;
    2422 
    2423     case SVGA3D_LUMINANCE16:            /* D3DFMT_? - ? */
    2424         pSurface->internalFormatGL = GL_LUMINANCE16_EXT;
    2425         pSurface->formatGL = GL_LUMINANCE;
    2426         pSurface->typeGL = GL_UNSIGNED_SHORT;
    2427         break;
    2428 
    2429     case SVGA3D_LUMINANCE4_ALPHA4:     /* D3DFMT_? - ? */
    2430         pSurface->internalFormatGL = GL_LUMINANCE4_ALPHA4_EXT;
    2431         pSurface->formatGL = GL_LUMINANCE_ALPHA;
    2432         pSurface->typeGL = GL_UNSIGNED_BYTE;
    2433         break;
    2434 
    2435     case SVGA3D_LUMINANCE8_ALPHA8:     /* D3DFMT_? - ? */
    2436         pSurface->internalFormatGL = GL_LUMINANCE8_ALPHA8_EXT;
    2437         pSurface->formatGL = GL_LUMINANCE_ALPHA;
    2438         pSurface->typeGL = GL_UNSIGNED_BYTE;    /* unsigned_short causes issues even though this type should be 16-bit */
    2439         break;
    2440 
    2441     case SVGA3D_ALPHA8:                /* D3DFMT_A8? - WINED3DFMT_A8_UNORM? */
    2442         pSurface->internalFormatGL = GL_ALPHA8_EXT;
    2443         pSurface->formatGL = GL_ALPHA;
    2444         pSurface->typeGL = GL_UNSIGNED_BYTE;
    2445         break;
    2446 
    2447 #if 0
    2448 
    2449     /* Bump-map formats */
    2450     case SVGA3D_BUMPU8V8:
    2451         return D3DFMT_V8U8;
    2452     case SVGA3D_BUMPL6V5U5:
    2453         return D3DFMT_L6V5U5;
    2454     case SVGA3D_BUMPX8L8V8U8:
    2455         return D3DFMT_X8L8V8U8;
    2456     case SVGA3D_BUMPL8V8U8:
    2457         /* No corresponding D3D9 equivalent. */
    2458         AssertFailedReturn(D3DFMT_UNKNOWN);
    2459     /* signed bump-map formats */
    2460     case SVGA3D_V8U8:
    2461         return D3DFMT_V8U8;
    2462     case SVGA3D_Q8W8V8U8:
    2463         return D3DFMT_Q8W8V8U8;
    2464     case SVGA3D_CxV8U8:
    2465         return D3DFMT_CxV8U8;
    2466     /* mixed bump-map formats */
    2467     case SVGA3D_X8L8V8U8:
    2468         return D3DFMT_X8L8V8U8;
    2469     case SVGA3D_A2W10V10U10:
    2470         return D3DFMT_A2W10V10U10;
    2471 #endif
    2472 
    2473     case SVGA3D_ARGB_S10E5:   /* 16-bit floating-point ARGB */ /* D3DFMT_A16B16G16R16F - WINED3DFMT_R16G16B16A16_FLOAT */
    2474         pSurface->internalFormatGL = GL_RGBA16F;
    2475         pSurface->formatGL = GL_RGBA;
    2476 #if 0 /* bird: wine uses half float, sounds correct to me... */
    2477         pSurface->typeGL = GL_FLOAT;
    2478 #else
    2479         pSurface->typeGL = GL_HALF_FLOAT;
    2480         AssertMsgFailed(("Test me - SVGA3D_ARGB_S10E5\n"));
    2481 #endif
    2482         break;
    2483 
    2484     case SVGA3D_ARGB_S23E8:   /* 32-bit floating-point ARGB */ /* D3DFMT_A32B32G32R32F - WINED3DFMT_R32G32B32A32_FLOAT */
    2485         pSurface->internalFormatGL = GL_RGBA32F;
    2486         pSurface->formatGL = GL_RGBA;
    2487         pSurface->typeGL = GL_FLOAT;    /* ?? - same as wine, so probably correct */
    2488         break;
    2489 
    2490     case SVGA3D_A2R10G10B10:            /* D3DFMT_A2R10G10B10 - WINED3DFMT_B10G10R10A2_UNORM */
    2491         pSurface->internalFormatGL = GL_RGB10_A2; /* ?? - same as wine, so probably correct */
    2492 #if 0 /* bird: Wine uses GL_BGRA instead of GL_RGBA. */
    2493         pSurface->formatGL = GL_RGBA;
    2494 #else
    2495         pSurface->formatGL = GL_BGRA;
    2496 #endif
    2497         pSurface->typeGL = GL_UNSIGNED_INT;
    2498         AssertMsgFailed(("Test me - SVGA3D_A2R10G10B10\n"));
    2499         break;
    2500 
    2501 
    2502     /* Single- and dual-component floating point formats */
    2503     case SVGA3D_R_S10E5:                /* D3DFMT_R16F - WINED3DFMT_R16_FLOAT */
    2504         pSurface->internalFormatGL = GL_R16F;
    2505         pSurface->formatGL = GL_RED;
    2506 #if 0 /* bird: wine uses half float, sounds correct to me... */
    2507         pSurface->typeGL = GL_FLOAT;
    2508 #else
    2509         pSurface->typeGL = GL_HALF_FLOAT;
    2510         AssertMsgFailed(("Test me - SVGA3D_R_S10E5\n"));
    2511 #endif
    2512         break;
    2513     case SVGA3D_R_S23E8:                /* D3DFMT_R32F - WINED3DFMT_R32_FLOAT */
    2514         pSurface->internalFormatGL = GL_R32F;
    2515         pSurface->formatGL = GL_RG;
    2516         pSurface->typeGL = GL_FLOAT;
    2517         break;
    2518     case SVGA3D_RG_S10E5:               /* D3DFMT_G16R16F - WINED3DFMT_R16G16_FLOAT */
    2519         pSurface->internalFormatGL = GL_RG16F;
    2520         pSurface->formatGL = GL_RG;
    2521 #if 0 /* bird: wine uses half float, sounds correct to me... */
    2522         pSurface->typeGL = GL_FLOAT;
    2523 #else
    2524         pSurface->typeGL = GL_HALF_FLOAT;
    2525         AssertMsgFailed(("Test me - SVGA3D_RG_S10E5\n"));
    2526 #endif
    2527         break;
    2528     case SVGA3D_RG_S23E8:               /* D3DFMT_G32R32F - WINED3DFMT_R32G32_FLOAT */
    2529         pSurface->internalFormatGL = GL_RG32F;
    2530         pSurface->formatGL = GL_RG;
    2531         pSurface->typeGL = GL_FLOAT;
    2532         break;
    2533 
    2534     /*
    2535      * Any surface can be used as a buffer object, but SVGA3D_BUFFER is
    2536      * the most efficient format to use when creating new surfaces
    2537      * expressly for index or vertex data.
    2538      */
    2539     case SVGA3D_BUFFER:
    2540         pSurface->internalFormatGL = -1;
    2541         pSurface->formatGL = -1;
    2542         pSurface->typeGL = -1;
    2543         break;
    2544 
    2545 #if 0
    2546         return D3DFMT_UNKNOWN;
    2547 
    2548     case SVGA3D_V16U16:
    2549         return D3DFMT_V16U16;
    2550 #endif
    2551 
    2552     case SVGA3D_G16R16:                 /* D3DFMT_G16R16 - WINED3DFMT_R16G16_UNORM */
    2553         pSurface->internalFormatGL = GL_RG16;
    2554         pSurface->formatGL = GL_RG;
    2555 #if 0 /* bird: Wine uses GL_UNSIGNED_SHORT here. */
    2556         pSurface->typeGL = GL_UNSIGNED_INT;
    2557 #else
    2558         pSurface->typeGL = GL_UNSIGNED_SHORT;
    2559         AssertMsgFailed(("test me - SVGA3D_G16R16\n"));
    2560 #endif
    2561         break;
    2562 
    2563     case SVGA3D_A16B16G16R16:           /* D3DFMT_A16B16G16R16 - WINED3DFMT_R16G16B16A16_UNORM */
    2564         pSurface->internalFormatGL = GL_RGBA16;
    2565         pSurface->formatGL = GL_RGBA;
    2566 #if 0 /* bird: Wine uses GL_UNSIGNED_SHORT here. */
    2567         pSurface->typeGL = GL_UNSIGNED_INT;     /* ??? */
    2568 #else
    2569         pSurface->typeGL = GL_UNSIGNED_SHORT;
    2570         AssertMsgFailed(("Test me - SVGA3D_A16B16G16R16\n"));
    2571 #endif
    2572         break;
    2573 
    2574 #if 0
    2575     /* Packed Video formats */
    2576     case SVGA3D_UYVY:
    2577         return D3DFMT_UYVY;
    2578     case SVGA3D_YUY2:
    2579         return D3DFMT_YUY2;
    2580 
    2581     /* Planar video formats */
    2582     case SVGA3D_NV12:
    2583         return (D3DFORMAT)MAKEFOURCC('N', 'V', '1', '2');
    2584 
    2585     /* Video format with alpha */
    2586     case SVGA3D_AYUV:
    2587         return (D3DFORMAT)MAKEFOURCC('A', 'Y', 'U', 'V');
    2588 
    2589     case SVGA3D_BC4_UNORM:
    2590     case SVGA3D_BC5_UNORM:
    2591         /* Unknown; only in DX10 & 11 */
    2592         break;
    2593 #endif
    2594     default:
    2595         AssertMsgFailed(("Unsupported format %d\n", format));
    2596         break;
    2597     }
    2598 }
    2599 
    2600 
    2601 #if 0
    2602 /**
    2603  * Convert SVGA multi sample count value to its D3D equivalent
    2604  */
    2605 D3DMULTISAMPLE_TYPE vmsvga3dMultipeSampleCount2D3D(uint32_t multisampleCount)
    2606 {
    2607     AssertCompile(D3DMULTISAMPLE_2_SAMPLES == 2);
    2608     AssertCompile(D3DMULTISAMPLE_16_SAMPLES == 16);
    2609 
    2610     if (multisampleCount > 16)
    2611         return D3DMULTISAMPLE_NONE;
    2612 
    2613     /* @todo exact same mapping as d3d? */
    2614     return (D3DMULTISAMPLE_TYPE)multisampleCount;
    2615 }
    2616 #endif
    2617 
    2618 int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,
    2619                           SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,
    2620                           SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *pMipLevelSize)
    2621 {
    2622     PVMSVGA3DSURFACE pSurface;
    2623     PVMSVGA3DSTATE   pState = pThis->svga.p3dState;
    2624     AssertReturn(pState, VERR_NO_MEMORY);
    2625 
    2626     Log(("vmsvga3dSurfaceDefine: sid=%x surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n",
    2627          sid, surfaceFlags, vmsvgaLookupEnum((int)format, &g_SVGA3dSurfaceFormat2String), format, multisampleCount, autogenFilter, cMipLevels, pMipLevelSize->width, pMipLevelSize->height, pMipLevelSize->depth));
    2628 
    2629     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    2630     AssertReturn(cMipLevels >= 1, VERR_INVALID_PARAMETER);
    2631     /* Assuming all faces have the same nr of mipmaps. */
    2632     AssertReturn(!(surfaceFlags & SVGA3D_SURFACE_CUBEMAP) || cMipLevels == face[0].numMipLevels * 6, VERR_INVALID_PARAMETER);
    2633     AssertReturn((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) || cMipLevels == face[0].numMipLevels, VERR_INVALID_PARAMETER);
    2634 
    2635     if (sid >= pState->cSurfaces)
    2636     {
    2637         /* Grow the array. */
    2638         uint32_t cNew = RT_ALIGN(sid + 15, 16);
    2639         void *pvNew = RTMemRealloc(pState->papSurfaces, sizeof(pState->papSurfaces[0]) * cNew);
    2640         AssertReturn(pvNew, VERR_NO_MEMORY);
    2641         pState->papSurfaces = (PVMSVGA3DSURFACE *)pvNew;
    2642         while (pState->cSurfaces < cNew)
    2643         {
    2644             pSurface = (PVMSVGA3DSURFACE)RTMemAllocZ(sizeof(*pSurface));
    2645             AssertReturn(pSurface, VERR_NO_MEMORY);
    2646             pSurface->id = SVGA3D_INVALID_ID;
    2647             pState->papSurfaces[pState->cSurfaces++] = pSurface;
    2648         }
    2649     }
    2650     pSurface = pState->papSurfaces[sid];
    2651 
    2652     /* If one already exists with this id, then destroy it now. */
    2653     if (pSurface->id != SVGA3D_INVALID_ID)
    2654         vmsvga3dSurfaceDestroy(pThis, sid);
    2655 
    2656     memset(pSurface, 0, sizeof(*pSurface));
    2657     pSurface->id                    = sid;
    2658 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    2659     pSurface->idWeakContextAssociation = SVGA3D_INVALID_ID;
    2660 #else
    2661     pSurface->idAssociatedContext   = SVGA3D_INVALID_ID;
    2662 #endif
    2663     vmsvga3dSurfaceFormat2OGL(pSurface, format);
    2664 
    2665     pSurface->oglId.buffer = OPENGL_INVALID_ID;
    2666 
    2667     /* The surface type is sort of undefined now, even though the hints and format can help to clear that up.
    2668      * In some case we'll have to wait until the surface is used to create the D3D object.
    2669      */
    2670     switch (format)
    2671     {
    2672     case SVGA3D_Z_D32:
    2673     case SVGA3D_Z_D16:
    2674     case SVGA3D_Z_D24S8:
    2675     case SVGA3D_Z_D15S1:
    2676     case SVGA3D_Z_D24X8:
    2677     case SVGA3D_Z_DF16:
    2678     case SVGA3D_Z_DF24:
    2679     case SVGA3D_Z_D24S8_INT:
    2680         surfaceFlags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
    2681         break;
    2682 
    2683     /* Texture compression formats */
    2684     case SVGA3D_DXT1:
    2685     case SVGA3D_DXT2:
    2686     case SVGA3D_DXT3:
    2687     case SVGA3D_DXT4:
    2688     case SVGA3D_DXT5:
    2689     /* Bump-map formats */
    2690     case SVGA3D_BUMPU8V8:
    2691     case SVGA3D_BUMPL6V5U5:
    2692     case SVGA3D_BUMPX8L8V8U8:
    2693     case SVGA3D_BUMPL8V8U8:
    2694     case SVGA3D_V8U8:
    2695     case SVGA3D_Q8W8V8U8:
    2696     case SVGA3D_CxV8U8:
    2697     case SVGA3D_X8L8V8U8:
    2698     case SVGA3D_A2W10V10U10:
    2699     case SVGA3D_V16U16:
    2700     /* Typical render target formats; we should allow render target buffers to be used as textures. */
    2701     case SVGA3D_X8R8G8B8:
    2702     case SVGA3D_A8R8G8B8:
    2703     case SVGA3D_R5G6B5:
    2704     case SVGA3D_X1R5G5B5:
    2705     case SVGA3D_A1R5G5B5:
    2706     case SVGA3D_A4R4G4B4:
    2707         surfaceFlags |= SVGA3D_SURFACE_HINT_TEXTURE;
    2708         break;
    2709 
    2710     case SVGA3D_LUMINANCE8:
    2711     case SVGA3D_LUMINANCE4_ALPHA4:
    2712     case SVGA3D_LUMINANCE16:
    2713     case SVGA3D_LUMINANCE8_ALPHA8:
    2714     case SVGA3D_ARGB_S10E5:   /* 16-bit floating-point ARGB */
    2715     case SVGA3D_ARGB_S23E8:   /* 32-bit floating-point ARGB */
    2716     case SVGA3D_A2R10G10B10:
    2717     case SVGA3D_ALPHA8:
    2718     case SVGA3D_R_S10E5:
    2719     case SVGA3D_R_S23E8:
    2720     case SVGA3D_RG_S10E5:
    2721     case SVGA3D_RG_S23E8:
    2722     case SVGA3D_G16R16:
    2723     case SVGA3D_A16B16G16R16:
    2724     case SVGA3D_UYVY:
    2725     case SVGA3D_YUY2:
    2726     case SVGA3D_NV12:
    2727     case SVGA3D_AYUV:
    2728     case SVGA3D_BC4_UNORM:
    2729     case SVGA3D_BC5_UNORM:
    2730         break;
    2731 
    2732     /*
    2733      * Any surface can be used as a buffer object, but SVGA3D_BUFFER is
    2734      * the most efficient format to use when creating new surfaces
    2735      * expressly for index or vertex data.
    2736      */
    2737     case SVGA3D_BUFFER:
    2738         break;
    2739 
    2740     default:
    2741         break;
    2742     }
    2743 
    2744     pSurface->flags             = surfaceFlags;
    2745     pSurface->format            = format;
    2746     memcpy(pSurface->faces, face, sizeof(pSurface->faces));
    2747     pSurface->cFaces            = 1;        /* check for cube maps later */
    2748     pSurface->multiSampleCount  = multisampleCount;
    2749     pSurface->autogenFilter     = autogenFilter;
    2750     Assert(autogenFilter != SVGA3D_TEX_FILTER_FLATCUBIC);
    2751     Assert(autogenFilter != SVGA3D_TEX_FILTER_GAUSSIANCUBIC);
    2752     pSurface->pMipmapLevels     = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
    2753     AssertReturn(pSurface->pMipmapLevels, VERR_NO_MEMORY);
    2754 
    2755     for (uint32_t i=0; i < cMipLevels; i++)
    2756         pSurface->pMipmapLevels[i].size = pMipLevelSize[i];
    2757 
    2758     pSurface->cbBlock = vmsvga3dSurfaceFormatSize(format);
    2759 
    2760     switch (surfaceFlags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
    2761     {
    2762     case SVGA3D_SURFACE_CUBEMAP:
    2763         Log(("SVGA3D_SURFACE_CUBEMAP\n"));
    2764         pSurface->cFaces = 6;
    2765         break;
    2766 
    2767     case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    2768         Log(("SVGA3D_SURFACE_HINT_INDEXBUFFER\n"));
    2769         /* else type unknown at this time; postpone buffer creation */
    2770         break;
    2771 
    2772     case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    2773         Log(("SVGA3D_SURFACE_HINT_VERTEXBUFFER\n"));
    2774         /* Type unknown at this time; postpone buffer creation */
    2775         break;
    2776 
    2777     case SVGA3D_SURFACE_HINT_TEXTURE:
    2778         Log(("SVGA3D_SURFACE_HINT_TEXTURE\n"));
    2779         break;
    2780 
    2781     case SVGA3D_SURFACE_HINT_RENDERTARGET:
    2782         Log(("SVGA3D_SURFACE_HINT_RENDERTARGET\n"));
    2783         break;
    2784 
    2785     case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
    2786         Log(("SVGA3D_SURFACE_HINT_DEPTHSTENCIL\n"));
    2787         break;
    2788 
    2789     default:
    2790         /* Unknown; decide later. */
    2791         break;
    2792     }
    2793 
    2794     /* Allocate buffer to hold the surface data until we can move it into a D3D object */
    2795     for (uint32_t iFace=0; iFace < pSurface->cFaces; iFace++)
    2796     {
    2797         for (uint32_t i=0; i < pSurface->faces[iFace].numMipLevels; i++)
    2798         {
    2799             uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;
    2800 
    2801             Log(("vmsvga3dSurfaceDefine: face %d mip level %d (%d,%d,%d)\n", iFace, i, pSurface->pMipmapLevels[idx].size.width, pSurface->pMipmapLevels[idx].size.height, pSurface->pMipmapLevels[idx].size.depth));
    2802             Log(("vmsvga3dSurfaceDefine: cbPitch=%x cbBlock=%x \n", pSurface->cbBlock * pSurface->pMipmapLevels[idx].size.width, pSurface->cbBlock));
    2803 
    2804             pSurface->pMipmapLevels[idx].cbSurfacePitch = pSurface->cbBlock * pSurface->pMipmapLevels[idx].size.width;
    2805             pSurface->pMipmapLevels[idx].cbSurface      = pSurface->pMipmapLevels[idx].cbSurfacePitch * pSurface->pMipmapLevels[idx].size.height * pSurface->pMipmapLevels[idx].size.depth;
    2806             pSurface->pMipmapLevels[idx].pSurfaceData   = RTMemAllocZ(pSurface->pMipmapLevels[idx].cbSurface);
    2807             AssertReturn(pSurface->pMipmapLevels[idx].pSurfaceData, VERR_NO_MEMORY);
    2808         }
    2809     }
    2810     return VINF_SUCCESS;
    2811 }
    2812 
    2813 int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)
    2814 {
    2815     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    2816     AssertReturn(pState, VERR_NO_MEMORY);
    2817 
    2818     if (    sid < pState->cSurfaces
    2819         &&  pState->papSurfaces[sid]->id == sid)
    2820     {
    2821         PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    2822         PVMSVGA3DCONTEXT pContext;
    2823 
    2824         Log(("vmsvga3dSurfaceDestroy id %x\n", sid));
    2825 
    2826 #if 1 /* Windows is doing this, guess it makes sense here as well... */
    2827         /* Check all contexts if this surface is used as a render target or active texture. */
    2828         for (uint32_t cid = 0; cid < pState->cContexts; cid++)
    2829         {
    2830             pContext = pState->papContexts[cid];
    2831             if (pContext->id == cid)
    2832             {
    2833                 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
    2834                     if (pContext->aSidActiveTexture[i] == sid)
    2835                         pContext->aSidActiveTexture[i] = SVGA3D_INVALID_ID;
    2836                 if (pContext->sidRenderTarget == sid)
    2837                     pContext->sidRenderTarget = SVGA3D_INVALID_ID;
    2838             }
    2839         }
    2840 #endif
    2841 
    2842 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    2843         pContext = &pState->SharedCtx;
    2844         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2845 #else
    2846         /* @todo stricter checks for associated context */
    2847         uint32_t cid = pSurface->idAssociatedContext;
    2848         if (    cid <= pState->cContexts
    2849             &&  pState->papContexts[cid]->id == cid)
    2850         {
    2851             pContext = pState->papContexts[cid];
    2852             VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2853         }
    2854         /* If there is a GL buffer or something associated with the surface, we
    2855            really need something here, so pick any active context. */
    2856         else if (pSurface->oglId.buffer != OPENGL_INVALID_ID)
    2857         {
    2858             for (cid = 0; cid < pState->cContexts; cid++)
    2859             {
    2860                 if (pState->papContexts[cid]->id == cid)
    2861                 {
    2862                     pContext = pState->papContexts[cid];
    2863                     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2864                     break;
    2865                 }
    2866             }
    2867             AssertReturn(pContext, VERR_INTERNAL_ERROR); /* otherwise crashes/fails; create temp context if this ever triggers! */
    2868         }
    2869 #endif
    2870 
    2871         switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
    2872         {
    2873         case SVGA3D_SURFACE_CUBEMAP:
    2874             AssertFailed(); /* @todo */
    2875             break;
    2876 
    2877         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    2878         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    2879             if (pSurface->oglId.buffer != OPENGL_INVALID_ID)
    2880             {
    2881                 pState->ext.glDeleteBuffers(1, &pSurface->oglId.buffer);
    2882                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    2883             }
    2884             break;
    2885 
    2886         case SVGA3D_SURFACE_HINT_TEXTURE:
    2887         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    2888             if (pSurface->oglId.texture != OPENGL_INVALID_ID)
    2889             {
    2890                 glDeleteTextures(1, &pSurface->oglId.texture);
    2891                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    2892             }
    2893             break;
    2894 
    2895         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    2896         case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
    2897         case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:    /* @todo actual texture surface not supported */
    2898             if (pSurface->oglId.renderbuffer != OPENGL_INVALID_ID)
    2899             {
    2900                 pState->ext.glDeleteRenderbuffers(1, &pSurface->oglId.renderbuffer);
    2901                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    2902             }
    2903             break;
    2904 
    2905         default:
    2906             break;
    2907         }
    2908 
    2909         if (pSurface->pMipmapLevels)
    2910         {
    2911             for (uint32_t face=0; face < pSurface->cFaces; face++)
    2912             {
    2913                 for (uint32_t i=0; i < pSurface->faces[face].numMipLevels; i++)
    2914                 {
    2915                     uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
    2916                     if (pSurface->pMipmapLevels[idx].pSurfaceData)
    2917                         RTMemFree(pSurface->pMipmapLevels[idx].pSurfaceData);
    2918                 }
    2919             }
    2920             RTMemFree(pSurface->pMipmapLevels);
    2921         }
    2922 
    2923         memset(pSurface, 0, sizeof(*pSurface));
    2924         pSurface->id = SVGA3D_INVALID_ID;
    2925     }
    2926     else
    2927         AssertFailedReturn(VERR_INVALID_PARAMETER);
    2928 
    2929     return VINF_SUCCESS;
    2930 }
    2931 
    2932 int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
    2933 {
    2934     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    2935     uint32_t            sidSrc = src.sid;
    2936     uint32_t            sidDest = dest.sid;
    2937     int                 rc = VINF_SUCCESS;
    2938 
    2939     AssertReturn(pState, VERR_NO_MEMORY);
    2940     AssertReturn(sidSrc < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    2941     AssertReturn(sidSrc < pState->cSurfaces && pState->papSurfaces[sidSrc]->id == sidSrc, VERR_INVALID_PARAMETER);
    2942     AssertReturn(sidDest < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    2943     AssertReturn(sidDest < pState->cSurfaces && pState->papSurfaces[sidDest]->id == sidDest, VERR_INVALID_PARAMETER);
    2944 
    2945     for (uint32_t i = 0; i < cCopyBoxes; i++)
    2946     {
    2947         SVGA3dBox destBox, srcBox;
    2948 
    2949         srcBox.x = pBox[i].srcx;
    2950         srcBox.y = pBox[i].srcy;
    2951         srcBox.z = pBox[i].srcz;
    2952         srcBox.w = pBox[i].w;
    2953         srcBox.h = pBox[i].h;
    2954         srcBox.d = pBox[i].z; /* XXX what about pBox[i].d? */
    2955 
    2956         destBox.x = pBox[i].x;
    2957         destBox.y = pBox[i].y;
    2958         destBox.z = pBox[i].z;
    2959         destBox.w = pBox[i].w;
    2960         destBox.h = pBox[i].h;
    2961         destBox.z = pBox[i].z; /* XXX initializing destBox.z again? What about pBox[i].d and destBox.d? */
    2962 
    2963         rc = vmsvga3dSurfaceStretchBlt(pThis, dest, destBox, src, srcBox, SVGA3D_STRETCH_BLT_LINEAR);
    2964         AssertRCReturn(rc, rc);
    2965     }
    2966     return VINF_SUCCESS;
    2967 }
    2968 
    2969 
    2970 /**
    2971  * Save texture unpacking parameters and loads those appropriate for the given
    2972  * surface.
    2973  *
    2974  * @param   pState              The VMSVGA3D state structure.
    2975  * @param   pContext            The active context.
    2976  * @param   pSurface            The surface.
    2977  * @param   pSave               Where to save stuff.
    2978  */
    2979 static void vmsvga3dSetUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    2980                                     PVMSVGAPACKPARAMS pSave)
    2981 {
    2982     /*
    2983      * Save (ignore errors, setting the defaults we want and avoids restore).
    2984      */
    2985     pSave->iAlignment = 1;
    2986     VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ALIGNMENT, &pSave->iAlignment), pState, pContext);
    2987     pSave->cxRow = 0;
    2988     VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ROW_LENGTH, &pSave->cxRow), pState, pContext);
    2989 
    2990 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    2991     pSave->cyImage = 0;
    2992     glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &pSave->cyImage);
    2993     Assert(pSave->cyImage == 0);
    2994 
    2995     pSave->fSwapBytes = GL_FALSE;
    2996     glGetBooleanv(GL_UNPACK_SWAP_BYTES, &pSave->fSwapBytes);
    2997     Assert(pSave->fSwapBytes == GL_FALSE);
    2998 
    2999     pSave->fLsbFirst = GL_FALSE;
    3000     glGetBooleanv(GL_UNPACK_LSB_FIRST, &pSave->fLsbFirst);
    3001     Assert(pSave->fLsbFirst == GL_FALSE);
    3002 
    3003     pSave->cSkipRows = 0;
    3004     glGetIntegerv(GL_UNPACK_SKIP_ROWS, &pSave->cSkipRows);
    3005     Assert(pSave->cSkipRows == 0);
    3006 
    3007     pSave->cSkipPixels = 0;
    3008     glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &pSave->cSkipPixels);
    3009     Assert(pSave->cSkipPixels == 0);
    3010 
    3011     pSave->cSkipImages = 0;
    3012     glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &pSave->cSkipImages);
    3013     Assert(pSave->cSkipImages == 0);
    3014 
    3015     VMSVGA3D_CLEAR_GL_ERRORS();
    3016 #endif
    3017 
    3018     /*
    3019      * Setup unpack.
    3020      *
    3021      * Note! We use 1 as alignment here because we currently don't do any
    3022      *       aligning of line pitches anywhere.
    3023      */
    3024     NOREF(pSurface);
    3025     if (pSave->iAlignment != 1)
    3026         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1), pState, pContext);
    3027     if (pSave->cxRow != 0)
    3028         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0), pState, pContext);
    3029 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    3030     if (pSave->cyImage != 0)
    3031         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0), pState, pContext);
    3032     if (pSave->fSwapBytes != 0)
    3033         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE), pState, pContext);
    3034     if (pSave->fLsbFirst != 0)
    3035         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE), pState, pContext);
    3036     if (pSave->cSkipRows != 0)
    3037         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS, 0), pState, pContext);
    3038     if (pSave->cSkipPixels != 0)
    3039         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0), pState, pContext);
    3040     if (pSave->cSkipImages != 0)
    3041         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0), pState, pContext);
    3042 #endif
    3043 }
    3044 
    3045 
    3046 /**
    3047  * Restores texture unpacking parameters.
    3048  *
    3049  * @param   pState              The VMSVGA3D state structure.
    3050  * @param   pContext            The active context.
    3051  * @param   pSurface            The surface.
    3052  * @param   pSave               Where stuff was saved.
    3053  */
    3054 static void vmsvga3dRestoreUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    3055                                         PCVMSVGAPACKPARAMS pSave)
    3056 {
    3057     NOREF(pSurface);
    3058     if (pSave->iAlignment != 1)
    3059         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, pSave->iAlignment), pState, pContext);
    3060     if (pSave->cxRow != 0)
    3061         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, pSave->cxRow), pState, pContext);
    3062 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    3063     if (pSave->cyImage != 0)
    3064         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, pSave->cyImage), pState, pContext);
    3065     if (pSave->fSwapBytes != 0)
    3066         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SWAP_BYTES, pSave->fSwapBytes), pState, pContext);
    3067     if (pSave->fLsbFirst != 0)
    3068         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_LSB_FIRST, pSave->fLsbFirst), pState, pContext);
    3069     if (pSave->cSkipRows != 0)
    3070         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS, pSave->cSkipRows), pState, pContext);
    3071     if (pSave->cSkipPixels != 0)
    3072         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS, pSave->cSkipPixels), pState, pContext);
    3073     if (pSave->cSkipImages != 0)
    3074         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_IMAGES, pSave->cSkipImages), pState, pContext);
    3075 #endif
    3076 }
    3077 
    3078 
    3079 /* Create D3D texture object for the specified surface. */
    3080 static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
    3081                                  PVMSVGA3DSURFACE pSurface)
    3082 {
    3083     GLint activeTexture = 0;
    3084 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3085     uint32_t idPrevCtx = pState->idActiveContext;
    3086     pContext = &pState->SharedCtx;
    3087     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3088 #endif
    3089 
    3090     glGenTextures(1, &pSurface->oglId.texture);
    3091     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3092     /* @todo Set the mip map generation filter settings. */
    3093 
    3094     glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    3095     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3096 
    3097     /* Must bind texture to the current context in order to change it. */
    3098     glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    3099     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3100 
    3101     /* Set the unpacking parameters. */
    3102     VMSVGAPACKPARAMS SavedParams;
    3103     vmsvga3dSetUnpackParams(pState, pContext, pSurface, &SavedParams);
    3104 
    3105     /* Set the mipmap base and max level paramters. */
    3106     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    3107     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3108     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pSurface->faces[0].numMipLevels);
    3109     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3110 
    3111     if (pSurface->fDirty)
    3112         Log(("vmsvga3dCreateTexture: sync dirty texture\n"));
    3113 
    3114     /* Always allocate and initialize all mipmap levels; non-initialized mipmap levels used as render targets cause failures. */
    3115     for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
    3116     {
    3117         /* Allocate and initialize texture memory.  Passing the zero filled pSurfaceData avoids
    3118             exposing random host memory to the guest and helps a with the fedora 21 surface
    3119             corruption issues (launchpad, background, search field, login). */
    3120         if (pSurface->pMipmapLevels[i].fDirty)
    3121             Log(("vmsvga3dCreateTexture: sync dirty texture mipmap level %d (pitch %x)\n", i, pSurface->pMipmapLevels[i].cbSurfacePitch));
    3122 
    3123         glTexImage2D(GL_TEXTURE_2D,
    3124                         i,
    3125                         pSurface->internalFormatGL,
    3126                         pSurface->pMipmapLevels[i].size.width,
    3127                         pSurface->pMipmapLevels[i].size.height,
    3128                         0,
    3129                         pSurface->formatGL,
    3130                         pSurface->typeGL,
    3131                         pSurface->pMipmapLevels[i].pSurfaceData);
    3132 
    3133         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3134 
    3135         pSurface->pMipmapLevels[i].fDirty = false;
    3136     }
    3137     pSurface->fDirty = false;
    3138 
    3139     /* Restore unpacking parameters. */
    3140     vmsvga3dRestoreUnpackParams(pState, pContext, pSurface, &SavedParams);
    3141 
    3142     /* Restore the old active texture. */
    3143     glBindTexture(GL_TEXTURE_2D, activeTexture);
    3144     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3145 
    3146     pSurface->flags              |= SVGA3D_SURFACE_HINT_TEXTURE;
    3147 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    3148     LogFlow(("vmsvga3dCreateTexture: sid=%x idAssociatedContext %#x -> %#x; oglId.texture=%#x\n",
    3149              pSurface->id, pSurface->idAssociatedContext, idAssociatedContext, pSurface->oglId.texture));
    3150     pSurface->idAssociatedContext = idAssociatedContext;
    3151 #endif
    3152 
    3153 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3154     if (idPrevCtx < pState->cContexts && pState->papContexts[idPrevCtx]->id == idPrevCtx)
    3155         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pState->papContexts[idPrevCtx]);
    3156 #endif
    3157     return VINF_SUCCESS;
    3158 }
    3159 
    3160 int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dBox destBox,
    3161                               SVGA3dSurfaceImageId src, SVGA3dBox srcBox, SVGA3dStretchBltMode mode)
    3162 {
    3163     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    3164     PVMSVGA3DSURFACE    pSurfaceSrc;
    3165     uint32_t            sidSrc = src.sid;
    3166     PVMSVGA3DSURFACE    pSurfaceDest;
    3167     uint32_t            sidDest = dest.sid;
    3168     int                 rc = VINF_SUCCESS;
    3169     uint32_t            cid;
    3170     PVMSVGA3DCONTEXT    pContext;
    3171 
    3172     AssertReturn(pState, VERR_NO_MEMORY);
    3173     AssertReturn(sidSrc < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    3174     AssertReturn(sidSrc < pState->cSurfaces && pState->papSurfaces[sidSrc]->id == sidSrc, VERR_INVALID_PARAMETER);
    3175     AssertReturn(sidDest < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    3176     AssertReturn(sidDest < pState->cSurfaces && pState->papSurfaces[sidDest]->id == sidDest, VERR_INVALID_PARAMETER);
    3177 
    3178     pSurfaceSrc  = pState->papSurfaces[sidSrc];
    3179     pSurfaceDest = pState->papSurfaces[sidDest];
    3180     AssertReturn(pSurfaceSrc->faces[0].numMipLevels > src.mipmap, VERR_INVALID_PARAMETER);
    3181     AssertReturn(pSurfaceDest->faces[0].numMipLevels > dest.mipmap, VERR_INVALID_PARAMETER);
    3182 
    3183 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3184     Log(("vmsvga3dSurfaceStretchBlt: src sid=%x (%d,%d)(%d,%d) dest sid=%x (%d,%d)(%d,%d) mode=%x\n",
    3185          src.sid, srcBox.x, srcBox.y, srcBox.x + srcBox.w, srcBox.y + srcBox.h,
    3186          dest.sid, destBox.x, destBox.y, destBox.x + destBox.w, destBox.y + destBox.h, mode));
    3187     cid = SVGA3D_INVALID_ID;
    3188     pContext = &pState->SharedCtx;
    3189     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3190 #else
    3191     Log(("vmsvga3dSurfaceStretchBlt: src sid=%x cid=%x (%d,%d)(%d,%d) dest sid=%x cid=%x (%d,%d)(%d,%d) mode=%x\n",
    3192          src.sid, pSurfaceSrc->idAssociatedContext, srcBox.x, srcBox.y, srcBox.x + srcBox.w, srcBox.y + srcBox.h,
    3193          dest.sid, pSurfaceDest->idAssociatedContext, destBox.x, destBox.y, destBox.x + destBox.w, destBox.y + destBox.h, mode));
    3194 
    3195     /* @todo stricter checks for associated context */
    3196     cid = pSurfaceDest->idAssociatedContext;
    3197     if (cid == SVGA3D_INVALID_ID)
    3198         cid = pSurfaceSrc->idAssociatedContext;
    3199 
    3200     if (    cid >= pState->cContexts
    3201         ||  pState->papContexts[cid]->id != cid)
    3202     {
    3203         Log(("vmsvga3dSurfaceStretchBlt invalid context id!\n"));
    3204         AssertFailedReturn(VERR_INVALID_PARAMETER);
    3205     }
    3206     pContext = pState->papContexts[cid];
    3207     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3208 #endif
    3209 
    3210     if (pSurfaceSrc->oglId.texture == OPENGL_INVALID_ID)
    3211     {
    3212         /* Unknown surface type; turn it into a texture, which can be used for other purposes too. */
    3213         Log(("vmsvga3dSurfaceStretchBlt: unknown src surface id=%x type=%d format=%d -> create texture\n", sidSrc, pSurfaceSrc->flags, pSurfaceSrc->format));
    3214         rc = vmsvga3dCreateTexture(pState, pContext, cid, pSurfaceSrc);
    3215         AssertRCReturn(rc, rc);
    3216     }
    3217 
    3218     if (pSurfaceDest->oglId.texture == OPENGL_INVALID_ID)
    3219     {
    3220         /* Unknown surface type; turn it into a texture, which can be used for other purposes too. */
    3221         Log(("vmsvga3dSurfaceStretchBlt: unknown dest surface id=%x type=%d format=%d -> create texture\n", sidDest, pSurfaceDest->flags, pSurfaceDest->format));
    3222         rc = vmsvga3dCreateTexture(pState, pContext, cid, pSurfaceDest);
    3223         AssertRCReturn(rc, rc);
    3224     }
    3225 
    3226     /* Activate the read and draw framebuffer objects. */
    3227     pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer);
    3228     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3229     pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pContext->idDrawFramebuffer);
    3230     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3231 
    3232     /* Bind the source and destination objects to the right place. */
    3233     pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
    3234                                        pSurfaceSrc->oglId.texture, src.mipmap);
    3235     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3236     pState->ext.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
    3237                                        pSurfaceDest->oglId.texture, dest.mipmap);
    3238     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3239 
    3240     Log(("src conv. (%d,%d)(%d,%d); dest conv (%d,%d)(%d,%d)\n", srcBox.x, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y + srcBox.h),
    3241          srcBox.x + srcBox.w, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y), destBox.x, D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y + destBox.h),
    3242          destBox.x + destBox.w, D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y)));
    3243 
    3244     pState->ext.glBlitFramebuffer(srcBox.x,
    3245 #ifdef MANUAL_FLIP_SURFACE_DATA
    3246                                   D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y + srcBox.h),     /* inclusive */
    3247 #else
    3248                                   srcBox.y,
    3249 #endif
    3250                                   srcBox.x + srcBox.w,                                      /* exclusive. */
    3251 #ifdef MANUAL_FLIP_SURFACE_DATA
    3252                                   D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y),                /* exclusive */
    3253 #else
    3254                                   srcBox.y + srcBox.h,
    3255 #endif
    3256                                   destBox.x,
    3257 #ifdef MANUAL_FLIP_SURFACE_DATA
    3258                                   D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y + destBox.h),  /* inclusive. */
    3259 #else
    3260                                   destBox.y,
    3261 #endif
    3262                                   destBox.x + destBox.w,                                    /* exclusive. */
    3263 #ifdef MANUAL_FLIP_SURFACE_DATA
    3264                                   D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y),              /* exclusive */
    3265 #else
    3266                                   destBox.y + destBox.h,
    3267 #endif
    3268                                   GL_COLOR_BUFFER_BIT,
    3269                                   (mode == SVGA3D_STRETCH_BLT_POINT) ? GL_NEAREST : GL_LINEAR);
    3270     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3271 
    3272     /* Reset the frame buffer association */
    3273     pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, pContext->idFramebuffer);
    3274     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3275 
    3276     return VINF_SUCCESS;
    3277 }
    3278 
    3279 /**
    3280  * Save texture packing parameters and loads those appropriate for the given
    3281  * surface.
    3282  *
    3283  * @param   pState              The VMSVGA3D state structure.
    3284  * @param   pContext            The active context.
    3285  * @param   pSurface            The surface.
    3286  * @param   pSave               Where to save stuff.
    3287  */
    3288 static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    3289                                   PVMSVGAPACKPARAMS pSave)
    3290 {
    3291     /*
    3292      * Save (ignore errors, setting the defaults we want and avoids restore).
    3293      */
    3294     pSave->iAlignment = 1;
    3295     VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ALIGNMENT, &pSave->iAlignment), pState, pContext);
    3296     pSave->cxRow = 0;
    3297     VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ROW_LENGTH, &pSave->cxRow), pState, pContext);
    3298 
    3299 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    3300     pSave->cyImage = 0;
    3301     glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pSave->cyImage);
    3302     Assert(pSave->cyImage == 0);
    3303 
    3304     pSave->fSwapBytes = GL_FALSE;
    3305     glGetBooleanv(GL_PACK_SWAP_BYTES, &pSave->fSwapBytes);
    3306     Assert(pSave->fSwapBytes == GL_FALSE);
    3307 
    3308     pSave->fLsbFirst = GL_FALSE;
    3309     glGetBooleanv(GL_PACK_LSB_FIRST, &pSave->fLsbFirst);
    3310     Assert(pSave->fLsbFirst == GL_FALSE);
    3311 
    3312     pSave->cSkipRows = 0;
    3313     glGetIntegerv(GL_PACK_SKIP_ROWS, &pSave->cSkipRows);
    3314     Assert(pSave->cSkipRows == 0);
    3315 
    3316     pSave->cSkipPixels = 0;
    3317     glGetIntegerv(GL_PACK_SKIP_PIXELS, &pSave->cSkipPixels);
    3318     Assert(pSave->cSkipPixels == 0);
    3319 
    3320     pSave->cSkipImages = 0;
    3321     glGetIntegerv(GL_PACK_SKIP_IMAGES, &pSave->cSkipImages);
    3322     Assert(pSave->cSkipImages == 0);
    3323 
    3324     VMSVGA3D_CLEAR_GL_ERRORS();
    3325 #endif
    3326 
    3327     /*
    3328      * Setup unpack.
    3329      *
    3330      * Note! We use 1 as alignment here because we currently don't do any
    3331      *       aligning of line pitches anywhere.
    3332      */
    3333     NOREF(pSurface);
    3334     if (pSave->iAlignment != 1)
    3335         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 1), pState, pContext);
    3336     if (pSave->cxRow != 0)
    3337         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ROW_LENGTH, 0), pState, pContext);
    3338 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    3339     if (pSave->cyImage != 0)
    3340         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0), pState, pContext);
    3341     if (pSave->fSwapBytes != 0)
    3342         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE), pState, pContext);
    3343     if (pSave->fLsbFirst != 0)
    3344         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE), pState, pContext);
    3345     if (pSave->cSkipRows != 0)
    3346         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_ROWS, 0), pState, pContext);
    3347     if (pSave->cSkipPixels != 0)
    3348         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_PIXELS, 0), pState, pContext);
    3349     if (pSave->cSkipImages != 0)
    3350         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_IMAGES, 0), pState, pContext);
    3351 #endif
    3352 }
    3353 
    3354 
    3355 /**
    3356  * Restores texture packing parameters.
    3357  *
    3358  * @param   pState              The VMSVGA3D state structure.
    3359  * @param   pContext            The active context.
    3360  * @param   pSurface            The surface.
    3361  * @param   pSave               Where stuff was saved.
    3362  */
    3363 static void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    3364                                       PCVMSVGAPACKPARAMS pSave)
    3365 {
    3366     NOREF(pSurface);
    3367     if (pSave->iAlignment != 1)
    3368         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, pSave->iAlignment), pState, pContext);
    3369     if (pSave->cxRow != 0)
    3370         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ROW_LENGTH, pSave->cxRow), pState, pContext);
    3371 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    3372     if (pSave->cyImage != 0)
    3373         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_IMAGE_HEIGHT, pSave->cyImage), pState, pContext);
    3374     if (pSave->fSwapBytes != 0)
    3375         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SWAP_BYTES, pSave->fSwapBytes), pState, pContext);
    3376     if (pSave->fLsbFirst != 0)
    3377         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_LSB_FIRST, pSave->fLsbFirst), pState, pContext);
    3378     if (pSave->cSkipRows != 0)
    3379         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_ROWS, pSave->cSkipRows), pState, pContext);
    3380     if (pSave->cSkipPixels != 0)
    3381         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_PIXELS, pSave->cSkipPixels), pState, pContext);
    3382     if (pSave->cSkipImages != 0)
    3383         VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_IMAGES, pSave->cSkipImages), pState, pContext);
    3384 #endif
    3385 }
    3386 
    3387 
    3388 int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer,
    3389                        uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
    3390 {
    3391     PVMSVGA3DSTATE          pState = pThis->svga.p3dState;
    3392     PVMSVGA3DSURFACE        pSurface;
    3393     PVMSVGA3DMIPMAPLEVEL    pMipLevel;
    3394     uint32_t                sid = host.sid;
    3395     int                     rc = VINF_SUCCESS;
    3396 
    3397     AssertReturn(pState, VERR_NO_MEMORY);
    3398     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    3399     AssertReturn(sid < pState->cSurfaces && pState->papSurfaces[sid]->id == sid, VERR_INVALID_PARAMETER);
    3400 
    3401     pSurface = pState->papSurfaces[sid];
    3402     AssertReturn(pSurface->faces[0].numMipLevels > host.mipmap, VERR_INVALID_PARAMETER);
    3403     pMipLevel = &pSurface->pMipmapLevels[host.mipmap];
    3404 
    3405     if (pSurface->flags & SVGA3D_SURFACE_HINT_TEXTURE)
    3406         Log(("vmsvga3dSurfaceDMA TEXTURE guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%s cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", cCopyBoxes));
    3407     else
    3408         Log(("vmsvga3dSurfaceDMA guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%s cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", cCopyBoxes));
    3409 
    3410     if (pSurface->oglId.texture == OPENGL_INVALID_ID)
    3411     {
    3412         AssertReturn(pSurface->pMipmapLevels[host.mipmap].pSurfaceData, VERR_INTERNAL_ERROR);
    3413 
    3414         for (unsigned i = 0; i < cCopyBoxes; i++)
    3415         {
    3416             unsigned uDestOffset;
    3417             unsigned cbSrcPitch;
    3418             uint8_t *pBufferStart;
    3419 
    3420             Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, pBoxes[i].srcx, pBoxes[i].srcy, pBoxes[i].srcz, pBoxes[i].w, pBoxes[i].h, pBoxes[i].d, pBoxes[i].x, pBoxes[i].y));
    3421             /* Apparently we're supposed to clip it (gmr test sample) */
    3422             if (pBoxes[i].x + pBoxes[i].w > pMipLevel->size.width)
    3423                 pBoxes[i].w = pMipLevel->size.width - pBoxes[i].x;
    3424             if (pBoxes[i].y + pBoxes[i].h > pMipLevel->size.height)
    3425                 pBoxes[i].h = pMipLevel->size.height - pBoxes[i].y;
    3426             if (pBoxes[i].z + pBoxes[i].d > pMipLevel->size.depth)
    3427                 pBoxes[i].d = pMipLevel->size.depth - pBoxes[i].z;
    3428 
    3429             if (    !pBoxes[i].w
    3430                 ||  !pBoxes[i].h
    3431                 ||  !pBoxes[i].d
    3432                 ||   pBoxes[i].x > pMipLevel->size.width
    3433                 ||   pBoxes[i].y > pMipLevel->size.height
    3434                 ||   pBoxes[i].z > pMipLevel->size.depth)
    3435             {
    3436                 Log(("Empty box; skip\n"));
    3437                 continue;
    3438             }
    3439 
    3440             uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch + pBoxes[i].z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;
    3441             AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock * pBoxes[i].h * pBoxes[i].d <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
    3442 
    3443             cbSrcPitch = (guest.pitch == 0) ? pBoxes[i].w * pSurface->cbBlock : guest.pitch;
    3444 #ifdef MANUAL_FLIP_SURFACE_DATA
    3445             pBufferStart =    (uint8_t *)pMipLevel->pSurfaceData
    3446                             + pBoxes[i].x * pSurface->cbBlock
    3447                             + pMipLevel->cbSurface - pBoxes[i].y * pMipLevel->cbSurfacePitch
    3448                             - pMipLevel->cbSurfacePitch;      /* flip image during copy */
    3449 #else
    3450             pBufferStart = (uint8_t *)pMipLevel->pSurfaceData + uDestOffset;
    3451 #endif
    3452             rc = vmsvgaGMRTransfer(pThis,
    3453                                    transfer,
    3454                                    pBufferStart,
    3455 #ifdef MANUAL_FLIP_SURFACE_DATA
    3456                                    -(int32_t)pMipLevel->cbSurfacePitch,
    3457 #else
    3458                                    (int32_t)pMipLevel->cbSurfacePitch,
    3459 #endif
    3460                                    guest.ptr,
    3461                                    pBoxes[i].srcx * pSurface->cbBlock + (pBoxes[i].srcy + pBoxes[i].srcz * pBoxes[i].h) * cbSrcPitch,
    3462                                    cbSrcPitch,
    3463                                    pBoxes[i].w * pSurface->cbBlock,
    3464                                    pBoxes[i].d * pBoxes[i].h);
    3465 
    3466             Log4(("first line:\n%.*Rhxd\n", pMipLevel->cbSurface, pMipLevel->pSurfaceData));
    3467 
    3468             AssertRC(rc);
    3469         }
    3470         pSurface->pMipmapLevels[host.mipmap].fDirty = true;
    3471         pSurface->fDirty = true;
    3472     }
    3473     else
    3474     {
    3475 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3476         PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    3477 #else
    3478         /* @todo stricter checks for associated context */
    3479         uint32_t cid = pSurface->idAssociatedContext;
    3480         if (    cid >= pState->cContexts
    3481             ||  pState->papContexts[cid]->id != cid)
    3482         {
    3483             Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    3484             AssertFailedReturn(VERR_INVALID_PARAMETER);
    3485         }
    3486         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    3487 #endif
    3488         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3489 
    3490         for (unsigned i = 0; i < cCopyBoxes; i++)
    3491         {
    3492             bool fVertex = false;
    3493             unsigned cbSrcPitch;
    3494 
    3495             /* Apparently we're supposed to clip it (gmr test sample) */
    3496             if (pBoxes[i].x + pBoxes[i].w > pMipLevel->size.width)
    3497                 pBoxes[i].w = pMipLevel->size.width - pBoxes[i].x;
    3498             if (pBoxes[i].y + pBoxes[i].h > pMipLevel->size.height)
    3499                 pBoxes[i].h = pMipLevel->size.height - pBoxes[i].y;
    3500             if (pBoxes[i].z + pBoxes[i].d > pMipLevel->size.depth)
    3501                 pBoxes[i].d = pMipLevel->size.depth - pBoxes[i].z;
    3502 
    3503             Assert((pBoxes[i].d == 1 || pBoxes[i].d == 0) && pBoxes[i].z == 0);
    3504 
    3505             if (    !pBoxes[i].w
    3506                 ||  !pBoxes[i].h
    3507                 ||   pBoxes[i].x > pMipLevel->size.width
    3508                 ||   pBoxes[i].y > pMipLevel->size.height)
    3509             {
    3510                 Log(("Empty box; skip\n"));
    3511                 continue;
    3512             }
    3513 
    3514             Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, pBoxes[i].srcx, pBoxes[i].srcy, pBoxes[i].srcz, pBoxes[i].w, pBoxes[i].h, pBoxes[i].d, pBoxes[i].x, pBoxes[i].y));
    3515 
    3516             cbSrcPitch = (guest.pitch == 0) ? pBoxes[i].w * pSurface->cbBlock : guest.pitch;
    3517 
    3518             switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
    3519             {
    3520             case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    3521             case SVGA3D_SURFACE_HINT_TEXTURE:
    3522             case SVGA3D_SURFACE_HINT_RENDERTARGET:
    3523             {
    3524                 uint32_t cbSurfacePitch;
    3525                 uint8_t *pDoubleBuffer, *pBufferStart;
    3526                 unsigned uDestOffset = 0;
    3527 
    3528                 pDoubleBuffer = (uint8_t *)RTMemAlloc(pMipLevel->cbSurface);
    3529                 AssertReturn(pDoubleBuffer, VERR_NO_MEMORY);
    3530 
    3531                 if (transfer == SVGA3D_READ_HOST_VRAM)
    3532                 {
    3533                     GLint activeTexture;
    3534 
    3535                     /* Must bind texture to the current context in order to read it. */
    3536                     glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    3537                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3538 
    3539                     glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    3540                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3541 
    3542                     /* Set row length and alignment of the input data. */
    3543                     VMSVGAPACKPARAMS SavedParams;
    3544                     vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
    3545 
    3546                     glGetTexImage(GL_TEXTURE_2D,
    3547                                   host.mipmap,
    3548                                   pSurface->formatGL,
    3549                                   pSurface->typeGL,
    3550                                   pDoubleBuffer);
    3551                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3552 
    3553                     vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
    3554 
    3555                     /* Restore the old active texture. */
    3556                     glBindTexture(GL_TEXTURE_2D, activeTexture);
    3557                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3558 
    3559                     uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch;
    3560                     AssertReturnStmt(   uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch
    3561                                      <= pMipLevel->cbSurface,
    3562                                      RTMemFree(pDoubleBuffer),
    3563                                      VERR_INTERNAL_ERROR);
    3564 
    3565                     cbSurfacePitch = pMipLevel->cbSurfacePitch;
    3566 
    3567 #ifdef MANUAL_FLIP_SURFACE_DATA
    3568                     pBufferStart =   pDoubleBuffer
    3569                                    + pBoxes[i].x * pSurface->cbBlock
    3570                                    + pMipLevel->cbSurface - pBoxes[i].y * cbSurfacePitch
    3571                                    - cbSurfacePitch;      /* flip image during copy */
    3572 #else
    3573                     pBufferStart = pDoubleBuffer + uDestOffset;
    3574 #endif
    3575                 }
    3576                 else
    3577                 {
    3578                     cbSurfacePitch = pBoxes[i].w * pSurface->cbBlock;
    3579 #ifdef MANUAL_FLIP_SURFACE_DATA
    3580                     pBufferStart = pDoubleBuffer + cbSurfacePitch * pBoxes[i].h - cbSurfacePitch;      /* flip image during copy */
    3581 #else
    3582                     pBufferStart = pDoubleBuffer;
    3583 #endif
    3584                 }
    3585 
    3586                 rc = vmsvgaGMRTransfer(pThis,
    3587                                        transfer,
    3588                                        pBufferStart,
    3589 #ifdef MANUAL_FLIP_SURFACE_DATA
    3590                                        -(int32_t)cbSurfacePitch,
    3591 #else
    3592                                        (int32_t)cbSurfacePitch,
    3593 #endif
    3594                                        guest.ptr,
    3595                                        pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch,
    3596                                        cbSrcPitch,
    3597                                        pBoxes[i].w * pSurface->cbBlock,
    3598                                        pBoxes[i].h);
    3599                 AssertRC(rc);
    3600 
    3601                 /* Update the opengl surface data. */
    3602                 if (transfer == SVGA3D_WRITE_HOST_VRAM)
    3603                 {
    3604                     GLint activeTexture = 0;
    3605 
    3606                     glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    3607                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3608 
    3609                     /* Must bind texture to the current context in order to change it. */
    3610                     glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    3611                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3612 
    3613                     Log(("vmsvga3dSurfaceDMA: copy texture mipmap level %d (pitch %x)\n", host.mipmap, pMipLevel->cbSurfacePitch));
    3614 
    3615                     /* Set row length and alignment of the input data. */
    3616                     VMSVGAPACKPARAMS SavedParams;
    3617                     vmsvga3dSetUnpackParams(pState, pContext, pSurface, &SavedParams); /** @todo do we need to set ROW_LENGTH to w here? */
    3618 
    3619                     glTexSubImage2D(GL_TEXTURE_2D,
    3620                                     host.mipmap,
    3621                                     pBoxes[i].x,
    3622                                     pBoxes[i].y,
    3623                                     pBoxes[i].w,
    3624                                     pBoxes[i].h,
    3625                                     pSurface->formatGL,
    3626                                     pSurface->typeGL,
    3627                                     pDoubleBuffer);
    3628 
    3629                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3630 
    3631                     /* Restore old values. */
    3632                     vmsvga3dRestoreUnpackParams(pState, pContext, pSurface, &SavedParams);
    3633 
    3634                     /* Restore the old active texture. */
    3635                     glBindTexture(GL_TEXTURE_2D, activeTexture);
    3636                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3637                 }
    3638 
    3639                 Log4(("first line:\n%.*Rhxd\n", pBoxes[i].w * pSurface->cbBlock, pDoubleBuffer));
    3640 
    3641                 /* Free the double buffer. */
    3642                 RTMemFree(pDoubleBuffer);
    3643                 break;
    3644             }
    3645 
    3646             case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
    3647                 AssertFailed(); /* @todo */
    3648                 break;
    3649 
    3650             case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    3651             case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    3652             {
    3653                 Assert(pBoxes[i].h == 1);
    3654 
    3655                 VMSVGA3D_CLEAR_GL_ERRORS();
    3656                 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
    3657                 if (VMSVGA3D_GL_IS_SUCCESS(pContext))
    3658                 {
    3659                     GLenum enmGlTransfer = (transfer == SVGA3D_READ_HOST_VRAM) ? GL_READ_ONLY : GL_WRITE_ONLY;
    3660                     uint8_t *pbData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, enmGlTransfer);
    3661                     if (RT_LIKELY(pbData != NULL))
    3662                     {
    3663 #if defined(VBOX_STRICT) && defined(RT_OS_DARWIN)
    3664                         GLint cbStrictBufSize;
    3665                         glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &cbStrictBufSize);
    3666                         Assert(VMSVGA3D_GL_IS_SUCCESS(pContext));
    3667 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3668                         AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,
    3669                                   ("cbStrictBufSize=%#x cbSurface=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pContext->id));
    3670 # else
    3671                         AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,
    3672                                   ("cbStrictBufSize=%#x cbSurface=%#x isAssociatedContext=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pSurface->idAssociatedContext, pContext->id));
    3673 # endif
    3674 #endif
    3675 
    3676                         unsigned offDst = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch;
    3677                         if (RT_LIKELY(   offDst + pBoxes[i].w * pSurface->cbBlock  + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch
    3678                                       <= pMipLevel->cbSurface))
    3679                         {
    3680                             Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (fVertex) ? "vertex" : "index",
    3681                                  pBoxes[i].x, pBoxes[i].y, pBoxes[i].x + pBoxes[i].w, pBoxes[i].y + pBoxes[i].h));
    3682 
    3683                             rc = vmsvgaGMRTransfer(pThis,
    3684                                                    transfer,
    3685                                                    pbData + offDst,
    3686                                                    pMipLevel->cbSurfacePitch,
    3687                                                    guest.ptr,
    3688                                                    pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch,
    3689                                                    cbSrcPitch,
    3690                                                    pBoxes[i].w * pSurface->cbBlock,
    3691                                                    pBoxes[i].h);
    3692                             AssertRC(rc);
    3693 
    3694                             Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pbData));
    3695                         }
    3696                         else
    3697                         {
    3698                             AssertFailed();
    3699                             rc = VERR_INTERNAL_ERROR;
    3700                         }
    3701 
    3702                         pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
    3703                         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3704                     }
    3705                     else
    3706                         VMSVGA3D_GL_GET_AND_COMPLAIN(pState, pContext, ("glMapBuffer(GL_ARRAY_BUFFER, %#x) -> NULL\n", enmGlTransfer));
    3707                 }
    3708                 else
    3709                     VMSVGA3D_GL_COMPLAIN(pState, pContext, ("glBindBuffer(GL_ARRAY_BUFFER, %#x)\n", pSurface->oglId.buffer));
    3710                 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
    3711                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3712                 break;
    3713             }
    3714 
    3715             default:
    3716                 AssertFailed();
    3717                 break;
    3718             }
    3719         }
    3720     }
    3721     return rc;
    3722 }
    3723 
    3724 int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect destRect, SVGA3dSurfaceImageId src, SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *pRect)
    3725 {
    3726     /* Requires SVGA_FIFO_CAP_SCREEN_OBJECT support */
    3727     Log(("vmsvga3dSurfaceBlitToScreen: dest=%d (%d,%d)(%d,%d) surface=%x (face=%d, mipmap=%d) (%d,%d)(%d,%d) cRects=%d\n", dest, destRect.left, destRect.top, destRect.right, destRect.bottom, src.sid, src.face, src.mipmap, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, cRects));
    3728     for (uint32_t i = 0; i < cRects; i++)
    3729     {
    3730         Log(("vmsvga3dSurfaceBlitToScreen: clipping rect %d (%d,%d)(%d,%d)\n", i, pRect[i].left, pRect[i].top, pRect[i].right, pRect[i].bottom));
    3731     }
    3732 
    3733     /* @todo Only screen 0 for now. */
    3734     AssertReturn(dest == 0, VERR_INTERNAL_ERROR);
    3735     AssertReturn(src.mipmap == 0 && src.face == 0, VERR_INVALID_PARAMETER);
    3736     /* @todo scaling */
    3737     AssertReturn(destRect.right - destRect.left == srcRect.right - srcRect.left && destRect.bottom - destRect.top == srcRect.bottom - srcRect.top, VERR_INVALID_PARAMETER);
    3738 
    3739     if (cRects == 0)
    3740     {
    3741         /* easy case; no clipping */
    3742         SVGA3dCopyBox        box;
    3743         SVGA3dGuestImage     dst;
    3744 
    3745         box.x       = destRect.left;
    3746         box.y       = destRect.top;
    3747         box.z       = 0;
    3748         box.w       = destRect.right - destRect.left;
    3749         box.h       = destRect.bottom - destRect.top;
    3750         box.d       = 1;
    3751         box.srcx    = srcRect.left;
    3752         box.srcy    = srcRect.top;
    3753         box.srcz    = 0;
    3754 
    3755         dst.ptr.gmrId  = SVGA_GMR_FRAMEBUFFER;
    3756         dst.ptr.offset = 0;
    3757         dst.pitch      = pThis->svga.cbScanline;
    3758 
    3759         int rc = vmsvga3dSurfaceDMA(pThis, dst, src, SVGA3D_READ_HOST_VRAM, 1, &box);
    3760         AssertRCReturn(rc, rc);
    3761 
    3762         vgaR3UpdateDisplay(pThis, box.x, box.y, box.w, box.h);
    3763         return VINF_SUCCESS;
    3764     }
    3765     else
    3766     {
    3767         SVGA3dGuestImage dst;
    3768         SVGA3dCopyBox    box;
    3769 
    3770         box.srcz    = 0;
    3771         box.z       = 0;
    3772         box.d       = 1;
    3773 
    3774         dst.ptr.gmrId  = SVGA_GMR_FRAMEBUFFER;
    3775         dst.ptr.offset = 0;
    3776         dst.pitch      = pThis->svga.cbScanline;
    3777 
    3778         /* @todo merge into one SurfaceDMA call */
    3779         for (uint32_t i = 0; i < cRects; i++)
    3780         {
    3781             /* The clipping rectangle is relative to the top-left corner of srcRect & destRect. Adjust here. */
    3782             box.srcx = srcRect.left + pRect[i].left;
    3783             box.srcy = srcRect.top  + pRect[i].top;
    3784 
    3785             box.x    = pRect[i].left + destRect.left;
    3786             box.y    = pRect[i].top  + destRect.top;
    3787             box.z    = 0;
    3788             box.w    = pRect[i].right - pRect[i].left;
    3789             box.h    = pRect[i].bottom - pRect[i].top;
    3790 
    3791             int rc = vmsvga3dSurfaceDMA(pThis, dst, src, SVGA3D_READ_HOST_VRAM, 1, &box);
    3792             AssertRCReturn(rc, rc);
    3793 
    3794             vgaR3UpdateDisplay(pThis, box.x, box.y, box.w, box.h);
    3795         }
    3796 
    3797         return VINF_SUCCESS;
    3798     }
    3799 }
    3800 
    3801 int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter filter)
    3802 {
    3803     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    3804     PVMSVGA3DSURFACE    pSurface;
    3805     int                 rc = VINF_SUCCESS;
    3806     PVMSVGA3DCONTEXT    pContext;
    3807     uint32_t            cid;
    3808     GLint               activeTexture = 0;
    3809 
    3810     AssertReturn(pState, VERR_NO_MEMORY);
    3811     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    3812     AssertReturn(sid < pState->cSurfaces && pState->papSurfaces[sid]->id == sid, VERR_INVALID_PARAMETER);
    3813 
    3814     pSurface = pState->papSurfaces[sid];
    3815 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    3816     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
    3817 #endif
    3818 
    3819     Assert(filter != SVGA3D_TEX_FILTER_FLATCUBIC);
    3820     Assert(filter != SVGA3D_TEX_FILTER_GAUSSIANCUBIC);
    3821     pSurface->autogenFilter = filter;
    3822 
    3823     Log(("vmsvga3dGenerateMipmaps: sid=%x filter=%d\n", sid, filter));
    3824 
    3825 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3826     cid = SVGA3D_INVALID_ID;
    3827     pContext = &pState->SharedCtx;
    3828     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3829 #else
    3830     /* @todo stricter checks for associated context */
    3831     cid = pSurface->idAssociatedContext;
    3832 
    3833     if (    cid >= pState->cContexts
    3834         ||  pState->papContexts[cid]->id != cid)
    3835     {
    3836         Log(("vmsvga3dGenerateMipmaps invalid context id!\n"));
    3837         return VERR_INVALID_PARAMETER;
    3838     }
    3839     pContext = pState->papContexts[cid];
    3840     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3841 #endif
    3842 
    3843     if (pSurface->oglId.texture == OPENGL_INVALID_ID)
    3844     {
    3845         /* Unknown surface type; turn it into a texture. */
    3846         Log(("vmsvga3dGenerateMipmaps: unknown src surface id=%x type=%d format=%d -> create texture\n", sid, pSurface->flags, pSurface->format));
    3847         rc = vmsvga3dCreateTexture(pState, pContext, cid, pSurface);
    3848         AssertRCReturn(rc, rc);
    3849     }
    3850     else
    3851     {
    3852         /* @todo new filter */
    3853         AssertFailed();
    3854     }
    3855 
    3856     glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    3857     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3858 
    3859     /* Must bind texture to the current context in order to change it. */
    3860     glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    3861     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3862 
    3863     /* Generate the mip maps. */
    3864     pState->ext.glGenerateMipmap(GL_TEXTURE_2D);
    3865     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3866 
    3867     /* Restore the old texture. */
    3868     glBindTexture(GL_TEXTURE_2D, activeTexture);
    3869     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    3870 
    3871     return VINF_SUCCESS;
    3872 }
    3873 
    3874 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
    3875 {
    3876     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    3877     PVMSVGA3DSURFACE    pSurface;
    3878     int                 rc = VINF_SUCCESS;
    3879     PVMSVGA3DCONTEXT    pContext;
    3880     uint32_t            cid;
    3881 
    3882     AssertReturn(pState, VERR_NO_MEMORY);
    3883     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    3884     AssertReturn(sid < pState->cSurfaces && pState->papSurfaces[sid]->id == sid, VERR_INVALID_PARAMETER);
    3885 
    3886     pSurface = pState->papSurfaces[sid];
    3887 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    3888     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
    3889 #endif
    3890 
    3891 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    3892     /* @todo stricter checks for associated context */
    3893     Log(("vmsvga3dCommandPresent: sid=%x cRects=%d\n", sid, cRects));
    3894     for (uint32_t i=0; i < cRects; i++)
    3895         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));
    3896 
    3897     pContext = &pState->SharedCtx;
    3898 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_1
    3899     if (   pSurface->idWeakContextAssociation < pState->cContexts
    3900         && pState->papContexts[pSurface->idWeakContextAssociation]->id == pSurface->idWeakContextAssociation)
    3901         pContext = pState->papContexts[pSurface->idWeakContextAssociation];
    3902 # endif
    3903     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3904     cid = pContext->id;
    3905 #else
    3906     /* @todo stricter checks for associated context */
    3907     cid = pSurface->idAssociatedContext;
    3908     Log(("vmsvga3dCommandPresent: sid=%x cRects=%d cid=%x\n", sid, cRects, cid));
    3909     for (uint32_t i=0; i < cRects; i++)
    3910     {
    3911         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));
    3912     }
    3913 
    3914     if (    cid >= pState->cContexts
    3915         ||  pState->papContexts[cid]->id != cid)
    3916     {
    3917         Log(("vmsvga3dCommandPresent invalid context id!\n"));
    3918         return VERR_INVALID_PARAMETER;
    3919     }
    3920     pContext = pState->papContexts[cid];
    3921     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    3922 #endif
    3923     VMSVGA3D_CLEAR_GL_ERRORS();
    3924 
    3925     /*
    3926      * Source surface different size?
    3927      */
    3928     RTRECT2 srcViewPort;
    3929     if (   pSurface->pMipmapLevels[0].size.width  != pThis->svga.uWidth
    3930         || pSurface->pMipmapLevels[0].size.height != pThis->svga.uHeight)
    3931     {
    3932         float xMultiplier = (float)pSurface->pMipmapLevels[0].size.width / (float)pThis->svga.uWidth;
    3933         float yMultiplier = (float)pSurface->pMipmapLevels[0].size.height / (float)pThis->svga.uHeight;
    3934 
    3935         LogFlow(("size (%d vs %d) (%d vs %d) multiplier (%d,%d)/100\n", pSurface->pMipmapLevels[0].size.width, pThis->svga.uWidth,
    3936                  pSurface->pMipmapLevels[0].size.height, pThis->svga.uHeight, (int)(xMultiplier * 100.0), (int)(yMultiplier * 100.0)));
    3937 
    3938         srcViewPort.x  = (uint32_t)((float)pThis->svga.viewport.x  * xMultiplier);
    3939         srcViewPort.y  = (uint32_t)((float)pThis->svga.viewport.y  * yMultiplier);
    3940         srcViewPort.cx = (uint32_t)((float)pThis->svga.viewport.cx * xMultiplier);
    3941         srcViewPort.cy = (uint32_t)((float)pThis->svga.viewport.cy * yMultiplier);
    3942     }
    3943     else
    3944     {
    3945         srcViewPort.x  = pThis->svga.viewport.x;
    3946         srcViewPort.y  = pThis->svga.viewport.y;
    3947         srcViewPort.cx = pThis->svga.viewport.cx;
    3948         srcViewPort.cy = pThis->svga.viewport.cy;
    3949     }
    3950     RTRECT SrcViewPortRect;
    3951     SrcViewPortRect.xLeft   = srcViewPort.x;
    3952     SrcViewPortRect.xRight  = srcViewPort.x + srcViewPort.cx;
    3953     SrcViewPortRect.yBottom = srcViewPort.y;
    3954     SrcViewPortRect.yTop    = srcViewPort.y + srcViewPort.cy;
    3955 
    3956 
    3957 #ifndef RT_OS_DARWIN /* blit-cube fails in this path... */
    3958     /*
    3959      * Note! this path is slightly faster than the glBlitFrameBuffer path below.
    3960      */
    3961     SVGA3dCopyRect rect;
    3962     uint32_t oldVShader, oldPShader;
    3963     GLint oldTextureId;
    3964 
    3965     if (cRects == 0)
    3966     {
    3967         rect.x = rect.y = rect.srcx = rect.srcy = 0;
    3968         rect.w = pSurface->pMipmapLevels[0].size.width;
    3969         rect.h = pSurface->pMipmapLevels[0].size.height;
    3970         pRect  = &rect;
    3971         cRects = 1;
    3972     }
    3973 
    3974     //glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
    3975 
    3976 #if 0
    3977     glDisable(GL_CULL_FACE);
    3978     glDisable(GL_BLEND);
    3979     glDisable(GL_ALPHA_TEST);
    3980     glDisable(GL_SCISSOR_TEST);
    3981     glDisable(GL_STENCIL_TEST);
    3982     glEnable(GL_DEPTH_TEST);
    3983     glDepthFunc(GL_ALWAYS);
    3984     glDepthMask(GL_TRUE);
    3985     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    3986     glViewport(0, 0, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height);
    3987 #endif
    3988 
    3989     VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureId), pState, pContext);
    3990 
    3991     oldVShader = pContext->state.shidVertex;
    3992     oldPShader = pContext->state.shidPixel;
    3993     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, SVGA_ID_INVALID);
    3994     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, SVGA_ID_INVALID);
    3995 
    3996     /* Flush shader changes. */
    3997     if (pContext->pShaderContext)
    3998         ShaderUpdateState(pContext->pShaderContext, 0);
    3999 
    4000     /* Activate the read and draw framebuffer objects. */
    4001     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer), pState, pContext);
    4002     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 /* back buffer */), pState, pContext);
    4003 
    4004     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glActiveTexture(GL_TEXTURE0), pState, pContext);
    4005     VMSVGA3D_ASSERT_GL_CALL(glEnable(GL_TEXTURE_2D), pState, pContext);;
    4006     VMSVGA3D_ASSERT_GL_CALL(glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture), pState, pContext);
    4007 
    4008     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR), pState, pContext);
    4009     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR), pState, pContext);;
    4010 
    4011 #if 0
    4012     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP), pState, pContext);;
    4013     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP), pState, pContext);;
    4014 #endif
    4015 
    4016     /* Reset the transformation matrices. */
    4017     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_MODELVIEW), pState, pContext);
    4018     VMSVGA3D_ASSERT_GL_CALL(glPushMatrix(), pState, pContext);
    4019     VMSVGA3D_ASSERT_GL_CALL(glLoadIdentity(), pState, pContext);
    4020     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_PROJECTION), pState, pContext);
    4021     VMSVGA3D_ASSERT_GL_CALL(glPushMatrix(), pState, pContext);
    4022     VMSVGA3D_ASSERT_GL_CALL(glLoadIdentity(), pState, pContext);
    4023     VMSVGA3D_ASSERT_GL_CALL(glScalef(1.0f, -1.0f, 1.0f), pState, pContext);
    4024     VMSVGA3D_ASSERT_GL_CALL(glOrtho(0, pThis->svga.uWidth, pThis->svga.uHeight, 0, 0.0, -1.0), pState, pContext);
    4025 
    4026     for (uint32_t i = 0; i < cRects; i++)
    4027     {
    4028         float left, right, top, bottom; /* Texture coordinates */
    4029         int   vertexLeft, vertexRight, vertexTop, vertexBottom;
    4030 
    4031         pRect[i].srcx = RT_MAX(pRect[i].srcx, (uint32_t)RT_MAX(srcViewPort.x, 0));
    4032         pRect[i].srcy = RT_MAX(pRect[i].srcy, (uint32_t)RT_MAX(srcViewPort.y, 0));
    4033         pRect[i].x    = RT_MAX(pRect[i].x, pThis->svga.viewport.x) - pThis->svga.viewport.x;
    4034         pRect[i].y    = RT_MAX(pRect[i].y, pThis->svga.viewport.y) - pThis->svga.viewport.y;
    4035         pRect[i].w    = pThis->svga.viewport.cx;
    4036         pRect[i].h    = pThis->svga.viewport.cy;
    4037 
    4038         if (    pRect[i].x + pRect[i].w <= pThis->svga.viewport.x
    4039             ||  pThis->svga.viewport.x + pThis->svga.viewport.cx <= pRect[i].x
    4040             ||  pRect[i].y + pRect[i].h <= pThis->svga.viewport.y
    4041             ||  pThis->svga.viewport.y + pThis->svga.viewport.cy <= pRect[i].y)
    4042         {
    4043             /* Intersection is empty; skip */
    4044             continue;
    4045         }
    4046 
    4047         left   = pRect[i].srcx;
    4048         right  = pRect[i].srcx + pRect[i].w;
    4049         top    = pRect[i].srcy + pRect[i].h;
    4050         bottom = pRect[i].srcy;
    4051 
    4052         left   /= pSurface->pMipmapLevels[0].size.width;
    4053         right  /= pSurface->pMipmapLevels[0].size.width;
    4054         top    /= pSurface->pMipmapLevels[0].size.height;
    4055         bottom /= pSurface->pMipmapLevels[0].size.height;
    4056 
    4057         vertexLeft   = pRect[i].x;
    4058         vertexRight  = pRect[i].x + pRect[i].w;
    4059         vertexTop    = ((uint32_t)pThis->svga.uHeight >= pRect[i].y + pRect[i].h) ? pThis->svga.uHeight - pRect[i].y - pRect[i].h : 0;
    4060         vertexBottom = pThis->svga.uHeight - pRect[i].y;
    4061 
    4062         Log(("view port (%d,%d)(%d,%d)\n", srcViewPort.x, srcViewPort.y, srcViewPort.cx, srcViewPort.cy));
    4063         Log(("vertex (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", vertexLeft, vertexBottom, vertexLeft, vertexTop, vertexRight, vertexTop, vertexRight, vertexBottom));
    4064         Log(("texture (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h), pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h)));
    4065 
    4066         glBegin(GL_QUADS);
    4067 
    4068         /* bottom left */
    4069         glTexCoord2f(left, bottom);
    4070         glVertex2i(vertexLeft, vertexBottom);
    4071 
    4072         /* top left */
    4073         glTexCoord2f(left, top);
    4074         glVertex2i(vertexLeft, vertexTop);
    4075 
    4076         /* top right */
    4077         glTexCoord2f(right, top);
    4078         glVertex2i(vertexRight, vertexTop);
    4079 
    4080         /* bottom right */
    4081         glTexCoord2f(right, bottom);
    4082         glVertex2i(vertexRight, vertexBottom);
    4083 
    4084         VMSVGA3D_ASSERT_GL_CALL(glEnd(), pState, pContext);
    4085     }
    4086 
    4087     /* Restore old settings. */
    4088     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_PROJECTION), pState, pContext);
    4089     VMSVGA3D_ASSERT_GL_CALL(glPopMatrix(), pState, pContext);
    4090     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_MODELVIEW), pState, pContext);
    4091     VMSVGA3D_ASSERT_GL_CALL(glPopMatrix(), pState, pContext);
    4092 
    4093     //VMSVGA3D_ASSERT_GL_CALL(glPopAttrib(), pState, pContext);
    4094 
    4095     VMSVGA3D_ASSERT_GL_CALL(glBindTexture(GL_TEXTURE_2D, oldTextureId), pState, pContext);
    4096     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, oldVShader);
    4097     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, oldPShader);
    4098 
    4099 #else
    4100     /*
    4101      * glBlitFramebuffer variant.
    4102      */
    4103     /* Activate the read and draw framebuffer objects. */
    4104     pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer);
    4105     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    4106     pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 /* back buffer */);
    4107     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    4108 
    4109     /* Bind the source objects to the right place. */
    4110     pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurface->oglId.texture, 0 /* level 0 */);
    4111     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    4112 
    4113     /* Blit the surface rectangle(s) to the back buffer. */
    4114     if (cRects == 0)
    4115 
    4116     {
    4117         Log(("view port (%d,%d)(%d,%d)\n", srcViewPort.x, srcViewPort.y, srcViewPort.cx, srcViewPort.cy));
    4118         pState->ext.glBlitFramebuffer(srcViewPort.x,
    4119                                       srcViewPort.y,
    4120                                       srcViewPort.x + srcViewPort.cx,   /* exclusive. */
    4121                                       srcViewPort.y + srcViewPort.cy,   /* exclusive. (reverse to flip the image) */
    4122                                       0,
    4123                                       pThis->svga.viewport.cy, /* exclusive. */
    4124                                       pThis->svga.viewport.cx, /* exclusive. */
    4125                                       0,
    4126                                       GL_COLOR_BUFFER_BIT,
    4127                                       GL_LINEAR);
    4128         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    4129     }
    4130     else
    4131     {
    4132         for (uint32_t i = 0; i < cRects; i++)
    4133         {
    4134 # ifdef RT_OS_DARWIN
    4135             /* This works better... */
    4136             RTRECT SrcRect;
    4137             SrcRect.xLeft   = pRect[i].srcx;
    4138             SrcRect.xRight  = pRect[i].srcx + pRect[i].w;
    4139             SrcRect.yBottom = pRect[i].srcy;
    4140             SrcRect.yTop    = pRect[i].srcy + pRect[i].h;
    4141             RTRECT DstRect; /* y flipped wrt source */
    4142             DstRect.xLeft   = pRect[i].x;
    4143             DstRect.xRight  = pRect[i].x + pRect[i].w;
    4144             DstRect.yBottom = pRect[i].y + pRect[i].h;
    4145             DstRect.yTop    = pRect[i].y;
    4146 
    4147             if (SrcRect.xLeft < SrcViewPortRect.xLeft)
    4148             {
    4149                 DstRect.xLeft += SrcViewPortRect.xLeft - SrcRect.xLeft;
    4150                 SrcRect.xLeft  = SrcViewPortRect.xLeft;
    4151             }
    4152             else if (SrcRect.xLeft >= SrcViewPortRect.xRight)
    4153                 continue;
    4154 
    4155             if (SrcRect.xRight > SrcViewPortRect.xRight)
    4156             {
    4157                 DstRect.xRight -= SrcViewPortRect.xRight - SrcRect.xRight;
    4158                 SrcRect.xRight  = SrcViewPortRect.xRight;
    4159             }
    4160             else if (SrcRect.xRight <= SrcViewPortRect.xLeft)
    4161                 continue;
    4162 
    4163             if (SrcRect.xRight <= SrcRect.xLeft)
    4164                 continue;
    4165 
    4166             if (SrcRect.yBottom < SrcViewPortRect.yBottom)
    4167             {
    4168                 DstRect.yTop    += SrcViewPortRect.yBottom - SrcRect.yBottom;
    4169                 SrcRect.yBottom  = SrcViewPortRect.yBottom;
    4170             }
    4171             else if (SrcRect.yBottom >= SrcViewPortRect.yTop)
    4172                 continue;
    4173 
    4174             if (SrcRect.yTop > SrcViewPortRect.yTop)
    4175             {
    4176                 DstRect.yBottom -= SrcViewPortRect.yTop - SrcRect.yTop;
    4177                 SrcRect.yTop     = SrcViewPortRect.yTop;
    4178             }
    4179             else if (SrcRect.yTop <= SrcViewPortRect.yBottom)
    4180                 continue;
    4181 
    4182             if (SrcRect.yTop <= SrcRect.yBottom)
    4183                 continue;
    4184 
    4185             Log(("SrcRect: (%d,%d)(%d,%d) DstRect: (%d,%d)(%d,%d)\n",
    4186                  SrcRect.xLeft, SrcRect.yBottom, SrcRect.xRight, SrcRect.yTop,
    4187                  DstRect.xLeft, DstRect.yBottom, DstRect.xRight, DstRect.yTop));
    4188             pState->ext.glBlitFramebuffer(SrcRect.xLeft, SrcRect.yBottom, SrcRect.xRight, SrcRect.yTop,
    4189                                           DstRect.xLeft, DstRect.yBottom, DstRect.xRight, DstRect.yTop,
    4190                                           GL_COLOR_BUFFER_BIT, GL_LINEAR);
    4191 
    4192 # else
    4193             if (    pRect[i].x + pRect[i].w <= pThis->svga.viewport.x
    4194                 ||  pThis->svga.viewport.x + pThis->svga.viewport.cx <= pRect[i].x
    4195                 ||  pRect[i].y + pRect[i].h <= pThis->svga.viewport.y
    4196                 ||  pThis->svga.viewport.y + pThis->svga.viewport.cy <= pRect[i].y)
    4197             {
    4198                 /* Intersection is empty; skip */
    4199                 continue;
    4200             }
    4201             pState->ext.glBlitFramebuffer(RT_MAX(pRect[i].srcx, srcViewPort.x),
    4202                                           pSurface->pMipmapLevels[0].size.width - RT_MAX(pRect[i].srcy, srcViewPort.y),   /* exclusive. (reverse to flip the image) */
    4203                                           RT_MIN(pRect[i].srcx + pRect[i].w, srcViewPort.x + srcViewPort.cx),  /* exclusive. */
    4204                                           pSurface->pMipmapLevels[0].size.width - RT_MIN(pRect[i].srcy + pRect[i].h, srcViewPort.y + srcViewPort.cy),
    4205                                           RT_MAX(pRect[i].x, pThis->svga.viewport.x) - pThis->svga.viewport.x,
    4206                                           pThis->svga.uHeight - (RT_MIN(pRect[i].y + pRect[i].h, pThis->svga.viewport.y + pThis->svga.viewport.cy) - pThis->svga.viewport.y),  /* exclusive. */
    4207                                           RT_MIN(pRect[i].x + pRect[i].w, pThis->svga.viewport.x + pThis->svga.viewport.cx) - pThis->svga.viewport.x,  /* exclusive. */
    4208                                           pThis->svga.uHeight - (RT_MAX(pRect[i].y, pThis->svga.viewport.y) - pThis->svga.viewport.y),
    4209                                           GL_COLOR_BUFFER_BIT,
    4210                                           GL_LINEAR);
    4211 # endif
    4212         }
    4213     }
    4214 
    4215 #endif
    4216 #ifndef RT_OS_DARWIN /* darwin: later */
    4217     /* Reset the frame buffer association - see below.  */
    4218     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, pContext->idFramebuffer), pState, pContext);
    4219 #endif
    4220 
    4221     /*
    4222      * Flip the front and back buffers.
    4223      */
    4224 #ifdef RT_OS_WINDOWS
    4225     BOOL ret = SwapBuffers(pContext->hdc);
    4226     AssertMsg(ret, ("SwapBuffers failed with %d\n", GetLastError()));
    4227 #elif defined(RT_OS_DARWIN)
    4228     vmsvga3dCocoaSwapBuffers(pContext->cocoaView, pContext->cocoaContext);
    4229 #else
    4230     /* show the window if not already done */
    4231     if (!pContext->fMapped)
    4232     {
    4233         XMapWindow(pState->display, pContext->window);
    4234         pContext->fMapped = true;
    4235     }
    4236     /* now swap the buffers, i.e. display the rendering result */
    4237     glXSwapBuffers(pState->display, pContext->window);
    4238 #endif
    4239 
    4240 #if defined(RT_OS_DARWIN)
    4241     /*
    4242      * Now we can reset the frame buffer association.  Doing it earlier means no
    4243      * output on darwin.
    4244      */
    4245     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, pContext->idFramebuffer), pState, pContext);
    4246 #endif
    4247     return VINF_SUCCESS;
    4248 }
    4249 
    4250 #ifdef RT_OS_LINUX
    4251 /**
    4252  * X11 event handling thread
    4253  * @param ThreadSelf thread handle
    4254  * @param pvUser pointer to pState structure
    4255  * @returns VBox status code
    4256  */
    4257 DECLCALLBACK(int) vmsvga3dXEventThread(RTTHREAD ThreadSelf, void *pvUser)
    4258 {
    4259     PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pvUser;
    4260     while (!pState->bTerminate)
    4261     {
    4262         while (XPending(pState->display) > 0)
    4263         {
    4264             XEvent event;
    4265             XNextEvent(pState->display, &event);
    4266 
    4267             switch (event.type)
    4268             {
    4269                 default:
    4270                     break;
    4271             }
    4272         }
    4273         /* sleep for 16ms to not burn too many cycles */
    4274         RTThreadSleep(16);
    4275     }
    4276     return VINF_SUCCESS;
    4277 }
    4278 #endif // RT_OS_LINUX
    4279 
    4280 
    4281 /**
    4282  * Create a new 3d context
    4283  *
    4284  * @returns VBox status code.
    4285  * @param   pThis           VGA device instance data.
    4286  * @param   cid             Context id
    4287  * @param   fFlags          VMSVGA3D_DEF_CTX_F_XXX.
    4288  */
    4289 static int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags)
    4290 {
    4291     int                     rc;
    4292     PVMSVGA3DCONTEXT        pContext;
    4293     PVMSVGA3DSTATE          pState = pThis->svga.p3dState;
    4294 
    4295     AssertReturn(pState, VERR_NO_MEMORY);
    4296 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    4297     AssertReturn(   cid < SVGA3D_MAX_CONTEXT_IDS
    4298                  || (cid == VMSVGA3D_SHARED_CTX_ID && (fFlags & VMSVGA3D_DEF_CTX_F_SHARED_CTX)), VERR_INVALID_PARAMETER);
    4299 #else
    4300     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
    4301 #endif
    4302 #if !defined(VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE) || !(defined(RT_OS_DARWIN))
    4303     AssertReturn(!(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE), VERR_INTERNAL_ERROR_3);
    4304 #endif
    4305 
    4306     Log(("vmsvga3dContextDefine id %x\n", cid));
    4307 #ifdef DEBUG_DEBUG_GFX_WINDOW_TEST_CONTEXT
    4308     if (pState->idTestContext == SVGA_ID_INVALID)
    4309     {
    4310         pState->idTestContext = 207;
    4311         rc = vmsvga3dContextDefine(pThis, pState->idTestContext);
    4312         AssertRCReturn(rc, rc);
    4313     }
    4314 #endif
    4315 
    4316 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    4317     if (cid == VMSVGA3D_SHARED_CTX_ID)
    4318         pContext = &pState->SharedCtx;
    4319     else
    4320 #endif
    4321     {
    4322         if (cid >= pState->cContexts)
    4323         {
    4324             /* Grow the array. */
    4325             uint32_t cNew = RT_ALIGN(cid + 15, 16);
    4326             void *pvNew = RTMemRealloc(pState->papContexts, sizeof(pState->papContexts[0]) * cNew);
    4327             AssertReturn(pvNew, VERR_NO_MEMORY);
    4328             pState->papContexts = (PVMSVGA3DCONTEXT *)pvNew;
    4329             while (pState->cContexts < cNew)
    4330             {
    4331                 pContext = (PVMSVGA3DCONTEXT)RTMemAllocZ(sizeof(*pContext));
    4332                 AssertReturn(pContext, VERR_NO_MEMORY);
    4333                 pContext->id = SVGA3D_INVALID_ID;
    4334                 pState->papContexts[pState->cContexts++] = pContext;
    4335             }
    4336         }
    4337         /* If one already exists with this id, then destroy it now. */
    4338         if (pState->papContexts[cid]->id != SVGA3D_INVALID_ID)
    4339             vmsvga3dContextDestroy(pThis, cid);
    4340 
    4341         pContext = pState->papContexts[cid];
    4342     }
    4343 
    4344     /*
    4345      * Find the shared context (necessary for sharing e.g. textures between contexts).
    4346      */
    4347 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    4348     PVMSVGA3DCONTEXT pSharedCtx = NULL;
    4349     if (!(fFlags & (VMSVGA3D_DEF_CTX_F_INIT | VMSVGA3D_DEF_CTX_F_SHARED_CTX)))
    4350     {
    4351         pSharedCtx = &pState->SharedCtx;
    4352         if (pSharedCtx->id != VMSVGA3D_SHARED_CTX_ID)
    4353         {
    4354             rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
    4355             AssertLogRelRCReturn(rc, rc);
    4356         }
    4357     }
    4358 #else
    4359     // TODO isn't this default on Linux since OpenGL 1.1?
    4360     /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
    4361     PVMSVGA3DCONTEXT pSharedCtx = NULL;
    4362     for (uint32_t i = 0; i < pState->cContexts; i++)
    4363         if (   pState->papContexts[i]->id != SVGA3D_INVALID_ID
    4364             && i != cid
    4365 # ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
    4366             && pState->papContexts[i]->fOtherProfile == RT_BOOL(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE)
    4367 # endif
    4368            )
    4369         {
    4370             Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
    4371             pSharedCtx = pState->papContexts[i];
    4372             break;
    4373         }
    4374 #endif
    4375 
    4376     /*
    4377      * Initialize the context.
    4378      */
    4379     memset(pContext, 0, sizeof(*pContext));
    4380     pContext->id                = cid;
    4381     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
    4382         pContext->aSidActiveTexture[i] = SVGA3D_INVALID_ID;
    4383 
    4384     pContext->sidRenderTarget   = SVGA3D_INVALID_ID;
    4385     pContext->state.shidVertex  = SVGA3D_INVALID_ID;
    4386     pContext->state.shidPixel   = SVGA3D_INVALID_ID;
    4387     pContext->idFramebuffer     = OPENGL_INVALID_ID;
    4388     pContext->idReadFramebuffer = OPENGL_INVALID_ID;
    4389     pContext->idDrawFramebuffer = OPENGL_INVALID_ID;
    4390 
    4391     rc = ShaderContextCreate(&pContext->pShaderContext);
    4392     AssertRCReturn(rc, rc);
    4393 
    4394     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
    4395         pContext->state.aRenderTargets[i] = SVGA3D_INVALID_ID;
    4396 
    4397     AssertReturn(pThis->svga.u64HostWindowId, VERR_INTERNAL_ERROR);
    4398 
    4399 #ifdef RT_OS_WINDOWS
    4400     /* Create a context window. */
    4401     CREATESTRUCT cs;
    4402     cs.lpCreateParams   = NULL;
    4403     cs.dwExStyle        = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT;
    4404 # ifdef DEBUG_GFX_WINDOW
    4405     cs.lpszName         = (char *)RTMemAllocZ(256);
    4406     RTStrPrintf((char *)cs.lpszName, 256, "Context %d OpenGL Window", cid);
    4407 # else
    4408     cs.lpszName         = NULL;
    4409 # endif
    4410     cs.lpszClass        = 0;
    4411 # ifdef DEBUG_GFX_WINDOW
    4412     cs.style            = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_CAPTION;
    4413 # else
    4414     cs.style            = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED | WS_CHILD | WS_VISIBLE;
    4415 # endif
    4416     cs.x                = 0;
    4417     cs.y                = 0;
    4418     cs.cx               = pThis->svga.uWidth;
    4419     cs.cy               = pThis->svga.uHeight;
    4420     cs.hwndParent       = (HWND)pThis->svga.u64HostWindowId;
    4421     cs.hMenu            = NULL;
    4422     cs.hInstance        = pState->hInstance;
    4423 
    4424     rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_CREATEWINDOW, (WPARAM)&pContext->hwnd, (LPARAM)&cs);
    4425     AssertRCReturn(rc, rc);
    4426 
    4427     pContext->hdc   = GetDC(pContext->hwnd);
    4428     AssertMsgReturn(pContext->hdc, ("GetDC %x failed with %d\n", pContext->hwnd, GetLastError()), VERR_INTERNAL_ERROR);
    4429 
    4430     PIXELFORMATDESCRIPTOR pfd = {
    4431         sizeof(PIXELFORMATDESCRIPTOR),  /*  size of this pfd */
    4432         1,                              /* version number */
    4433         PFD_DRAW_TO_WINDOW |            /* support window */
    4434         PFD_DOUBLEBUFFER   |            /* support double buffering */
    4435         PFD_SUPPORT_OPENGL,             /* support OpenGL */
    4436         PFD_TYPE_RGBA,                  /* RGBA type */
    4437         24,                             /* 24-bit color depth */
    4438         0, 0, 0, 0, 0, 0,               /* color bits ignored */
    4439         8,                              /* alpha buffer */
    4440         0,                              /* shift bit ignored */
    4441         0,                              /* no accumulation buffer */
    4442         0, 0, 0, 0,                     /* accum bits ignored */
    4443         16,                             /* set depth buffer  */
    4444         16,                             /* set stencil buffer */
    4445         0,                              /* no auxiliary buffer */
    4446         PFD_MAIN_PLANE,                 /* main layer */
    4447         0,                              /* reserved */
    4448         0, 0, 0                         /* layer masks ignored */
    4449     };
    4450     int     pixelFormat;
    4451     BOOL    ret;
    4452 
    4453     pixelFormat = ChoosePixelFormat(pContext->hdc, &pfd);
    4454     /* @todo is this really necessary?? */
    4455     pixelFormat = ChoosePixelFormat(pContext->hdc, &pfd);
    4456     AssertMsgReturn(pixelFormat != 0, ("ChoosePixelFormat failed with %d\n", GetLastError()), VERR_INTERNAL_ERROR);
    4457 
    4458     ret = SetPixelFormat(pContext->hdc, pixelFormat, &pfd);
    4459     AssertMsgReturn(ret == TRUE, ("SetPixelFormat failed with %d\n", GetLastError()), VERR_INTERNAL_ERROR);
    4460 
    4461     pContext->hglrc = wglCreateContext(pContext->hdc);
    4462     AssertMsgReturn(pContext->hglrc, ("wglCreateContext %x failed with %d\n", pContext->hdc, GetLastError()), VERR_INTERNAL_ERROR);
    4463 
    4464     if (pSharedCtx)
    4465     {
    4466         ret = wglShareLists(pSharedCtx->hglrc, pContext->hglrc);
    4467         AssertMsg(ret == TRUE, ("wglShareLists(%p, %p) failed with %d\n", pSharedCtx->hglrc, pContext->hglrc, GetLastError()));
    4468     }
    4469 
    4470 #elif defined(RT_OS_DARWIN)
    4471     pContext->fOtherProfile = RT_BOOL(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE);
    4472 
    4473     NativeNSOpenGLContextRef pShareContext = pSharedCtx ? pSharedCtx->cocoaContext : NULL;
    4474     NativeNSViewRef          pHostView    = (NativeNSViewRef)pThis->svga.u64HostWindowId;
    4475     vmsvga3dCocoaCreateViewAndContext(&pContext->cocoaView, &pContext->cocoaContext,
    4476 # 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. */
    4477                                       pSharedCtx ? NULL : pHostView, /** @todo screen objects and stuff. */
    4478 # else
    4479                                       pHostView,
    4480 # endif
    4481                                       pThis->svga.uWidth, pThis->svga.uHeight,
    4482                                       pShareContext, pContext->fOtherProfile);
    4483 
    4484 #else
    4485     Window hostWindow = (Window)pThis->svga.u64HostWindowId;
    4486 
    4487     if (pState->display == NULL)
    4488     {
    4489         /* get an X display and make sure we have glX 1.3 */
    4490         pState->display = XOpenDisplay(0);
    4491         Assert(pState->display);
    4492         int glxMajor, glxMinor;
    4493         Bool ret = glXQueryVersion(pState->display, &glxMajor, &glxMinor);
    4494         AssertMsgReturn(ret && glxMajor == 1 && glxMinor >= 3, ("glX >=1.3 not present"), VERR_INTERNAL_ERROR);
    4495         /* start our X event handling thread */
    4496         rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dXEventThread, pState, 0, RTTHREADTYPE_GUI, RTTHREADFLAGS_WAITABLE, "VMSVGA3DXEVENT");
    4497         if (RT_FAILURE(rc))
    4498         {
    4499             AssertMsgFailed(("%s: Async IO Thread creation for 3d window handling failed rc=%d\n", __FUNCTION__, rc));
    4500             return rc;
    4501         }
    4502     }
    4503     int attrib[] =
    4504     {
    4505         GLX_RGBA,
    4506         GLX_RED_SIZE, 1,
    4507         GLX_GREEN_SIZE, 1,
    4508         GLX_BLUE_SIZE, 1,
    4509         //GLX_ALPHA_SIZE, 1, this flips the bbos screen
    4510         GLX_DOUBLEBUFFER,
    4511         None
    4512     };
    4513     XVisualInfo *vi = glXChooseVisual(pState->display, DefaultScreen(pState->display), attrib);
    4514     XSetWindowAttributes swa;
    4515     swa.colormap = XCreateColormap(pState->display, XDefaultRootWindow(pState->display), vi->visual, AllocNone);
    4516     swa.border_pixel = 0;
    4517     swa.background_pixel = 0;
    4518     swa.event_mask = StructureNotifyMask | ExposureMask;
    4519     unsigned long flags = CWBorderPixel | CWBackPixel | CWColormap | CWEventMask;
    4520     pContext->window = XCreateWindow(pState->display, hostWindow,//XDefaultRootWindow(pState->display),//hostWindow,
    4521                                      0, 0, pThis->svga.uWidth, pThis->svga.uHeight,
    4522                                      0, vi->depth, InputOutput,
    4523                                      vi->visual, flags, &swa);
    4524     AssertMsgReturn(pContext->window, ("XCreateWindow failed"), VERR_INTERNAL_ERROR);
    4525     uint32_t cardinal_alpha = (uint32_t) (0.5 * (uint32_t)-1) ;
    4526 
    4527     /* the window is hidden by default and only mapped when CommandPresent is executed on it */
    4528 
    4529     GLXContext shareContext = pSharedCtx ? pSharedCtx->glxContext : NULL;
    4530     pContext->glxContext = glXCreateContext(pState->display, vi, shareContext, GL_TRUE);
    4531     AssertMsgReturn(pContext->glxContext, ("glXCreateContext failed"), VERR_INTERNAL_ERROR);
    4532 #endif
    4533 
    4534     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4535 
    4536     /* NULL during the first PowerOn call. */
    4537     if (pState->ext.glGenFramebuffers)
    4538     {
    4539         /* Create a framebuffer object for this context. */
    4540         pState->ext.glGenFramebuffers(1, &pContext->idFramebuffer);
    4541         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4542 
    4543         /* Bind the object to the framebuffer target. */
    4544         pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, pContext->idFramebuffer);
    4545         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4546 
    4547         /* Create read and draw framebuffer objects for this context. */
    4548         pState->ext.glGenFramebuffers(1, &pContext->idReadFramebuffer);
    4549         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4550 
    4551         pState->ext.glGenFramebuffers(1, &pContext->idDrawFramebuffer);
    4552         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4553 
    4554     }
    4555 #if 0
    4556     /* @todo move to shader lib!!! */
    4557     /* Clear the screen */
    4558     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4559 
    4560     glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    4561     glClearIndex(0);
    4562     glClearDepth(1);
    4563     glClearStencil(0xffff);
    4564     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
    4565     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
    4566     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
    4567     if (pState->ext.glProvokingVertex)
    4568         pState->ext.glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
    4569     /* @todo move to shader lib!!! */
    4570 #endif
    4571     return VINF_SUCCESS;
    4572 }
    4573 
    4574 
    4575 /**
    4576  * Create a new 3d context
    4577  *
    4578  * @returns VBox status code.
    4579  * @param   pThis           VGA device instance data.
    4580  * @param   cid             Context id
    4581  */
    4582 int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
    4583 {
    4584     return vmsvga3dContextDefineOgl(pThis, cid, 0/*fFlags*/);
    4585 }
    4586 
    4587 /**
    4588  * Destroys a 3d context.
    4589  *
    4590  * @returns VBox status code.
    4591  * @param   pThis           VGA device instance data.
    4592  * @param   pContext        The context to destroy.
    4593  * @param   cid             Context id
    4594  */
    4595 static int vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid)
    4596 {
    4597     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    4598     AssertReturn(pState, VERR_NO_MEMORY);
    4599     AssertReturn(pContext, VERR_INVALID_PARAMETER);
    4600     AssertReturn(pContext->id == cid, VERR_INVALID_PARAMETER);
    4601     Log(("vmsvga3dContextDestroyOgl id %x\n", cid));
    4602 
    4603     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4604 
    4605     /* Destroy all leftover pixel shaders. */
    4606     for (uint32_t i = 0; i < pContext->cPixelShaders; i++)
    4607     {
    4608         if (pContext->paPixelShader[i].id != SVGA3D_INVALID_ID)
    4609             vmsvga3dShaderDestroy(pThis, pContext->paPixelShader[i].cid, pContext->paPixelShader[i].id, pContext->paPixelShader[i].type);
    4610     }
    4611     if (pContext->paPixelShader)
    4612         RTMemFree(pContext->paPixelShader);
    4613 
    4614     /* Destroy all leftover vertex shaders. */
    4615     for (uint32_t i = 0; i < pContext->cVertexShaders; i++)
    4616     {
    4617         if (pContext->paVertexShader[i].id != SVGA3D_INVALID_ID)
    4618             vmsvga3dShaderDestroy(pThis, pContext->paVertexShader[i].cid, pContext->paVertexShader[i].id, pContext->paVertexShader[i].type);
    4619     }
    4620     if (pContext->paVertexShader)
    4621         RTMemFree(pContext->paVertexShader);
    4622 
    4623     if (pContext->state.paVertexShaderConst)
    4624         RTMemFree(pContext->state.paVertexShaderConst);
    4625     if (pContext->state.paPixelShaderConst)
    4626         RTMemFree(pContext->state.paPixelShaderConst);
    4627 
    4628     if (pContext->pShaderContext)
    4629     {
    4630         int rc = ShaderContextDestroy(pContext->pShaderContext);
    4631         AssertRC(rc);
    4632     }
    4633 
    4634 #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. */
    4635     /* Check for all surfaces that are associated with this context to remove all dependencies */
    4636     for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
    4637     {
    4638         PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    4639         if (    pSurface->idAssociatedContext == cid
    4640             &&  pSurface->id == sid)
    4641         {
    4642             int rc;
    4643 
    4644             Log(("vmsvga3dContextDestroy: remove all dependencies for surface %x\n", sid));
    4645 
    4646             uint32_t            surfaceFlags = pSurface->flags;
    4647             SVGA3dSurfaceFormat format = pSurface->format;
    4648             SVGA3dSurfaceFace   face[SVGA3D_MAX_SURFACE_FACES];
    4649             uint32_t            multisampleCount = pSurface->multiSampleCount;
    4650             SVGA3dTextureFilter autogenFilter = pSurface->autogenFilter;
    4651             SVGA3dSize         *pMipLevelSize;
    4652             uint32_t            cFaces = pSurface->cFaces;
    4653 
    4654             pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(pSurface->faces[0].numMipLevels * pSurface->cFaces * sizeof(SVGA3dSize));
    4655             AssertReturn(pMipLevelSize, VERR_NO_MEMORY);
    4656 
    4657             for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    4658             {
    4659                 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
    4660                 {
    4661                     uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;
    4662                     memcpy(&pMipLevelSize[idx], &pSurface->pMipmapLevels[idx].size, sizeof(SVGA3dSize));
    4663                 }
    4664             }
    4665             memcpy(face, pSurface->faces, sizeof(pSurface->faces));
    4666 
    4667             /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */
    4668             rc = vmsvga3dSurfaceDestroy(pThis, sid);
    4669             AssertRC(rc);
    4670 
    4671             rc = vmsvga3dSurfaceDefine(pThis, sid, surfaceFlags, format, face, multisampleCount, autogenFilter, face[0].numMipLevels * cFaces, pMipLevelSize);
    4672             AssertRC(rc);
    4673         }
    4674     }
    4675 #endif
    4676 
    4677     if (pContext->idFramebuffer != OPENGL_INVALID_ID)
    4678     {
    4679         /* Unbind the object from the framebuffer target. */
    4680         pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, 0 /* back buffer */);
    4681         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4682         pState->ext.glDeleteFramebuffers(1, &pContext->idFramebuffer);
    4683         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4684 
    4685         if (pContext->idReadFramebuffer != OPENGL_INVALID_ID)
    4686         {
    4687             pState->ext.glDeleteFramebuffers(1, &pContext->idReadFramebuffer);
    4688             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4689         }
    4690         if (pContext->idDrawFramebuffer != OPENGL_INVALID_ID)
    4691         {
    4692             pState->ext.glDeleteFramebuffers(1, &pContext->idDrawFramebuffer);
    4693             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4694         }
    4695     }
    4696 #ifdef RT_OS_WINDOWS
    4697     wglMakeCurrent(pContext->hdc, NULL);
    4698     wglDeleteContext(pContext->hglrc);
    4699     ReleaseDC(pContext->hwnd, pContext->hdc);
    4700 
    4701     /* Destroy the window we've created. */
    4702     int rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_DESTROYWINDOW, (WPARAM)pContext->hwnd, 0);
    4703     AssertRC(rc);
    4704 #elif defined(RT_OS_DARWIN)
    4705     vmsvga3dCocoaDestroyViewAndContext(pContext->cocoaView, pContext->cocoaContext);
    4706 #elif defined(RT_OS_LINUX)
    4707     glXMakeCurrent(pState->display, None, NULL);
    4708     glXDestroyContext(pState->display, pContext->glxContext);
    4709     XDestroyWindow(pState->display, pContext->window);
    4710 #endif
    4711 
    4712     memset(pContext, 0, sizeof(*pContext));
    4713     pContext->id = SVGA3D_INVALID_ID;
    4714 
    4715     VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState);
    4716     return VINF_SUCCESS;
    4717 }
    4718 
    4719 /**
    4720  * Destroy an existing 3d context
    4721  *
    4722  * @returns VBox status code.
    4723  * @param   pThis           VGA device instance data.
    4724  * @param   cid             Context id
    4725  */
    4726 int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
    4727 {
    4728     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    4729     AssertReturn(pState, VERR_WRONG_ORDER);
    4730 
    4731     /*
    4732      * Resolve the context and hand it to the common worker function.
    4733      */
    4734     if (   cid < pState->cContexts
    4735         && pState->papContexts[cid]->id == cid)
    4736         return vmsvga3dContextDestroyOgl(pThis, pState->papContexts[cid], cid);
    4737 
    4738     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
    4739     return VINF_SUCCESS;
    4740 }
    4741 
    4742 /**
    4743  * Worker for vmsvga3dChangeMode that resizes a context.
    4744  *
    4745  * @param   pThis               The VGA device instance data.
    4746  * @param   pState              The VMSVGA3d state.
    4747  * @param   pContext            The context.
    4748  */
    4749 static void vmsvga3dChangeModeOneContext(PVGASTATE pThis, PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
    4750 {
    4751 #ifdef RT_OS_WINDOWS
    4752     /* Resize the window. */
    4753     CREATESTRUCT          cs;
    4754     RT_ZERO(cs);
    4755     cs.cx = pThis->svga.uWidth;
    4756     cs.cy = pThis->svga.uHeight;
    4757     int rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_RESIZEWINDOW, (WPARAM)pContext->hwnd, (LPARAM)&cs);
    4758     AssertRC(rc);
    4759 
    4760 #elif defined(RT_OS_DARWIN)
    4761     vmsvga3dCocoaViewSetSize(pContext->cocoaView, pThis->svga.uWidth, pThis->svga.uHeight);
    4762 
    4763 #elif defined(RT_OS_LINUX)
    4764     XWindowChanges wc;
    4765     wc.width = pThis->svga.uWidth;
    4766     wc.height = pThis->svga.uHeight;
    4767     XConfigureWindow(pState->display, pContext->window, CWWidth | CWHeight, &wc);
    4768 #endif
    4769 }
    4770 
    4771 /* Handle resize */
    4772 int vmsvga3dChangeMode(PVGASTATE pThis)
    4773 {
    4774     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    4775     AssertReturn(pState, VERR_NO_MEMORY);
    4776 
    4777 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    4778     /* Resize the shared context too. */
    4779     if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    4780         vmsvga3dChangeModeOneContext(pThis, pState, &pState->SharedCtx);
    4781 #endif
    4782 
    4783     /* Resize all active contexts. */
    4784     for (uint32_t i = 0; i < pState->cContexts; i++)
    4785     {
    4786         PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
    4787         if (pContext->id != SVGA3D_INVALID_ID)
    4788             vmsvga3dChangeModeOneContext(pThis, pState, pContext);
    4789     }
    4790 
    4791     return VINF_SUCCESS;
    4792 }
    4793 
    4794 
    4795 int vmsvga3dSetTransform(PVGASTATE pThis, uint32_t cid, SVGA3dTransformType type, float matrix[16])
    4796 {
    4797     PVMSVGA3DCONTEXT      pContext;
    4798     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    4799     AssertReturn(pState, VERR_NO_MEMORY);
    4800     bool                  fModelViewChanged = false;
    4801 
    4802     Log(("vmsvga3dSetTransform cid=%x %s\n", cid, vmsvgaTransformToString(type)));
    4803 
    4804     if (    cid >= pState->cContexts
    4805         ||  pState->papContexts[cid]->id != cid)
    4806     {
    4807         Log(("vmsvga3dSetTransform invalid context id!\n"));
    4808         return VERR_INVALID_PARAMETER;
    4809     }
    4810     pContext = pState->papContexts[cid];
    4811     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4812 
    4813     /* Save this matrix for vm state save/restore. */
    4814     pContext->state.aTransformState[type].fValid = true;
    4815     memcpy(pContext->state.aTransformState[type].matrix, matrix, sizeof(pContext->state.aTransformState[type].matrix));
    4816     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_TRANSFORM;
    4817 
    4818     Log(("Matrix [%d %d %d %d]\n", (int)(matrix[0] * 10.0), (int)(matrix[1] * 10.0), (int)(matrix[2] * 10.0), (int)(matrix[3] * 10.0)));
    4819     Log(("       [%d %d %d %d]\n", (int)(matrix[4] * 10.0), (int)(matrix[5] * 10.0), (int)(matrix[6] * 10.0), (int)(matrix[7] * 10.0)));
    4820     Log(("       [%d %d %d %d]\n", (int)(matrix[8] * 10.0), (int)(matrix[9] * 10.0), (int)(matrix[10] * 10.0), (int)(matrix[11] * 10.0)));
    4821     Log(("       [%d %d %d %d]\n", (int)(matrix[12] * 10.0), (int)(matrix[13] * 10.0), (int)(matrix[14] * 10.0), (int)(matrix[15] * 10.0)));
    4822 
    4823     switch (type)
    4824     {
    4825     case SVGA3D_TRANSFORM_VIEW:
    4826         /* View * World = Model View */
    4827         glMatrixMode(GL_MODELVIEW);
    4828         glLoadMatrixf(matrix);
    4829         if (pContext->state.aTransformState[SVGA3D_TRANSFORM_WORLD].fValid)
    4830             glMultMatrixf(pContext->state.aTransformState[SVGA3D_TRANSFORM_WORLD].matrix);
    4831         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4832         fModelViewChanged = true;
    4833         break;
    4834 
    4835     case SVGA3D_TRANSFORM_PROJECTION:
    4836     {
    4837         int rc = ShaderTransformProjection(pContext->state.RectViewPort.w, pContext->state.RectViewPort.h, matrix);
    4838         AssertRCReturn(rc, rc);
    4839         break;
    4840     }
    4841 
    4842     case SVGA3D_TRANSFORM_TEXTURE0:
    4843         glMatrixMode(GL_TEXTURE);
    4844         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4845         glLoadMatrixf(matrix);
    4846         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4847         break;
    4848 
    4849     case SVGA3D_TRANSFORM_TEXTURE1:
    4850     case SVGA3D_TRANSFORM_TEXTURE2:
    4851     case SVGA3D_TRANSFORM_TEXTURE3:
    4852     case SVGA3D_TRANSFORM_TEXTURE4:
    4853     case SVGA3D_TRANSFORM_TEXTURE5:
    4854     case SVGA3D_TRANSFORM_TEXTURE6:
    4855     case SVGA3D_TRANSFORM_TEXTURE7:
    4856         Log(("vmsvga3dSetTransform: unsupported SVGA3D_TRANSFORM_TEXTUREx transform!!\n"));
    4857         return VERR_INVALID_PARAMETER;
    4858 
    4859     case SVGA3D_TRANSFORM_WORLD:
    4860         /* View * World = Model View */
    4861         glMatrixMode(GL_MODELVIEW);
    4862         if (pContext->state.aTransformState[SVGA3D_TRANSFORM_VIEW].fValid)
    4863             glLoadMatrixf(pContext->state.aTransformState[SVGA3D_TRANSFORM_VIEW].matrix);
    4864         else
    4865             glLoadIdentity();
    4866         glMultMatrixf(matrix);
    4867         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4868         fModelViewChanged = true;
    4869         break;
    4870 
    4871     case SVGA3D_TRANSFORM_WORLD1:
    4872     case SVGA3D_TRANSFORM_WORLD2:
    4873     case SVGA3D_TRANSFORM_WORLD3:
    4874         Log(("vmsvga3dSetTransform: unsupported SVGA3D_TRANSFORM_WORLDx transform!!\n"));
    4875         return VERR_INVALID_PARAMETER;
    4876 
    4877     default:
    4878         Log(("vmsvga3dSetTransform: unknown type!!\n"));
    4879         return VERR_INVALID_PARAMETER;
    4880     }
    4881 
    4882     /* Apparently we need to reset the light and clip data after modifying the modelview matrix. */
    4883     if (fModelViewChanged)
    4884     {
    4885         /* Reprogram the clip planes. */
    4886         for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aClipPlane); j++)
    4887         {
    4888             if (pContext->state.aClipPlane[j].fValid == true)
    4889                 vmsvga3dSetClipPlane(pThis, cid, j, pContext->state.aClipPlane[j].plane);
    4890         }
    4891 
    4892         /* Reprogram the light data. */
    4893         for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aLightData); j++)
    4894         {
    4895             if (pContext->state.aLightData[j].fValidData == true)
    4896                 vmsvga3dSetLightData(pThis, cid, j, &pContext->state.aLightData[j].data);
    4897         }
    4898     }
    4899 
    4900     return VINF_SUCCESS;
    4901 }
    4902 
    4903 int vmsvga3dSetZRange(PVGASTATE pThis, uint32_t cid, SVGA3dZRange zRange)
    4904 {
    4905     PVMSVGA3DCONTEXT      pContext;
    4906     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    4907     AssertReturn(pState, VERR_NO_MEMORY);
    4908 
    4909     Log(("vmsvga3dSetZRange cid=%x min=%d max=%d\n", cid, (uint32_t)(zRange.min * 100.0), (uint32_t)(zRange.max * 100.0)));
    4910 
    4911     if (    cid >= pState->cContexts
    4912         ||  pState->papContexts[cid]->id != cid)
    4913     {
    4914         Log(("vmsvga3dSetZRange invalid context id!\n"));
    4915         return VERR_INVALID_PARAMETER;
    4916     }
    4917     pContext = pState->papContexts[cid];
    4918     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4919 
    4920     pContext->state.zRange = zRange;
    4921     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_ZRANGE;
    4922 
    4923     if (zRange.min < -1.0)
    4924         zRange.min = -1.0;
    4925     if (zRange.max > 1.0)
    4926         zRange.max = 1.0;
    4927 
    4928     glDepthRange((GLdouble)zRange.min, (GLdouble)zRange.max);
    4929     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4930     return VINF_SUCCESS;
    4931 }
    4932 
    4933 /**
    4934  * Convert SVGA blend op value to its OpenGL equivalent
    4935  */
    4936 static GLenum vmsvga3dBlendOp2GL(uint32_t blendOp)
    4937 {
    4938     switch (blendOp)
    4939     {
    4940     case SVGA3D_BLENDOP_ZERO:
    4941         return GL_ZERO;
    4942     case SVGA3D_BLENDOP_ONE:
    4943         return GL_ONE;
    4944     case SVGA3D_BLENDOP_SRCCOLOR:
    4945         return GL_SRC_COLOR;
    4946     case SVGA3D_BLENDOP_INVSRCCOLOR:
    4947         return GL_ONE_MINUS_SRC_COLOR;
    4948     case SVGA3D_BLENDOP_SRCALPHA:
    4949         return GL_SRC_ALPHA;
    4950     case SVGA3D_BLENDOP_INVSRCALPHA:
    4951         return GL_ONE_MINUS_SRC_ALPHA;
    4952     case SVGA3D_BLENDOP_DESTALPHA:
    4953         return GL_DST_ALPHA;
    4954     case SVGA3D_BLENDOP_INVDESTALPHA:
    4955         return GL_ONE_MINUS_DST_ALPHA;
    4956     case SVGA3D_BLENDOP_DESTCOLOR:
    4957         return GL_DST_COLOR;
    4958     case SVGA3D_BLENDOP_INVDESTCOLOR:
    4959         return GL_ONE_MINUS_DST_COLOR;
    4960     case SVGA3D_BLENDOP_SRCALPHASAT:
    4961         return GL_SRC_ALPHA_SATURATE;
    4962     case SVGA3D_BLENDOP_BLENDFACTOR:
    4963         return GL_CONSTANT_ALPHA;       /* @todo correct?? */
    4964     case SVGA3D_BLENDOP_INVBLENDFACTOR:
    4965         return GL_ONE_MINUS_CONSTANT_ALPHA;       /* @todo correct?? */
    4966     default:
    4967         AssertFailed();
    4968         return GL_ONE;
    4969     }
    4970 }
    4971 
    4972 static GLenum vmsvga3dBlendEquation2GL(uint32_t blendEq)
    4973 {
    4974     switch (blendEq)
    4975     {
    4976     case SVGA3D_BLENDEQ_ADD:
    4977         return GL_FUNC_ADD;
    4978     case SVGA3D_BLENDEQ_SUBTRACT:
    4979         return GL_FUNC_SUBTRACT;
    4980     case SVGA3D_BLENDEQ_REVSUBTRACT:
    4981         return GL_FUNC_REVERSE_SUBTRACT;
    4982     case SVGA3D_BLENDEQ_MINIMUM:
    4983         return GL_MIN;
    4984     case SVGA3D_BLENDEQ_MAXIMUM:
    4985         return GL_MAX;
    4986     default:
    4987         AssertMsgFailed(("blendEq=%d (%#x)\n", blendEq, blendEq));
    4988         return GL_FUNC_ADD;
    4989     }
    4990 }
    4991 
    4992 static GLenum vmsvgaCmpFunc2GL(uint32_t cmpFunc)
    4993 {
    4994     switch (cmpFunc)
    4995     {
    4996     case SVGA3D_CMP_NEVER:
    4997         return GL_NEVER;
    4998     case SVGA3D_CMP_LESS:
    4999         return GL_LESS;
    5000     case SVGA3D_CMP_EQUAL:
    5001         return GL_EQUAL;
    5002     case SVGA3D_CMP_LESSEQUAL:
    5003         return GL_LEQUAL;
    5004     case SVGA3D_CMP_GREATER:
    5005         return GL_GREATER;
    5006     case SVGA3D_CMP_NOTEQUAL:
    5007         return GL_NOTEQUAL;
    5008     case SVGA3D_CMP_GREATEREQUAL:
    5009         return GL_GEQUAL;
    5010     case SVGA3D_CMP_ALWAYS:
    5011         return GL_ALWAYS;
    5012     default:
    5013         AssertFailed();
    5014         return GL_LESS;
    5015     }
    5016 }
    5017 
    5018 static GLenum vmsvgaStencipOp2GL(uint32_t stencilOp)
    5019 {
    5020     switch (stencilOp)
    5021     {
    5022     case SVGA3D_STENCILOP_KEEP:
    5023         return GL_KEEP;
    5024     case SVGA3D_STENCILOP_ZERO:
    5025         return GL_ZERO;
    5026     case SVGA3D_STENCILOP_REPLACE:
    5027         return GL_REPLACE;
    5028     case SVGA3D_STENCILOP_INCRSAT:
    5029         return GL_INCR_WRAP;
    5030     case SVGA3D_STENCILOP_DECRSAT:
    5031         return GL_DECR_WRAP;
    5032     case SVGA3D_STENCILOP_INVERT:
    5033         return GL_INVERT;
    5034     case SVGA3D_STENCILOP_INCR:
    5035         return GL_INCR;
    5036     case SVGA3D_STENCILOP_DECR:
    5037         return GL_DECR;
    5038     default:
    5039         AssertFailed();
    5040         return GL_KEEP;
    5041     }
    5042 }
    5043 
    5044 int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
    5045 {
    5046     uint32_t                    val;
    5047     PVMSVGA3DCONTEXT            pContext;
    5048     PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
    5049     AssertReturn(pState, VERR_NO_MEMORY);
    5050 
    5051     Log(("vmsvga3dSetRenderState cid=%x cRenderStates=%d\n", cid, cRenderStates));
    5052 
    5053     if (    cid >= pState->cContexts
    5054         ||  pState->papContexts[cid]->id != cid)
    5055     {
    5056         Log(("vmsvga3dSetRenderState invalid context id!\n"));
    5057         return VERR_INVALID_PARAMETER;
    5058     }
    5059     pContext = pState->papContexts[cid];
    5060     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    5061 
    5062     for (unsigned i = 0; i < cRenderStates; i++)
    5063     {
    5064         GLenum enableCap = ~0U;
    5065         Log(("vmsvga3dSetRenderState: cid=%x state=%s (%d) val=%x\n", cid, vmsvga3dGetRenderStateName(pRenderState[i].state), pRenderState[i].state, pRenderState[i].uintValue));
    5066         /* Save the render state for vm state saving. */
    5067         if (pRenderState[i].state < SVGA3D_RS_MAX)
    5068             pContext->state.aRenderState[pRenderState[i].state] = pRenderState[i];
    5069 
    5070         switch (pRenderState[i].state)
    5071         {
    5072         case SVGA3D_RS_ZENABLE:                /* SVGA3dBool */
    5073             enableCap = GL_DEPTH_TEST;
    5074             val = pRenderState[i].uintValue;
    5075             break;
    5076 
    5077         case SVGA3D_RS_ZWRITEENABLE:           /* SVGA3dBool */
    5078             glDepthMask(!!pRenderState[i].uintValue);
    5079             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5080             break;
    5081 
    5082         case SVGA3D_RS_ALPHATESTENABLE:        /* SVGA3dBool */
    5083             enableCap = GL_ALPHA_TEST;
    5084             val = pRenderState[i].uintValue;
    5085             break;
    5086 
    5087         case SVGA3D_RS_DITHERENABLE:           /* SVGA3dBool */
    5088             enableCap = GL_DITHER;
    5089             val = pRenderState[i].uintValue;
    5090             break;
    5091 
    5092         case SVGA3D_RS_FOGENABLE:              /* SVGA3dBool */
    5093             enableCap = GL_FOG;
    5094             val = pRenderState[i].uintValue;
    5095             break;
    5096 
    5097         case SVGA3D_RS_SPECULARENABLE:         /* SVGA3dBool */
    5098             Log(("vmsvga3dSetRenderState: WARNING: not applicable.\n"));
    5099             break;
    5100 
    5101         case SVGA3D_RS_LIGHTINGENABLE:         /* SVGA3dBool */
    5102             enableCap = GL_LIGHTING;
    5103             val = pRenderState[i].uintValue;
    5104             break;
    5105 
    5106         case SVGA3D_RS_NORMALIZENORMALS:       /* SVGA3dBool */
    5107             /* not applicable */
    5108             Log(("vmsvga3dSetRenderState: WARNING: not applicable.\n"));
    5109             break;
    5110 
    5111         case SVGA3D_RS_POINTSPRITEENABLE:      /* SVGA3dBool */
    5112             enableCap = GL_POINT_SPRITE_ARB;
    5113             val = pRenderState[i].uintValue;
    5114             break;
    5115 
    5116         case SVGA3D_RS_POINTSIZE:              /* float */
    5117             /* @todo we need to apply scaling for point sizes below the min or above the max; see Wine) */
    5118             if (pRenderState[i].floatValue < pState->caps.flPointSize[0])
    5119                 pRenderState[i].floatValue = pState->caps.flPointSize[0];
    5120             if (pRenderState[i].floatValue > pState->caps.flPointSize[1])
    5121                 pRenderState[i].floatValue = pState->caps.flPointSize[1];
    5122 
    5123             glPointSize(pRenderState[i].floatValue);
    5124             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5125             Log(("SVGA3D_RS_POINTSIZE: %d\n", (uint32_t) (pRenderState[i].floatValue * 100.0)));
    5126             break;
    5127 
    5128         case SVGA3D_RS_POINTSIZEMIN:           /* float */
    5129             pState->ext.glPointParameterf(GL_POINT_SIZE_MIN, pRenderState[i].floatValue);
    5130             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5131             Log(("SVGA3D_RS_POINTSIZEMIN: %d\n", (uint32_t) (pRenderState[i].floatValue * 100.0)));
    5132             break;
    5133 
    5134         case SVGA3D_RS_POINTSIZEMAX:           /* float */
    5135             pState->ext.glPointParameterf(GL_POINT_SIZE_MAX, pRenderState[i].floatValue);
    5136             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5137             Log(("SVGA3D_RS_POINTSIZEMAX: %d\n", (uint32_t) (pRenderState[i].floatValue * 100.0)));
    5138             break;
    5139 
    5140         case SVGA3D_RS_POINTSCALEENABLE:       /* SVGA3dBool */
    5141         case SVGA3D_RS_POINTSCALE_A:           /* float */
    5142         case SVGA3D_RS_POINTSCALE_B:           /* float */
    5143         case SVGA3D_RS_POINTSCALE_C:           /* float */
    5144             Log(("vmsvga3dSetRenderState: WARNING: not applicable.\n"));
    5145             break;
    5146 
    5147         case SVGA3D_RS_AMBIENT:                /* SVGA3dColor */
    5148         {
    5149             GLfloat color[4]; /* red, green, blue, alpha */
    5150 
    5151             vmsvgaColor2GLFloatArray(pRenderState[i].uintValue, &color[0], &color[1], &color[2], &color[3]);
    5152 
    5153             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color);
    5154             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5155             break;
    5156         }
    5157 
    5158         case SVGA3D_RS_CLIPPLANEENABLE:        /* SVGA3dClipPlanes */
    5159         {
    5160             AssertCompile(SVGA3D_CLIPPLANE_MAX == (1 << 5));
    5161             for (uint32_t j = 0; j <= 5; j++)
    5162             {
    5163                 if (pRenderState[i].uintValue & RT_BIT(j))
    5164                     glEnable(GL_CLIP_PLANE0 + j);
    5165                 else
    5166                     glDisable(GL_CLIP_PLANE0 + j);
    5167                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5168             }
    5169             break;
    5170         }
    5171 
    5172         case SVGA3D_RS_FOGCOLOR:               /* SVGA3dColor */
    5173         {
    5174             GLfloat color[4]; /* red, green, blue, alpha */
    5175 
    5176             vmsvgaColor2GLFloatArray(pRenderState[i].uintValue, &color[0], &color[1], &color[2], &color[3]);
    5177 
    5178             glFogfv(GL_FOG_COLOR, color);
    5179             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5180             break;
    5181         }
    5182 
    5183         case SVGA3D_RS_FOGSTART:               /* float */
    5184             glFogf(GL_FOG_START, pRenderState[i].floatValue);
    5185             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5186             break;
    5187 
    5188         case SVGA3D_RS_FOGEND:                 /* float */
    5189             glFogf(GL_FOG_END, pRenderState[i].floatValue);
    5190             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5191             break;
    5192 
    5193         case SVGA3D_RS_FOGDENSITY:             /* float */
    5194             glFogf(GL_FOG_DENSITY, pRenderState[i].floatValue);
    5195             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5196             break;
    5197 
    5198         case SVGA3D_RS_RANGEFOGENABLE:         /* SVGA3dBool */
    5199             glFogi(GL_FOG_COORD_SRC, (pRenderState[i].uintValue) ? GL_FOG_COORD : GL_FRAGMENT_DEPTH);
    5200             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5201             break;
    5202 
    5203         case SVGA3D_RS_FOGMODE:                /* SVGA3dFogMode */
    5204         {
    5205             SVGA3dFogMode mode;
    5206             mode.uintValue = pRenderState[i].uintValue;
    5207 
    5208             enableCap = GL_FOG_MODE;
    5209             switch (mode.s.function)
    5210             {
    5211             case SVGA3D_FOGFUNC_EXP:
    5212                 val = GL_EXP;
    5213                 break;
    5214             case SVGA3D_FOGFUNC_EXP2:
    5215                 val = GL_EXP2;
    5216                 break;
    5217             case SVGA3D_FOGFUNC_LINEAR:
    5218                 val = GL_LINEAR;
    5219                 break;
    5220             default:
    5221                 AssertMsgFailedReturn(("Unexpected fog function %d\n", mode.s.function), VERR_INTERNAL_ERROR);
    5222                 break;
    5223             }
    5224 
    5225             /* @todo how to switch between vertex and pixel fog modes??? */
    5226             Assert(mode.s.type == SVGA3D_FOGTYPE_PIXEL);
    5227 #if 0
    5228             /* The fog type determines the render state. */
    5229             switch (mode.s.type)
    5230             {
    5231             case SVGA3D_FOGTYPE_VERTEX:
    5232                 renderState = D3DRS_FOGVERTEXMODE;
    5233                 break;
    5234             case SVGA3D_FOGTYPE_PIXEL:
    5235                 renderState = D3DRS_FOGTABLEMODE;
    5236                 break;
    5237             default:
    5238                 AssertMsgFailedReturn(("Unexpected fog type %d\n", mode.s.type), VERR_INTERNAL_ERROR);
    5239                 break;
    5240             }
    5241 #endif
    5242 
    5243             /* Set the fog base to depth or range. */
    5244             switch (mode.s.base)
    5245             {
    5246             case SVGA3D_FOGBASE_DEPTHBASED:
    5247                 glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH);
    5248                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5249                 break;
    5250             case SVGA3D_FOGBASE_RANGEBASED:
    5251                 glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD);
    5252                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5253                 break;
    5254             default:
    5255                 /* ignore */
    5256                 AssertMsgFailed(("Unexpected fog base %d\n", mode.s.base));
    5257                 break;
    5258             }
    5259             break;
    5260         }
    5261 
    5262         case SVGA3D_RS_FILLMODE:               /* SVGA3dFillMode */
    5263         {
    5264             SVGA3dFillMode mode;
    5265 
    5266             mode.uintValue = pRenderState[i].uintValue;
    5267 
    5268             switch (mode.s.mode)
    5269             {
    5270             case SVGA3D_FILLMODE_POINT:
    5271                 val = GL_POINT;
    5272                 break;
    5273             case SVGA3D_FILLMODE_LINE:
    5274                 val = GL_LINE;
    5275                 break;
    5276             case SVGA3D_FILLMODE_FILL:
    5277                 val = GL_FILL;
    5278                 break;
    5279             default:
    5280                 AssertMsgFailedReturn(("Unexpected fill mode %d\n", mode.s.mode), VERR_INTERNAL_ERROR);
    5281                 break;
    5282             }
    5283             /* @note only front and back faces */
    5284             Assert(mode.s.face == SVGA3D_FACE_FRONT_BACK);
    5285             glPolygonMode(GL_FRONT_AND_BACK, val);
    5286             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5287             break;
    5288         }
    5289 
    5290         case SVGA3D_RS_SHADEMODE:              /* SVGA3dShadeMode */
    5291             switch (pRenderState[i].uintValue)
    5292             {
    5293             case SVGA3D_SHADEMODE_FLAT:
    5294                 val = GL_FLAT;
    5295                 break;
    5296 
    5297             case SVGA3D_SHADEMODE_SMOOTH:
    5298                 val = GL_SMOOTH;
    5299                 break;
    5300 
    5301             default:
    5302                 AssertMsgFailedReturn(("Unexpected shade mode %d\n", pRenderState[i].uintValue), VERR_INTERNAL_ERROR);
    5303                 break;
    5304             }
    5305 
    5306             glShadeModel(val);
    5307             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5308             break;
    5309 
    5310         case SVGA3D_RS_LINEPATTERN:            /* SVGA3dLinePattern */
    5311             /* No longer supported by d3d; mesagl comments suggest not all backends support it */
    5312             /* @todo */
    5313             Log(("WARNING: SVGA3D_RS_LINEPATTERN %x not supported!!\n", pRenderState[i].uintValue));
    5314             /*
    5315             renderState = D3DRS_LINEPATTERN;
    5316             val = pRenderState[i].uintValue;
    5317             */
    5318             break;
    5319 
    5320         case SVGA3D_RS_LINEAA:                 /* SVGA3dBool */
    5321             enableCap = GL_LINE_SMOOTH;
    5322             val = pRenderState[i].uintValue;
    5323             break;
    5324 
    5325         case SVGA3D_RS_LINEWIDTH:              /* float */
    5326             glLineWidth(pRenderState[i].floatValue);
    5327             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5328             break;
    5329 
    5330         case SVGA3D_RS_SEPARATEALPHABLENDENABLE: /* SVGA3dBool */
    5331         {
    5332             /* Refresh the blending state based on the new enable setting. */
    5333             SVGA3dRenderState renderstate[2];
    5334 
    5335             renderstate[0].state     = SVGA3D_RS_SRCBLEND;
    5336             renderstate[0].uintValue = pContext->state.aRenderState[SVGA3D_RS_SRCBLEND].uintValue;
    5337             renderstate[1].state     = SVGA3D_RS_BLENDEQUATION;
    5338             renderstate[1].uintValue = pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATION].uintValue;
    5339 
    5340             int rc = vmsvga3dSetRenderState(pThis, cid, 2, renderstate);
    5341             AssertRCReturn(rc, rc);
    5342 
    5343             if (pContext->state.aRenderState[SVGA3D_RS_BLENDENABLE].uintValue != 0)
    5344                 continue;   /* ignore if blend is already enabled */
    5345             /* no break */
    5346         }
    5347 
    5348         case SVGA3D_RS_BLENDENABLE:            /* SVGA3dBool */
    5349             enableCap = GL_BLEND;
    5350             val = pRenderState[i].uintValue;
    5351             break;
    5352 
    5353         case SVGA3D_RS_SRCBLENDALPHA:          /* SVGA3dBlendOp */
    5354         case SVGA3D_RS_DSTBLENDALPHA:          /* SVGA3dBlendOp */
    5355         case SVGA3D_RS_SRCBLEND:               /* SVGA3dBlendOp */
    5356         case SVGA3D_RS_DSTBLEND:               /* SVGA3dBlendOp */
    5357         {
    5358             GLint srcRGB, srcAlpha, dstRGB, dstAlpha;
    5359             GLint blendop = vmsvga3dBlendOp2GL(pRenderState[i].uintValue);
    5360 
    5361             glGetIntegerv(GL_BLEND_SRC_RGB, &srcRGB);
    5362             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5363             glGetIntegerv(GL_BLEND_DST_RGB, &dstRGB);
    5364             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5365             glGetIntegerv(GL_BLEND_DST_ALPHA, &dstAlpha);
    5366             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5367             glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcAlpha);
    5368             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5369 
    5370             switch (pRenderState[i].state)
    5371             {
    5372             case SVGA3D_RS_SRCBLEND:
    5373                 srcRGB = blendop;
    5374                 break;
    5375             case SVGA3D_RS_DSTBLEND:
    5376                 dstRGB = blendop;
    5377                 break;
    5378             case SVGA3D_RS_SRCBLENDALPHA:
    5379                 srcAlpha = blendop;
    5380                 break;
    5381             case SVGA3D_RS_DSTBLENDALPHA:
    5382                 dstAlpha = blendop;
    5383                 break;
    5384             default:
    5385                 /* not possible; shut up gcc */
    5386                 AssertFailed();
    5387                 break;
    5388             }
    5389 
    5390             if (pContext->state.aRenderState[SVGA3D_RS_SEPARATEALPHABLENDENABLE].uintValue != 0)
    5391                 pState->ext.glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
    5392             else
    5393                 glBlendFunc(srcRGB, dstRGB);
    5394             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5395             break;
    5396         }
    5397 
    5398         case SVGA3D_RS_BLENDEQUATIONALPHA:     /* SVGA3dBlendEquation */
    5399         case SVGA3D_RS_BLENDEQUATION:          /* SVGA3dBlendEquation */
    5400             if (pContext->state.aRenderState[SVGA3D_RS_SEPARATEALPHABLENDENABLE].uintValue != 0)
    5401                 pState->ext.glBlendEquationSeparate(vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATION].uintValue),
    5402                                                     vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATIONALPHA].uintValue));
    5403             else
    5404             {
    5405 #if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x102
    5406                 glBlendEquation(vmsvga3dBlendEquation2GL(pRenderState[i].uintValue));
    5407 #else
    5408                 pState->ext.glBlendEquation(vmsvga3dBlendEquation2GL(pRenderState[i].uintValue));
    5409 #endif
    5410             }
    5411             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5412             break;
    5413 
    5414         case SVGA3D_RS_BLENDCOLOR:             /* SVGA3dColor */
    5415         {
    5416             GLfloat red, green, blue, alpha;
    5417 
    5418             vmsvgaColor2GLFloatArray(pRenderState[i].uintValue, &red, &green, &blue, &alpha);
    5419 
    5420 #if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x102
    5421             glBlendColor(red, green, blue, alpha);
    5422 #else
    5423             pState->ext.glBlendColor(red, green, blue, alpha);
    5424 #endif
    5425             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5426             break;
    5427         }
    5428 
    5429         case SVGA3D_RS_CULLMODE:               /* SVGA3dFace */
    5430         {
    5431             GLenum mode = GL_BACK;  /* default for OpenGL */
    5432 
    5433             switch (pRenderState[i].uintValue)
    5434             {
    5435             case SVGA3D_FACE_NONE:
    5436                 break;
    5437             case SVGA3D_FACE_FRONT:
    5438                 mode = GL_FRONT;
    5439                 break;
    5440             case SVGA3D_FACE_BACK:
    5441                 mode = GL_BACK;
    5442                 break;
    5443             case SVGA3D_FACE_FRONT_BACK:
    5444                 mode = GL_FRONT_AND_BACK;
    5445                 break;
    5446             default:
    5447                 AssertMsgFailedReturn(("Unexpected cull mode %d\n", pRenderState[i].uintValue), VERR_INTERNAL_ERROR);
    5448                 break;
    5449             }
    5450             enableCap = GL_CULL_FACE;
    5451             if (pRenderState[i].uintValue != SVGA3D_FACE_NONE)
    5452             {
    5453                 glCullFace(mode);
    5454                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5455                 val = 1;
    5456             }
    5457             else
    5458                 val = 0;
    5459             break;
    5460         }
    5461 
    5462         case SVGA3D_RS_ZFUNC:                  /* SVGA3dCmpFunc */
    5463             glDepthFunc(vmsvgaCmpFunc2GL(pRenderState[i].uintValue));
    5464             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5465             break;
    5466 
    5467         case SVGA3D_RS_ALPHAFUNC:              /* SVGA3dCmpFunc */
    5468         {
    5469             GLclampf ref;
    5470 
    5471             glGetFloatv(GL_ALPHA_TEST_REF, &ref);
    5472             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5473             glAlphaFunc(vmsvgaCmpFunc2GL(pRenderState[i].uintValue), ref);
    5474             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5475             break;
    5476         }
    5477 
    5478         case SVGA3D_RS_ALPHAREF:               /* float (0.0 .. 1.0) */
    5479         {
    5480             GLint func;
    5481 
    5482             glGetIntegerv(GL_ALPHA_TEST_FUNC, &func);
    5483             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5484             glAlphaFunc(func, pRenderState[i].floatValue);
    5485             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5486             break;
    5487         }
    5488 
    5489         case SVGA3D_RS_STENCILENABLE:          /* SVGA3dBool */
    5490             enableCap = GL_STENCIL_TEST;
    5491             val = pRenderState[i].uintValue;
    5492             break;
    5493 
    5494         case SVGA3D_RS_STENCILFUNC:            /* SVGA3dCmpFunc */
    5495         case SVGA3D_RS_STENCILREF:             /* uint32_t */
    5496         case SVGA3D_RS_STENCILMASK:            /* uint32_t */
    5497         {
    5498             GLint func, ref;
    5499             GLuint mask;
    5500 
    5501             glGetIntegerv(GL_STENCIL_FUNC, &func);
    5502             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5503             glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)&mask);
    5504             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5505             glGetIntegerv(GL_STENCIL_REF, &ref);
    5506             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5507 
    5508             switch (pRenderState[i].state)
    5509             {
    5510             case SVGA3D_RS_STENCILFUNC:            /* SVGA3dCmpFunc */
    5511                 func = vmsvgaCmpFunc2GL(pRenderState[i].uintValue);
    5512                 break;
    5513 
    5514             case SVGA3D_RS_STENCILREF:             /* uint32_t */
    5515                 ref = pRenderState[i].uintValue;
    5516                 break;
    5517 
    5518             case SVGA3D_RS_STENCILMASK:            /* uint32_t */
    5519                 mask = pRenderState[i].uintValue;
    5520                 break;
    5521 
    5522             default:
    5523                 /* not possible; shut up gcc */
    5524                 AssertFailed();
    5525                 break;
    5526             }
    5527 
    5528             glStencilFunc(func, ref, mask);
    5529             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5530             break;
    5531         }
    5532 
    5533         case SVGA3D_RS_STENCILWRITEMASK:       /* uint32_t */
    5534             glStencilMask(pRenderState[i].uintValue);
    5535             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5536             break;
    5537 
    5538         case SVGA3D_RS_STENCILFAIL:            /* SVGA3dStencilOp */
    5539         case SVGA3D_RS_STENCILZFAIL:           /* SVGA3dStencilOp */
    5540         case SVGA3D_RS_STENCILPASS:            /* SVGA3dStencilOp */
    5541         {
    5542             GLint sfail, dpfail, dppass;
    5543             GLenum stencilop = vmsvgaStencipOp2GL(pRenderState[i].uintValue);
    5544 
    5545             glGetIntegerv(GL_STENCIL_FAIL, &sfail);
    5546             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5547             glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &dpfail);
    5548             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5549             glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &dppass);
    5550             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5551 
    5552             switch (pRenderState[i].state)
    5553             {
    5554             case SVGA3D_RS_STENCILFAIL:            /* SVGA3dStencilOp */
    5555                 sfail = stencilop;
    5556                 break;
    5557             case SVGA3D_RS_STENCILZFAIL:           /* SVGA3dStencilOp */
    5558                 dpfail = stencilop;
    5559                 break;
    5560             case SVGA3D_RS_STENCILPASS:            /* SVGA3dStencilOp */
    5561                 dppass = stencilop;
    5562                 break;
    5563             default:
    5564                 /* not possible; shut up gcc */
    5565                 AssertFailed();
    5566                 break;
    5567             }
    5568             glStencilOp(sfail, dpfail, dppass);
    5569             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5570             break;
    5571         }
    5572 
    5573         case SVGA3D_RS_STENCILENABLE2SIDED:    /* SVGA3dBool */
    5574             /* @note GL_EXT_stencil_two_side required! */
    5575             if (pState->ext.fEXT_stencil_two_side)
    5576             {
    5577                 enableCap = GL_STENCIL_TEST_TWO_SIDE_EXT;
    5578                 val = pRenderState[i].uintValue;
    5579             }
    5580             else
    5581                 Log(("vmsvga3dSetRenderState: WARNING unsupported SVGA3D_RS_STENCILENABLE2SIDED\n"));
    5582             break;
    5583 
    5584         case SVGA3D_RS_CCWSTENCILFUNC:         /* SVGA3dCmpFunc */
    5585         {
    5586             /* @todo SVGA3D_RS_STENCILFAIL/ZFAIL/PASS for front & back faces
    5587              *       SVGA3D_RS_CCWSTENCILFAIL/ZFAIL/PASS for back faces ??
    5588              */
    5589             GLint ref;
    5590             GLuint mask;
    5591 
    5592             glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, (GLint *)&mask);
    5593             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5594             glGetIntegerv(GL_STENCIL_BACK_REF, &ref);
    5595             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5596 
    5597             pState->ext.glStencilFuncSeparate(GL_BACK, vmsvgaCmpFunc2GL(pRenderState[i].uintValue), ref, mask);
    5598             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5599             break;
    5600         }
    5601 
    5602         case SVGA3D_RS_CCWSTENCILFAIL:         /* SVGA3dStencilOp */
    5603         case SVGA3D_RS_CCWSTENCILZFAIL:        /* SVGA3dStencilOp */
    5604         case SVGA3D_RS_CCWSTENCILPASS:         /* SVGA3dStencilOp */
    5605         {
    5606             /* @todo SVGA3D_RS_STENCILFAIL/ZFAIL/PASS for front & back faces
    5607              *       SVGA3D_RS_CCWSTENCILFAIL/ZFAIL/PASS for back faces ??
    5608              */
    5609             GLint sfail, dpfail, dppass;
    5610             GLenum stencilop = vmsvgaStencipOp2GL(pRenderState[i].uintValue);
    5611 
    5612             glGetIntegerv(GL_STENCIL_BACK_FAIL, &sfail);
    5613             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5614             glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &dpfail);
    5615             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5616             glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &dppass);
    5617             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5618 
    5619             switch (pRenderState[i].state)
    5620             {
    5621             case SVGA3D_RS_CCWSTENCILFAIL:         /* SVGA3dStencilOp */
    5622                 sfail = stencilop;
    5623                 break;
    5624             case SVGA3D_RS_CCWSTENCILZFAIL:        /* SVGA3dStencilOp */
    5625                 dpfail = stencilop;
    5626                 break;
    5627             case SVGA3D_RS_CCWSTENCILPASS:         /* SVGA3dStencilOp */
    5628                 dppass = stencilop;
    5629                 break;
    5630             default:
    5631                 /* not possible; shut up gcc */
    5632                 AssertFailed();
    5633                 break;
    5634             }
    5635             pState->ext.glStencilOpSeparate(GL_BACK, sfail, dpfail, dppass);
    5636             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5637             break;
    5638         }
    5639 
    5640         case SVGA3D_RS_ZBIAS:                  /* float */
    5641             /* @todo unknown meaning; depth bias is not identical
    5642             renderState = D3DRS_DEPTHBIAS;
    5643             val = pRenderState[i].uintValue;
    5644             */
    5645             Log(("vmsvga3dSetRenderState: WARNING unsupported SVGA3D_RS_ZBIAS\n"));
    5646             break;
    5647 
    5648         case SVGA3D_RS_DEPTHBIAS:              /* float */
    5649         {
    5650             GLfloat factor;
    5651 
    5652             /* @todo not sure if the d3d & ogl definitions are identical. */
    5653 
    5654             /* Do not change the factor part. */
    5655             glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
    5656             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5657 
    5658             glPolygonOffset(factor, pRenderState[i].floatValue);
    5659             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5660             break;
    5661         }
    5662 
    5663         case SVGA3D_RS_SLOPESCALEDEPTHBIAS:    /* float */
    5664         {
    5665             GLfloat units;
    5666 
    5667             /* @todo not sure if the d3d & ogl definitions are identical. */
    5668 
    5669             /* Do not change the factor part. */
    5670             glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
    5671             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5672 
    5673             glPolygonOffset(pRenderState[i].floatValue, units);
    5674             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5675             break;
    5676         }
    5677 
    5678         case SVGA3D_RS_COLORWRITEENABLE:       /* SVGA3dColorMask */
    5679         {
    5680             GLboolean red, green, blue, alpha;
    5681             SVGA3dColorMask mask;
    5682 
    5683             mask.uintValue = pRenderState[i].uintValue;
    5684 
    5685             red     = mask.s.red;
    5686             green   = mask.s.green;
    5687             blue    = mask.s.blue;
    5688             alpha   = mask.s.alpha;
    5689 
    5690             glColorMask(red, green, blue, alpha);
    5691             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5692             break;
    5693         }
    5694 
    5695         case SVGA3D_RS_COLORWRITEENABLE1:      /* SVGA3dColorMask to D3DCOLORWRITEENABLE_* */
    5696         case SVGA3D_RS_COLORWRITEENABLE2:      /* SVGA3dColorMask to D3DCOLORWRITEENABLE_* */
    5697         case SVGA3D_RS_COLORWRITEENABLE3:      /* SVGA3dColorMask to D3DCOLORWRITEENABLE_* */
    5698             Log(("vmsvga3dSetRenderState: WARNING SVGA3D_RS_COLORWRITEENABLEx not supported!!\n"));
    5699             break;
    5700 
    5701         case SVGA3D_RS_SCISSORTESTENABLE:      /* SVGA3dBool */
    5702             enableCap = GL_SCISSOR_TEST;
    5703             val = pRenderState[i].uintValue;
    5704             break;
    5705 
    5706 #if 0
    5707         case SVGA3D_RS_DIFFUSEMATERIALSOURCE:  /* SVGA3dVertexMaterial */
    5708             AssertCompile(D3DMCS_COLOR2 == SVGA3D_VERTEXMATERIAL_SPECULAR);
    5709             renderState = D3DRS_DIFFUSEMATERIALSOURCE;
    5710             val = pRenderState[i].uintValue;
    5711             break;
    5712 
    5713         case SVGA3D_RS_SPECULARMATERIALSOURCE: /* SVGA3dVertexMaterial */
    5714             renderState = D3DRS_SPECULARMATERIALSOURCE;
    5715             val = pRenderState[i].uintValue;
    5716             break;
    5717 
    5718         case SVGA3D_RS_AMBIENTMATERIALSOURCE:  /* SVGA3dVertexMaterial */
    5719             renderState = D3DRS_AMBIENTMATERIALSOURCE;
    5720             val = pRenderState[i].uintValue;
    5721             break;
    5722 
    5723         case SVGA3D_RS_EMISSIVEMATERIALSOURCE: /* SVGA3dVertexMaterial */
    5724             renderState = D3DRS_EMISSIVEMATERIALSOURCE;
    5725             val = pRenderState[i].uintValue;
    5726             break;
    5727 #endif
    5728 
    5729         case SVGA3D_RS_WRAP3:                  /* SVGA3dWrapFlags */
    5730         case SVGA3D_RS_WRAP4:                  /* SVGA3dWrapFlags */
    5731         case SVGA3D_RS_WRAP5:                  /* SVGA3dWrapFlags */
    5732         case SVGA3D_RS_WRAP6:                  /* SVGA3dWrapFlags */
    5733         case SVGA3D_RS_WRAP7:                  /* SVGA3dWrapFlags */
    5734         case SVGA3D_RS_WRAP8:                  /* SVGA3dWrapFlags */
    5735         case SVGA3D_RS_WRAP9:                  /* SVGA3dWrapFlags */
    5736         case SVGA3D_RS_WRAP10:                 /* SVGA3dWrapFlags */
    5737         case SVGA3D_RS_WRAP11:                 /* SVGA3dWrapFlags */
    5738         case SVGA3D_RS_WRAP12:                 /* SVGA3dWrapFlags */
    5739         case SVGA3D_RS_WRAP13:                 /* SVGA3dWrapFlags */
    5740         case SVGA3D_RS_WRAP14:                 /* SVGA3dWrapFlags */
    5741         case SVGA3D_RS_WRAP15:                 /* SVGA3dWrapFlags */
    5742             Log(("vmsvga3dSetRenderState: WARNING unsupported SVGA3D_WRAPx (x >= 3)\n"));
    5743             break;
    5744 
    5745         case SVGA3D_RS_LASTPIXEL:              /* SVGA3dBool */
    5746         case SVGA3D_RS_TWEENFACTOR:            /* float */
    5747         case SVGA3D_RS_INDEXEDVERTEXBLENDENABLE: /* SVGA3dBool */
    5748         case SVGA3D_RS_VERTEXBLEND:            /* SVGA3dVertexBlendFlags */
    5749             Log(("vmsvga3dSetRenderState: WARNING not applicable!!\n"));
    5750             break;
    5751 
    5752         case SVGA3D_RS_MULTISAMPLEANTIALIAS:   /* SVGA3dBool */
    5753             enableCap = GL_MULTISAMPLE;
    5754             val = pRenderState[i].uintValue;
    5755             break;
    5756 
    5757         case SVGA3D_RS_MULTISAMPLEMASK:        /* uint32_t */
    5758         case SVGA3D_RS_ANTIALIASEDLINEENABLE:  /* SVGA3dBool */
    5759             Log(("vmsvga3dSetRenderState: WARNING not applicable??!!\n"));
    5760             break;
    5761 
    5762         case SVGA3D_RS_COORDINATETYPE:         /* SVGA3dCoordinateType */
    5763             Assert(pRenderState[i].uintValue == SVGA3D_COORDINATE_LEFTHANDED);
    5764             /* @todo setup a view matrix to scale the world space by -1 in the z-direction for right handed coordinates. */
    5765             /*
    5766             renderState = D3DRS_COORDINATETYPE;
    5767             val = pRenderState[i].uintValue;
    5768             */
    5769             break;
    5770 
    5771         case SVGA3D_RS_FRONTWINDING:           /* SVGA3dFrontWinding */
    5772             Assert(pRenderState[i].uintValue == SVGA3D_FRONTWINDING_CW);
    5773             /* Invert the selected mode because of y-inversion (?) */
    5774             glFrontFace((pRenderState[i].uintValue != SVGA3D_FRONTWINDING_CW) ? GL_CW : GL_CCW);
    5775             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5776             break;
    5777 
    5778         case SVGA3D_RS_OUTPUTGAMMA:            /* float */
    5779             //AssertFailed();
    5780             /*
    5781             D3DRS_SRGBWRITEENABLE ??
    5782             renderState = D3DRS_OUTPUTGAMMA;
    5783             val = pRenderState[i].uintValue;
    5784             */
    5785             break;
    5786 
    5787 #if 0
    5788 
    5789         case SVGA3D_RS_VERTEXMATERIALENABLE:   /* SVGA3dBool */
    5790             //AssertFailed();
    5791             renderState = D3DRS_INDEXEDVERTEXBLENDENABLE;       /* correct?? */
    5792             val = pRenderState[i].uintValue;
    5793             break;
    5794 
    5795         case SVGA3D_RS_TEXTUREFACTOR:          /* SVGA3dColor */
    5796             renderState = D3DRS_TEXTUREFACTOR;
    5797             val = pRenderState[i].uintValue;
    5798             break;
    5799 
    5800         case SVGA3D_RS_LOCALVIEWER:            /* SVGA3dBool */
    5801             renderState = D3DRS_LOCALVIEWER;
    5802             val = pRenderState[i].uintValue;
    5803             break;
    5804 
    5805         case SVGA3D_RS_ZVISIBLE:               /* SVGA3dBool */
    5806             AssertFailed();
    5807             /*
    5808             renderState = D3DRS_ZVISIBLE;
    5809             val = pRenderState[i].uintValue;
    5810             */
    5811             break;
    5812 
    5813         case SVGA3D_RS_CLIPPING:               /* SVGA3dBool */
    5814             renderState = D3DRS_CLIPPING;
    5815             val = pRenderState[i].uintValue;
    5816             break;
    5817 
    5818         case SVGA3D_RS_WRAP0:                  /* SVGA3dWrapFlags */
    5819             glTexParameter GL_TEXTURE_WRAP_S
    5820             Assert(SVGA3D_WRAPCOORD_3 == D3DWRAPCOORD_3);
    5821             renderState = D3DRS_WRAP0;
    5822             val = pRenderState[i].uintValue;
    5823             break;
    5824 
    5825         case SVGA3D_RS_WRAP1:                  /* SVGA3dWrapFlags */
    5826             glTexParameter GL_TEXTURE_WRAP_T
    5827             renderState = D3DRS_WRAP1;
    5828             val = pRenderState[i].uintValue;
    5829             break;
    5830 
    5831         case SVGA3D_RS_WRAP2:                  /* SVGA3dWrapFlags */
    5832             glTexParameter GL_TEXTURE_WRAP_R
    5833             renderState = D3DRS_WRAP2;
    5834             val = pRenderState[i].uintValue;
    5835             break;
    5836 
    5837 
    5838         case SVGA3D_RS_SEPARATEALPHABLENDENABLE: /* SVGA3dBool */
    5839             renderState = D3DRS_SEPARATEALPHABLENDENABLE;
    5840             val = pRenderState[i].uintValue;
    5841             break;
    5842 
    5843 
    5844         case SVGA3D_RS_BLENDEQUATIONALPHA:     /* SVGA3dBlendEquation */
    5845             renderState = D3DRS_BLENDOPALPHA;
    5846             val = pRenderState[i].uintValue;
    5847             break;
    5848 
    5849         case SVGA3D_RS_TRANSPARENCYANTIALIAS:  /* SVGA3dTransparencyAntialiasType */
    5850             AssertFailed();
    5851             /*
    5852             renderState = D3DRS_TRANSPARENCYANTIALIAS;
    5853             val = pRenderState[i].uintValue;
    5854             */
    5855             break;
    5856 
    5857 #endif
    5858         default:
    5859             AssertFailed();
    5860             break;
    5861         }
    5862 
    5863         if (enableCap != ~0U)
    5864         {
    5865             if (val)
    5866                 glEnable(enableCap);
    5867             else
    5868                 glDisable(enableCap);
    5869         }
    5870     }
    5871 
    5872     return VINF_SUCCESS;
    5873 }
    5874 
    5875 int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
    5876 {
    5877     PVMSVGA3DCONTEXT            pContext;
    5878     PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
    5879     PVMSVGA3DSURFACE            pRenderTarget;
    5880 
    5881     AssertReturn(pState, VERR_NO_MEMORY);
    5882     AssertReturn(type < SVGA3D_RT_MAX, VERR_INVALID_PARAMETER);
    5883     AssertReturn(target.face == 0, VERR_INVALID_PARAMETER);
    5884 
    5885     Log(("vmsvga3dSetRenderTarget cid=%x type=%x surface id=%x\n", cid, type, target.sid));
    5886 
    5887     if (    cid >= pState->cContexts
    5888         ||  pState->papContexts[cid]->id != cid)
    5889     {
    5890         Log(("vmsvga3dSetRenderTarget invalid context id!\n"));
    5891         return VERR_INVALID_PARAMETER;
    5892     }
    5893     pContext = pState->papContexts[cid];
    5894     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    5895 
    5896     /* Save for vm state save/restore. */
    5897     pContext->state.aRenderTargets[type] = target.sid;
    5898 
    5899     if (target.sid == SVGA3D_INVALID_ID)
    5900     {
    5901         /* Disable render target. */
    5902         switch (type)
    5903         {
    5904         case SVGA3D_RT_DEPTH:
    5905         case SVGA3D_RT_STENCIL:
    5906             pState->ext.glFramebufferRenderbuffer(GL_FRAMEBUFFER, (type == SVGA3D_RT_DEPTH) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
    5907             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5908             break;
    5909 
    5910         case SVGA3D_RT_COLOR0:
    5911         case SVGA3D_RT_COLOR1:
    5912         case SVGA3D_RT_COLOR2:
    5913         case SVGA3D_RT_COLOR3:
    5914         case SVGA3D_RT_COLOR4:
    5915         case SVGA3D_RT_COLOR5:
    5916         case SVGA3D_RT_COLOR6:
    5917         case SVGA3D_RT_COLOR7:
    5918             pContext->sidRenderTarget = SVGA3D_INVALID_ID;
    5919             pState->ext.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + type - SVGA3D_RT_COLOR0, 0, 0, 0);
    5920             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5921             break;
    5922 
    5923         default:
    5924             AssertFailedReturn(VERR_INVALID_PARAMETER);
    5925         }
    5926         return VINF_SUCCESS;
    5927     }
    5928 
    5929     AssertReturn(target.sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    5930     AssertReturn(target.sid < pState->cSurfaces && pState->papSurfaces[target.sid]->id == target.sid, VERR_INVALID_PARAMETER);
    5931     pRenderTarget = pState->papSurfaces[target.sid];
    5932 
    5933     switch (type)
    5934     {
    5935     case SVGA3D_RT_DEPTH:
    5936     case SVGA3D_RT_STENCIL:
    5937         AssertReturn(target.mipmap == 0, VERR_INVALID_PARAMETER);
    5938         if (pRenderTarget->oglId.texture == OPENGL_INVALID_ID)
    5939         {
    5940             Log(("vmsvga3dSetRenderTarget: create renderbuffer to be used as render target; surface id=%x type=%d format=%d\n", target.sid, pRenderTarget->flags, pRenderTarget->internalFormatGL));
    5941 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    5942             pContext = &pState->SharedCtx;
    5943             VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    5944 #endif
    5945             pState->ext.glGenRenderbuffers(1, &pRenderTarget->oglId.renderbuffer);
    5946             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5947 
    5948             pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
    5949             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5950 
    5951             pState->ext.glRenderbufferStorage(GL_RENDERBUFFER,
    5952                                               pRenderTarget->internalFormatGL,
    5953                                               pRenderTarget->pMipmapLevels[0].size.width,
    5954                                               pRenderTarget->pMipmapLevels[0].size.height);
    5955             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5956 
    5957 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    5958             pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, OPENGL_INVALID_ID);
    5959             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5960 
    5961             pContext = pState->papContexts[cid];
    5962             VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    5963 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_1
    5964             pRenderTarget->idWeakContextAssociation = cid;
    5965 # endif
    5966 #else
    5967             LogFlow(("vmsvga3dSetRenderTarget: sid=%x idAssociatedContext %#x -> %#x\n", pRenderTarget->id, pRenderTarget->idAssociatedContext, cid));
    5968             pRenderTarget->idAssociatedContext = cid;
    5969 #endif
    5970         }
    5971 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    5972         else
    5973 #endif
    5974         {
    5975             pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
    5976             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5977         }
    5978 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    5979         Assert(pRenderTarget->idAssociatedContext == cid);
    5980 #endif
    5981         Assert(!pRenderTarget->fDirty);
    5982         AssertReturn(pRenderTarget->oglId.texture != OPENGL_INVALID_ID, VERR_INVALID_PARAMETER);
    5983 
    5984         pRenderTarget->flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
    5985 
    5986         pState->ext.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
    5987                                               (type == SVGA3D_RT_DEPTH) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT,
    5988                                               GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
    5989         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    5990         break;
    5991 
    5992     case SVGA3D_RT_COLOR0:
    5993     case SVGA3D_RT_COLOR1:
    5994     case SVGA3D_RT_COLOR2:
    5995     case SVGA3D_RT_COLOR3:
    5996     case SVGA3D_RT_COLOR4:
    5997     case SVGA3D_RT_COLOR5:
    5998     case SVGA3D_RT_COLOR6:
    5999     case SVGA3D_RT_COLOR7:
    6000     {
    6001         /* A texture surface can be used as a render target to fill it and later on used as a texture. */
    6002         if (pRenderTarget->oglId.texture == OPENGL_INVALID_ID)
    6003         {
    6004             Log(("vmsvga3dSetRenderTarget: create texture to be used as render target; surface id=%x type=%d format=%d -> create texture\n", target.sid, pRenderTarget->flags, pRenderTarget->format));
    6005             int rc = vmsvga3dCreateTexture(pState, pContext, cid, pRenderTarget);
    6006             AssertRCReturn(rc, rc);
    6007         }
    6008 
    6009         AssertReturn(pRenderTarget->oglId.texture != OPENGL_INVALID_ID, VERR_INVALID_PARAMETER);
    6010         Assert(!pRenderTarget->fDirty);
    6011 
    6012         pRenderTarget->flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
    6013 
    6014         pState->ext.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + type - SVGA3D_RT_COLOR0, GL_TEXTURE_2D, pRenderTarget->oglId.texture, target.mipmap);
    6015         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6016 
    6017         pContext->sidRenderTarget = target.sid;
    6018 
    6019 #ifdef DEBUG
    6020         GLenum status = pState->ext.glCheckFramebufferStatus(GL_FRAMEBUFFER);
    6021         if (status != GL_FRAMEBUFFER_COMPLETE)
    6022             Log(("vmsvga3dSetRenderTarget: WARNING: glCheckFramebufferStatus returned %x\n", status));
    6023 #endif
    6024         /* @todo use glDrawBuffers too? */
    6025         break;
    6026     }
    6027 
    6028     default:
    6029         AssertFailedReturn(VERR_INVALID_PARAMETER);
    6030     }
    6031 
    6032     return VINF_SUCCESS;
    6033 }
    6034 
    6035 #if 0
    6036 /**
    6037  * Convert SVGA texture combiner value to its D3D equivalent
    6038  */
    6039 static DWORD vmsvga3dTextureCombiner2D3D(uint32_t value)
    6040 {
    6041     switch (value)
    6042     {
    6043     case SVGA3D_TC_DISABLE:
    6044         return D3DTOP_DISABLE;
    6045     case SVGA3D_TC_SELECTARG1:
    6046         return D3DTOP_SELECTARG1;
    6047     case SVGA3D_TC_SELECTARG2:
    6048         return D3DTOP_SELECTARG2;
    6049     case SVGA3D_TC_MODULATE:
    6050         return D3DTOP_MODULATE;
    6051     case SVGA3D_TC_ADD:
    6052         return D3DTOP_ADD;
    6053     case SVGA3D_TC_ADDSIGNED:
    6054         return D3DTOP_ADDSIGNED;
    6055     case SVGA3D_TC_SUBTRACT:
    6056         return D3DTOP_SUBTRACT;
    6057     case SVGA3D_TC_BLENDTEXTUREALPHA:
    6058         return D3DTOP_BLENDTEXTUREALPHA;
    6059     case SVGA3D_TC_BLENDDIFFUSEALPHA:
    6060         return D3DTOP_BLENDDIFFUSEALPHA;
    6061     case SVGA3D_TC_BLENDCURRENTALPHA:
    6062         return D3DTOP_BLENDCURRENTALPHA;
    6063     case SVGA3D_TC_BLENDFACTORALPHA:
    6064         return D3DTOP_BLENDFACTORALPHA;
    6065     case SVGA3D_TC_MODULATE2X:
    6066         return D3DTOP_MODULATE2X;
    6067     case SVGA3D_TC_MODULATE4X:
    6068         return D3DTOP_MODULATE4X;
    6069     case SVGA3D_TC_DSDT:
    6070         AssertFailed(); /* @todo ??? */
    6071         return D3DTOP_DISABLE;
    6072     case SVGA3D_TC_DOTPRODUCT3:
    6073         return D3DTOP_DOTPRODUCT3;
    6074     case SVGA3D_TC_BLENDTEXTUREALPHAPM:
    6075         return D3DTOP_BLENDTEXTUREALPHAPM;
    6076     case SVGA3D_TC_ADDSIGNED2X:
    6077         return D3DTOP_ADDSIGNED2X;
    6078     case SVGA3D_TC_ADDSMOOTH:
    6079         return D3DTOP_ADDSMOOTH;
    6080     case SVGA3D_TC_PREMODULATE:
    6081         return D3DTOP_PREMODULATE;
    6082     case SVGA3D_TC_MODULATEALPHA_ADDCOLOR:
    6083         return D3DTOP_MODULATEALPHA_ADDCOLOR;
    6084     case SVGA3D_TC_MODULATECOLOR_ADDALPHA:
    6085         return D3DTOP_MODULATECOLOR_ADDALPHA;
    6086     case SVGA3D_TC_MODULATEINVALPHA_ADDCOLOR:
    6087         return D3DTOP_MODULATEINVALPHA_ADDCOLOR;
    6088     case SVGA3D_TC_MODULATEINVCOLOR_ADDALPHA:
    6089         return D3DTOP_MODULATEINVCOLOR_ADDALPHA;
    6090     case SVGA3D_TC_BUMPENVMAPLUMINANCE:
    6091         return D3DTOP_BUMPENVMAPLUMINANCE;
    6092     case SVGA3D_TC_MULTIPLYADD:
    6093         return D3DTOP_MULTIPLYADD;
    6094     case SVGA3D_TC_LERP:
    6095         return D3DTOP_LERP;
    6096     default:
    6097         AssertFailed();
    6098         return D3DTOP_DISABLE;
    6099     }
    6100 }
    6101 
    6102 /**
    6103  * Convert SVGA texture arg data value to its D3D equivalent
    6104  */
    6105 static DWORD vmsvga3dTextureArgData2D3D(uint32_t value)
    6106 {
    6107     switch (value)
    6108     {
    6109     case SVGA3D_TA_CONSTANT:
    6110         return D3DTA_CONSTANT;
    6111     case SVGA3D_TA_PREVIOUS:
    6112         return D3DTA_CURRENT;   /* current = previous */
    6113     case SVGA3D_TA_DIFFUSE:
    6114         return D3DTA_DIFFUSE;
    6115     case SVGA3D_TA_TEXTURE:
    6116         return D3DTA_TEXTURE;
    6117     case SVGA3D_TA_SPECULAR:
    6118         return D3DTA_SPECULAR;
    6119     default:
    6120         AssertFailed();
    6121         return 0;
    6122     }
    6123 }
    6124 
    6125 /**
    6126  * Convert SVGA texture transform flag value to its D3D equivalent
    6127  */
    6128 static DWORD vmsvga3dTextTransformFlags2D3D(uint32_t value)
    6129 {
    6130     switch (value)
    6131     {
    6132     case SVGA3D_TEX_TRANSFORM_OFF:
    6133         return D3DTTFF_DISABLE;
    6134     case SVGA3D_TEX_TRANSFORM_S:
    6135         return D3DTTFF_COUNT1;      /* @todo correct? */
    6136     case SVGA3D_TEX_TRANSFORM_T:
    6137         return D3DTTFF_COUNT2;      /* @todo correct? */
    6138     case SVGA3D_TEX_TRANSFORM_R:
    6139         return D3DTTFF_COUNT3;      /* @todo correct? */
    6140     case SVGA3D_TEX_TRANSFORM_Q:
    6141         return D3DTTFF_COUNT4;      /* @todo correct? */
    6142     case SVGA3D_TEX_PROJECTED:
    6143         return D3DTTFF_PROJECTED;
    6144     default:
    6145         AssertFailed();
    6146         return 0;
    6147     }
    6148 }
    6149 #endif
    6150 
    6151 static GLenum vmsvga3dTextureAddress2OGL(SVGA3dTextureAddress value)
    6152 {
    6153     switch (value)
    6154     {
    6155     case SVGA3D_TEX_ADDRESS_WRAP:
    6156         return GL_REPEAT;
    6157     case SVGA3D_TEX_ADDRESS_MIRROR:
    6158         return GL_MIRRORED_REPEAT;
    6159     case SVGA3D_TEX_ADDRESS_CLAMP:
    6160         return GL_CLAMP_TO_EDGE;
    6161     case SVGA3D_TEX_ADDRESS_BORDER:
    6162         return GL_CLAMP_TO_BORDER;
    6163     case SVGA3D_TEX_ADDRESS_MIRRORONCE:
    6164         AssertFailed();
    6165         return GL_CLAMP_TO_EDGE_SGIS; /* @todo correct? */
    6166 
    6167     case SVGA3D_TEX_ADDRESS_EDGE:
    6168     case SVGA3D_TEX_ADDRESS_INVALID:
    6169     default:
    6170         AssertFailed();
    6171         return GL_REPEAT;   /* default */
    6172     }
    6173 }
    6174 
    6175 static GLenum vmsvga3dTextureFilter2OGL(SVGA3dTextureFilter value)
    6176 {
    6177     switch (value)
    6178     {
    6179     case SVGA3D_TEX_FILTER_NONE:
    6180     case SVGA3D_TEX_FILTER_LINEAR:
    6181         return GL_LINEAR;
    6182     case SVGA3D_TEX_FILTER_NEAREST:
    6183         return GL_NEAREST;
    6184     case SVGA3D_TEX_FILTER_ANISOTROPIC:
    6185         /* @todo */
    6186     case SVGA3D_TEX_FILTER_FLATCUBIC:       // Deprecated, not implemented
    6187     case SVGA3D_TEX_FILTER_GAUSSIANCUBIC:   // Deprecated, not implemented
    6188     case SVGA3D_TEX_FILTER_PYRAMIDALQUAD:   // Not currently implemented
    6189     case SVGA3D_TEX_FILTER_GAUSSIANQUAD:    // Not currently implemented
    6190     default:
    6191         AssertFailed();
    6192         return GL_LINEAR;   /* default */
    6193     }
    6194 }
    6195 
    6196 uint32_t vmsvga3dSVGA3dColor2RGBA(SVGA3dColor value)
    6197 {
    6198     /* flip the red and blue bytes */
    6199     uint8_t blue = value & 0xff;
    6200     uint8_t red  = (value >> 16) & 0xff;
    6201     return (value & 0xff00ff00) | red | (blue << 16);
    6202 }
    6203 
    6204 int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
    6205 {
    6206     GLenum                      val;
    6207     GLenum                      currentStage = ~0L;
    6208     PVMSVGA3DCONTEXT            pContext;
    6209     PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
    6210     AssertReturn(pState, VERR_NO_MEMORY);
    6211 
    6212     Log(("vmsvga3dSetTextureState %x cTextureState=%d\n", cid, cTextureStates));
    6213 
    6214     if (    cid >= pState->cContexts
    6215         ||  pState->papContexts[cid]->id != cid)
    6216     {
    6217         Log(("vmsvga3dSetTextureState invalid context id!\n"));
    6218         return VERR_INVALID_PARAMETER;
    6219     }
    6220     pContext = pState->papContexts[cid];
    6221     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6222 
    6223     for (unsigned i = 0; i < cTextureStates; i++)
    6224     {
    6225         GLenum textureType = ~0U;
    6226         GLenum samplerType = ~0U;
    6227 
    6228         Log(("vmsvga3dSetTextureState: cid=%x stage=%d type=%s (%x) val=%x\n", cid, pTextureState[i].stage, vmsvga3dTextureStateToString(pTextureState[i].name), pTextureState[i].name, pTextureState[i].value));
    6229         /* Record the texture state for vm state saving. */
    6230         if (    pTextureState[i].stage < SVGA3D_MAX_TEXTURE_STAGE
    6231             &&  pTextureState[i].name < SVGA3D_TS_MAX)
    6232         {
    6233             pContext->state.aTextureState[pTextureState[i].stage][pTextureState[i].name] = pTextureState[i];
    6234         }
    6235 
    6236         /* Active the right texture unit for subsequent texture state changes. */
    6237         if (pTextureState[i].stage != currentStage || i == 0)
    6238         {
    6239             /** @todo Is this the appropriate limit for all kinds of textures?  It is the
    6240              * size of aSidActiveTexture and for binding/unbinding we cannot exceed it. */
    6241             if (pTextureState[i].stage < SVGA3D_MAX_TEXTURE_STAGE)
    6242             {
    6243                 pState->ext.glActiveTexture(GL_TEXTURE0 + pTextureState[i].stage);
    6244                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6245                 currentStage = pTextureState[i].stage;
    6246             }
    6247             else
    6248             {
    6249                 AssertMsgFailed(("pTextureState[%d].stage=%#x name=%#x\n", i, pTextureState[i].stage, pTextureState[i].name));
    6250                 continue;
    6251             }
    6252         }
    6253 
    6254         switch (pTextureState[i].name)
    6255         {
    6256         case SVGA3D_TS_BUMPENVMAT00:                /* float */
    6257         case SVGA3D_TS_BUMPENVMAT01:                /* float */
    6258         case SVGA3D_TS_BUMPENVMAT10:                /* float */
    6259         case SVGA3D_TS_BUMPENVMAT11:                /* float */
    6260         case SVGA3D_TS_BUMPENVLSCALE:               /* float */
    6261         case SVGA3D_TS_BUMPENVLOFFSET:              /* float */
    6262             Log(("vmsvga3dSetTextureState: bump mapping texture options not supported!!\n"));
    6263             break;
    6264 
    6265         case SVGA3D_TS_COLOROP:                     /* SVGA3dTextureCombiner */
    6266         case SVGA3D_TS_COLORARG0:                   /* SVGA3dTextureArgData */
    6267         case SVGA3D_TS_COLORARG1:                   /* SVGA3dTextureArgData */
    6268         case SVGA3D_TS_COLORARG2:                   /* SVGA3dTextureArgData */
    6269         case SVGA3D_TS_ALPHAOP:                     /* SVGA3dTextureCombiner */
    6270         case SVGA3D_TS_ALPHAARG0:                   /* SVGA3dTextureArgData */
    6271         case SVGA3D_TS_ALPHAARG1:                   /* SVGA3dTextureArgData */
    6272         case SVGA3D_TS_ALPHAARG2:                   /* SVGA3dTextureArgData */
    6273             /* @todo; not used by MesaGL */
    6274             Log(("vmsvga3dSetTextureState: colorop/alphaop not yet supported!!\n"));
    6275             break;
    6276 #if 0
    6277 
    6278         case SVGA3D_TS_TEXCOORDINDEX:               /* uint32_t */
    6279             textureType = D3DTSS_TEXCOORDINDEX;
    6280             val = pTextureState[i].value;
    6281             break;
    6282 
    6283         case SVGA3D_TS_TEXTURETRANSFORMFLAGS:       /* SVGA3dTexTransformFlags */
    6284             textureType = D3DTSS_TEXTURETRANSFORMFLAGS;
    6285             val = vmsvga3dTextTransformFlags2D3D(pTextureState[i].value);
    6286             break;
    6287 #endif
    6288 
    6289         case SVGA3D_TS_BIND_TEXTURE:                /* SVGA3dSurfaceId */
    6290             if (pTextureState[i].value == SVGA3D_INVALID_ID)
    6291             {
    6292                 Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x replacing=%x\n",
    6293                      currentStage, pTextureState[i].value, pContext->aSidActiveTexture[currentStage]));
    6294 
    6295                 pContext->aSidActiveTexture[currentStage] = SVGA3D_INVALID_ID;
    6296                 /* Unselect the currently associated texture. */
    6297                 glBindTexture(GL_TEXTURE_2D, 0);
    6298                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6299                 /* Necessary for the fixed pipeline. */
    6300                 glDisable(GL_TEXTURE_2D);
    6301                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6302             }
    6303             else
    6304             {
    6305                 uint32_t sid = pTextureState[i].value;
    6306 
    6307                 AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    6308                 AssertReturn(sid < pState->cSurfaces && pState->papSurfaces[sid]->id == sid, VERR_INVALID_PARAMETER);
    6309 
    6310                 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    6311 
    6312                 Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x (%d,%d) replacing=%x\n",
    6313                      currentStage, pTextureState[i].value, pSurface->pMipmapLevels[0].size.width,
    6314                      pSurface->pMipmapLevels[0].size.height, pContext->aSidActiveTexture[currentStage]));
    6315 
    6316                 if (pSurface->oglId.texture == OPENGL_INVALID_ID)
    6317                 {
    6318 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    6319                     Assert(pSurface->idAssociatedContext == SVGA3D_INVALID_ID);
    6320 #endif
    6321                     Log(("CreateTexture (%d,%d) level=%d\n", pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height, pSurface->faces[0].numMipLevels));
    6322                     int rc = vmsvga3dCreateTexture(pState, pContext, cid, pSurface);
    6323                     AssertRCReturn(rc, rc);
    6324                 }
    6325 
    6326                 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    6327                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6328 
    6329                 /* Necessary for the fixed pipeline. */
    6330                 glEnable(GL_TEXTURE_2D);
    6331                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6332 
    6333                 if (pContext->aSidActiveTexture[currentStage] != sid)
    6334                 {
    6335                     /* Recreate the texture state as glBindTexture resets them all (sigh). */
    6336                     for (uint32_t iStage = 0; iStage < SVGA3D_MAX_TEXTURE_STAGE; iStage++)
    6337                     {
    6338                         for (uint32_t j = 0; j < SVGA3D_TS_MAX; j++)
    6339                         {
    6340                             SVGA3dTextureState *pTextureStateIter = &pContext->state.aTextureState[iStage][j];
    6341 
    6342                             if (    pTextureStateIter->name != SVGA3D_TS_INVALID
    6343                                 &&  pTextureStateIter->name != SVGA3D_TS_BIND_TEXTURE)
    6344                                 vmsvga3dSetTextureState(pThis, pContext->id, 1, pTextureStateIter);
    6345                         }
    6346                     }
    6347                 }
    6348                 pContext->aSidActiveTexture[currentStage] = sid;
    6349             }
    6350             /* Finished; continue with the next one. */
    6351             continue;
    6352 
    6353         case SVGA3D_TS_ADDRESSW:                    /* SVGA3dTextureAddress */
    6354             textureType = GL_TEXTURE_WRAP_R;    /* R = W */
    6355             val = vmsvga3dTextureAddress2OGL((SVGA3dTextureAddress)pTextureState[i].value);
    6356             break;
    6357 
    6358         case SVGA3D_TS_ADDRESSU:                    /* SVGA3dTextureAddress */
    6359             textureType = GL_TEXTURE_WRAP_S;    /* S = U */
    6360             val = vmsvga3dTextureAddress2OGL((SVGA3dTextureAddress)pTextureState[i].value);
    6361             break;
    6362 
    6363         case SVGA3D_TS_ADDRESSV:                    /* SVGA3dTextureAddress */
    6364             textureType = GL_TEXTURE_WRAP_T;    /* T = V */
    6365             val = vmsvga3dTextureAddress2OGL((SVGA3dTextureAddress)pTextureState[i].value);
    6366             break;
    6367 
    6368         case SVGA3D_TS_MIPFILTER:                   /* SVGA3dTextureFilter */
    6369         case SVGA3D_TS_MINFILTER:                   /* SVGA3dTextureFilter */
    6370         {
    6371             uint32_t mipFilter = pContext->state.aTextureState[currentStage][SVGA3D_TS_MIPFILTER].value;
    6372             uint32_t minFilter = pContext->state.aTextureState[currentStage][SVGA3D_TS_MINFILTER].value;
    6373 
    6374             /* If SVGA3D_TS_MIPFILTER is set to NONE, then use SVGA3D_TS_MIPFILTER, otherwise SVGA3D_TS_MIPFILTER enables mipmap minification. */
    6375             textureType = GL_TEXTURE_MIN_FILTER;
    6376             if (mipFilter != SVGA3D_TEX_FILTER_NONE)
    6377             {
    6378                 if (minFilter == SVGA3D_TEX_FILTER_NEAREST)
    6379                 {
    6380                     if (mipFilter == SVGA3D_TEX_FILTER_LINEAR)
    6381                         val = GL_NEAREST_MIPMAP_LINEAR;
    6382                     else
    6383                         val = GL_NEAREST_MIPMAP_NEAREST;
    6384                 }
    6385                 else
    6386                 {
    6387                     if (mipFilter == SVGA3D_TEX_FILTER_LINEAR)
    6388                         val = GL_LINEAR_MIPMAP_LINEAR;
    6389                     else
    6390                         val = GL_LINEAR_MIPMAP_NEAREST;
    6391                 }
    6392             }
    6393             else
    6394                 val = vmsvga3dTextureFilter2OGL((SVGA3dTextureFilter)minFilter);
    6395             break;
    6396         }
    6397 
    6398         case SVGA3D_TS_MAGFILTER:                   /* SVGA3dTextureFilter */
    6399             textureType = GL_TEXTURE_MAG_FILTER;
    6400             val = vmsvga3dTextureFilter2OGL((SVGA3dTextureFilter)pTextureState[i].value);
    6401             Assert(val == GL_NEAREST || val == GL_LINEAR);
    6402             break;
    6403 
    6404         case SVGA3D_TS_BORDERCOLOR:                 /* SVGA3dColor */
    6405         {
    6406             GLfloat color[4]; /* red, green, blue, alpha */
    6407 
    6408             vmsvgaColor2GLFloatArray(pTextureState[i].value, &color[0], &color[1], &color[2], &color[3]);
    6409 
    6410             glTexParameterfv(GL_TEXTURE_2D /* @todo flexible type */, GL_TEXTURE_BORDER_COLOR, color);   /* Identical; default 0.0 identical too */
    6411             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6412             break;
    6413         }
    6414 
    6415         case SVGA3D_TS_TEXTURE_LOD_BIAS:            /* float */
    6416             glTexParameterf(GL_TEXTURE_2D /* @todo flexible type */, GL_TEXTURE_LOD_BIAS, pTextureState[i].value);   /* Identical; default 0.0 identical too */
    6417             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6418             break;
    6419 
    6420         case SVGA3D_TS_TEXTURE_MIPMAP_LEVEL:        /* uint32_t */
    6421             textureType = GL_TEXTURE_BASE_LEVEL;
    6422             val = pTextureState[i].value;
    6423             break;
    6424 
    6425 #if 0
    6426         case SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL:   /* uint32_t */
    6427             samplerType = D3DSAMP_MAXANISOTROPY;
    6428             val = pTextureState[i].value;   /* Identical?? */
    6429             break;
    6430 
    6431         case SVGA3D_TS_GAMMA:                       /* float */
    6432             samplerType = D3DSAMP_SRGBTEXTURE;
    6433             /* Boolean in D3D */
    6434             if (pTextureState[i].floatValue == 1.0f)
    6435                 val = FALSE;
    6436             else
    6437                 val = TRUE;
    6438             break;
    6439 #endif
    6440         /* Internal commands, that don't map directly to the SetTextureStageState API. */
    6441         case SVGA3D_TS_TEXCOORDGEN:                 /* SVGA3dTextureCoordGen */
    6442             AssertFailed();
    6443             break;
    6444 
    6445         default:
    6446             //AssertFailed();
    6447             break;
    6448         }
    6449 
    6450         if (textureType != ~0U)
    6451         {
    6452             glTexParameteri(GL_TEXTURE_2D /* @todo flexible type */, textureType, val);
    6453             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6454         }
    6455     }
    6456 
    6457     return VINF_SUCCESS;
    6458 }
    6459 
    6460 int vmsvga3dSetMaterial(PVGASTATE pThis, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
    6461 {
    6462     PVMSVGA3DCONTEXT      pContext;
    6463     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6464     AssertReturn(pState, VERR_NO_MEMORY);
    6465     GLenum                oglFace;
    6466 
    6467     Log(("vmsvga3dSetMaterial cid=%x face %d\n", cid, face));
    6468 
    6469     if (    cid >= pState->cContexts
    6470         ||  pState->papContexts[cid]->id != cid)
    6471     {
    6472         Log(("vmsvga3dSetMaterial invalid context id!\n"));
    6473         return VERR_INVALID_PARAMETER;
    6474     }
    6475     pContext = pState->papContexts[cid];
    6476     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6477 
    6478     switch (face)
    6479     {
    6480     case SVGA3D_FACE_NONE:
    6481     case SVGA3D_FACE_FRONT:
    6482         oglFace = GL_FRONT;
    6483         break;
    6484 
    6485     case SVGA3D_FACE_BACK:
    6486         oglFace = GL_BACK;
    6487         break;
    6488 
    6489     case SVGA3D_FACE_FRONT_BACK:
    6490         oglFace = GL_FRONT_AND_BACK;
    6491         break;
    6492 
    6493     default:
    6494         AssertFailedReturn(VERR_INVALID_PARAMETER);
    6495     }
    6496 
    6497     /* Save for vm state save/restore. */
    6498     pContext->state.aMaterial[face].fValid = true;
    6499     pContext->state.aMaterial[face].material = *pMaterial;
    6500     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_MATERIAL;
    6501 
    6502     glMaterialfv(oglFace, GL_DIFFUSE, pMaterial->diffuse);
    6503     glMaterialfv(oglFace, GL_AMBIENT, pMaterial->ambient);
    6504     glMaterialfv(oglFace, GL_SPECULAR, pMaterial->specular);
    6505     glMaterialfv(oglFace, GL_EMISSION, pMaterial->emissive);
    6506     glMaterialfv(oglFace, GL_SHININESS, &pMaterial->shininess);
    6507     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6508 
    6509     return VINF_SUCCESS;
    6510 }
    6511 
    6512 /* @todo Move into separate library as we are using logic from Wine here. */
    6513 int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
    6514 {
    6515     PVMSVGA3DCONTEXT      pContext;
    6516     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6517     AssertReturn(pState, VERR_NO_MEMORY);
    6518     float                 QuadAttenuation;
    6519 
    6520     Log(("vmsvga3dSetLightData cid=%x index=%d type=%d\n", cid, index, pData->type));
    6521 
    6522     if (    cid >= pState->cContexts
    6523         ||  pState->papContexts[cid]->id != cid)
    6524     {
    6525         Log(("vmsvga3dSetLightData invalid context id!\n"));
    6526         return VERR_INVALID_PARAMETER;
    6527     }
    6528     pContext = pState->papContexts[cid];
    6529     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6530 
    6531     /* Store for vm state save/restore */
    6532     if (index < SVGA3D_MAX_LIGHTS)
    6533     {
    6534         pContext->state.aLightData[index].fValidData = true;
    6535         pContext->state.aLightData[index].data = *pData;
    6536     }
    6537     else
    6538         AssertFailed();
    6539 
    6540     if (    pData->attenuation0 < 0.0f
    6541         ||  pData->attenuation1 < 0.0f
    6542         ||  pData->attenuation2 < 0.0f)
    6543     {
    6544         Log(("vmsvga3dSetLightData: invalid negative attenuation values!!\n"));
    6545         return VINF_SUCCESS;    /* ignore; could crash the GL driver */
    6546     }
    6547 
    6548     /* Light settings are affected by the model view in OpenGL, the View transform in direct3d */
    6549     glMatrixMode(GL_MODELVIEW);
    6550     glPushMatrix();
    6551     glLoadMatrixf(pContext->state.aTransformState[SVGA3D_TRANSFORM_VIEW].matrix);
    6552 
    6553     glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, pData->diffuse);
    6554     glLightfv(GL_LIGHT0 + index, GL_SPECULAR, pData->specular);
    6555     glLightfv(GL_LIGHT0 + index, GL_AMBIENT, pData->ambient);
    6556 
    6557     if (pData->range * pData->range >= FLT_MIN)
    6558         QuadAttenuation = 1.4f / (pData->range * pData->range);
    6559     else
    6560         QuadAttenuation = 0.0f;
    6561 
    6562     switch (pData->type)
    6563     {
    6564     case SVGA3D_LIGHTTYPE_POINT:
    6565     {
    6566         GLfloat position[4];
    6567 
    6568         position[0] = pData->position[0];
    6569         position[1] = pData->position[1];
    6570         position[2] = pData->position[2];
    6571         position[3] = 1.0f;
    6572 
    6573         glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
    6574         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6575 
    6576         glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
    6577         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6578 
    6579         /* Attenuation - Are these right? guessing... */
    6580         glLightf(GL_LIGHT0 + index, GL_CONSTANT_ATTENUATION, pData->attenuation0);
    6581         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6582 
    6583         glLightf(GL_LIGHT0 + index, GL_LINEAR_ATTENUATION, pData->attenuation1);
    6584         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6585 
    6586         glLightf(GL_LIGHT0 + index, GL_QUADRATIC_ATTENUATION, (QuadAttenuation < pData->attenuation2) ? pData->attenuation2 : QuadAttenuation);
    6587         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6588 
    6589         /* @todo range */
    6590         break;
    6591     }
    6592 
    6593     case SVGA3D_LIGHTTYPE_SPOT1:
    6594     {
    6595         GLfloat exponent;
    6596         GLfloat position[4];
    6597         const GLfloat pi = 4.0f * atanf(1.0f);
    6598 
    6599         position[0] = pData->position[0];
    6600         position[1] = pData->position[1];
    6601         position[2] = pData->position[2];
    6602         position[3] = 1.0f;
    6603 
    6604         glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
    6605         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6606 
    6607         position[0] = pData->direction[0];
    6608         position[1] = pData->direction[1];
    6609         position[2] = pData->direction[2];
    6610         position[3] = 1.0f;
    6611 
    6612         glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, position);
    6613         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6614 
    6615         /*
    6616          * opengl-ish and d3d-ish spot lights use too different models for the
    6617          * light "intensity" as a function of the angle towards the main light direction,
    6618          * so we only can approximate very roughly.
    6619          * however spot lights are rather rarely used in games (if ever used at all).
    6620          * furthermore if still used, probably nobody pays attention to such details.
    6621          */
    6622         if (pData->falloff == 0)
    6623         {
    6624             /* Falloff = 0 is easy, because d3d's and opengl's spot light equations have the
    6625              * falloff resp. exponent parameter as an exponent, so the spot light lighting
    6626              * will always be 1.0 for both of them, and we don't have to care for the
    6627              * rest of the rather complex calculation
    6628              */
    6629             exponent = 0.0f;
    6630         }
    6631         else
    6632         {
    6633             float rho = pData->theta + (pData->phi - pData->theta) / (2 * pData->falloff);
    6634             if (rho < 0.0001f)
    6635                 rho = 0.0001f;
    6636             exponent = -0.3f/log(cos(rho/2));
    6637         }
    6638         if (exponent > 128.0f)
    6639             exponent = 128.0f;
    6640 
    6641         glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, exponent);
    6642         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6643 
    6644         glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, pData->phi * 90.0 / pi);
    6645         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6646 
    6647         /* Attenuation - Are these right? guessing... */
    6648         glLightf(GL_LIGHT0 + index, GL_CONSTANT_ATTENUATION, pData->attenuation0);
    6649         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6650 
    6651         glLightf(GL_LIGHT0 + index, GL_LINEAR_ATTENUATION, pData->attenuation1);
    6652         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6653 
    6654         glLightf(GL_LIGHT0 + index, GL_QUADRATIC_ATTENUATION, (QuadAttenuation < pData->attenuation2) ? pData->attenuation2 : QuadAttenuation);
    6655         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6656 
    6657         /* @todo range */
    6658         break;
    6659     }
    6660 
    6661     case SVGA3D_LIGHTTYPE_DIRECTIONAL:
    6662     {
    6663         GLfloat position[4];
    6664 
    6665         position[0] = -pData->direction[0];
    6666         position[1] = -pData->direction[1];
    6667         position[2] = -pData->direction[2];
    6668         position[3] = 0.0f;
    6669 
    6670         glLightfv(GL_LIGHT0 + index, GL_POSITION, position); /* Note gl uses w position of 0 for direction! */
    6671         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6672 
    6673         glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
    6674         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6675 
    6676         glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, 0.0f);
    6677         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    6678         break;
    6679     }
    6680 
    6681     case SVGA3D_LIGHTTYPE_SPOT2:
    6682     default:
    6683         Log(("Unsupported light type!!\n"));
    6684         return VERR_INVALID_PARAMETER;
    6685     }
    6686 
    6687     /* Restore the modelview matrix */
    6688     glPopMatrix();
    6689 
    6690     return VINF_SUCCESS;
    6691 }
    6692 
    6693 int vmsvga3dSetLightEnabled(PVGASTATE pThis, uint32_t cid, uint32_t index, uint32_t enabled)
    6694 {
    6695     PVMSVGA3DCONTEXT      pContext;
    6696     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6697     AssertReturn(pState, VERR_NO_MEMORY);
    6698 
    6699     Log(("vmsvga3dSetLightEnabled cid=%x %d -> %d\n", cid, index, enabled));
    6700 
    6701     if (    cid >= pState->cContexts
    6702         ||  pState->papContexts[cid]->id != cid)
    6703     {
    6704         Log(("vmsvga3dSetLightEnabled invalid context id!\n"));
    6705         return VERR_INVALID_PARAMETER;
    6706     }
    6707     pContext = pState->papContexts[cid];
    6708     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6709 
    6710     /* Store for vm state save/restore */
    6711     if (index < SVGA3D_MAX_LIGHTS)
    6712         pContext->state.aLightData[index].fEnabled = !!enabled;
    6713     else
    6714         AssertFailed();
    6715 
    6716     if (enabled)
    6717     {
    6718         /* Load the default settings if none have been set yet. */
    6719         if (!pContext->state.aLightData[index].fValidData)
    6720             vmsvga3dSetLightData(pThis, cid, index, (SVGA3dLightData *)&vmsvga3d_default_light);
    6721         glEnable(GL_LIGHT0 + index);
    6722     }
    6723     else
    6724         glDisable(GL_LIGHT0 + index);
    6725 
    6726     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6727     return VINF_SUCCESS;
    6728 }
    6729 
    6730 int vmsvga3dSetViewPort(PVGASTATE pThis, uint32_t cid, SVGA3dRect *pRect)
    6731 {
    6732     PVMSVGA3DCONTEXT      pContext;
    6733     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6734     AssertReturn(pState, VERR_NO_MEMORY);
    6735 
    6736     Log(("vmsvga3dSetViewPort cid=%x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
    6737 
    6738     if (    cid >= pState->cContexts
    6739         ||  pState->papContexts[cid]->id != cid)
    6740     {
    6741         Log(("vmsvga3dSetViewPort invalid context id!\n"));
    6742         return VERR_INVALID_PARAMETER;
    6743     }
    6744     pContext = pState->papContexts[cid];
    6745     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6746 
    6747     /* Save for vm state save/restore. */
    6748     pContext->state.RectViewPort = *pRect;
    6749     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_VIEWPORT;
    6750 
    6751     /* @todo y-inversion for partial viewport coordinates? */
    6752     glViewport(pRect->x, pRect->y, pRect->w, pRect->h);
    6753     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6754 
    6755     /* Reset the projection matrix as that relies on the viewport setting. */
    6756     if (pContext->state.aTransformState[SVGA3D_TRANSFORM_PROJECTION].fValid == true)
    6757     {
    6758         vmsvga3dSetTransform(pThis, cid, SVGA3D_TRANSFORM_PROJECTION, pContext->state.aTransformState[SVGA3D_TRANSFORM_PROJECTION].matrix);
    6759     }
    6760     else
    6761     {
    6762         float matrix[16];
    6763 
    6764         /* identity matrix if no matrix set. */
    6765         memset(matrix, 0, sizeof(matrix));
    6766         matrix[0]  = 1.0;
    6767         matrix[5]  = 1.0;
    6768         matrix[10] = 1.0;
    6769         matrix[15] = 1.0;
    6770         vmsvga3dSetTransform(pThis, cid, SVGA3D_TRANSFORM_PROJECTION, matrix);
    6771     }
    6772 
    6773     return VINF_SUCCESS;
    6774 }
    6775 
    6776 int vmsvga3dSetClipPlane(PVGASTATE pThis, uint32_t cid,  uint32_t index, float plane[4])
    6777 {
    6778     PVMSVGA3DCONTEXT      pContext;
    6779     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6780     AssertReturn(pState, VERR_NO_MEMORY);
    6781     double                oglPlane[4];
    6782 
    6783     Log(("vmsvga3dSetClipPlane cid=%x %d (%d,%d)(%d,%d)\n", cid, index, (unsigned)(plane[0] * 100.0), (unsigned)(plane[1] * 100.0), (unsigned)(plane[2] * 100.0), (unsigned)(plane[3] * 100.0)));
    6784     AssertReturn(index < SVGA3D_CLIPPLANE_MAX, VERR_INVALID_PARAMETER);
    6785 
    6786     if (    cid >= pState->cContexts
    6787         ||  pState->papContexts[cid]->id != cid)
    6788     {
    6789         Log(("vmsvga3dSetClipPlane invalid context id!\n"));
    6790         return VERR_INVALID_PARAMETER;
    6791     }
    6792     pContext = pState->papContexts[cid];
    6793     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6794 
    6795     /* Store for vm state save/restore. */
    6796     pContext->state.aClipPlane[index].fValid = true;
    6797     memcpy(pContext->state.aClipPlane[index].plane, plane, sizeof(pContext->state.aClipPlane[index].plane));
    6798 
    6799     /** @todo clip plane affected by model view in OpenGL & view in D3D + vertex shader -> not transformed (see Wine; state.c clipplane) */
    6800     oglPlane[0] = (double)plane[0];
    6801     oglPlane[1] = (double)plane[1];
    6802     oglPlane[2] = (double)plane[2];
    6803     oglPlane[3] = (double)plane[3];
    6804 
    6805     glClipPlane(GL_CLIP_PLANE0 + index, oglPlane);
    6806     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6807 
    6808     return VINF_SUCCESS;
    6809 }
    6810 
    6811 int vmsvga3dSetScissorRect(PVGASTATE pThis, uint32_t cid, SVGA3dRect *pRect)
    6812 {
    6813     PVMSVGA3DCONTEXT      pContext;
    6814     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6815     AssertReturn(pState, VERR_NO_MEMORY);
    6816 
    6817     Log(("vmsvga3dSetScissorRect cid=%x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
    6818 
    6819     if (    cid >= pState->cContexts
    6820         ||  pState->papContexts[cid]->id != cid)
    6821     {
    6822         Log(("vmsvga3dSetScissorRect invalid context id!\n"));
    6823         return VERR_INVALID_PARAMETER;
    6824     }
    6825     pContext = pState->papContexts[cid];
    6826     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6827 
    6828     /* Store for vm state save/restore. */
    6829     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_SCISSORRECT;
    6830     pContext->state.RectScissor = *pRect;
    6831 
    6832     glScissor(pRect->x, pRect->y, pRect->w, pRect->h);
    6833     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6834 
    6835     return VINF_SUCCESS;
    6836 }
    6837 
    6838 static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha)
    6839 {
    6840     /* Convert byte color components to float (0-1.0) */
    6841     *pAlpha = (GLfloat)(color >> 24) / 255.0;
    6842     *pRed   = (GLfloat)((color >> 16) & 0xff) / 255.0;
    6843     *pGreen = (GLfloat)((color >> 8) & 0xff) / 255.0;
    6844     *pBlue  = (GLfloat)(color & 0xff) / 255.0;
    6845 }
    6846 
    6847 int vmsvga3dCommandClear(PVGASTATE pThis, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth, uint32_t stencil,
    6848                          uint32_t cRects, SVGA3dRect *pRect)
    6849 {
    6850     GLbitfield            mask = 0;
    6851     PVMSVGA3DCONTEXT      pContext;
    6852     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    6853     AssertReturn(pState, VERR_NO_MEMORY);
    6854     GLboolean             fDepthWriteEnabled = GL_FALSE;
    6855 
    6856     Log(("vmsvga3dCommandClear cid=%x clearFlag=%x color=%x depth=%d stencil=%x cRects=%d\n", cid, clearFlag, color, (uint32_t)(depth * 100.0), stencil, cRects));
    6857 
    6858     if (    cid >= pState->cContexts
    6859         ||  pState->papContexts[cid]->id != cid)
    6860     {
    6861         Log(("vmsvga3dCommandClear invalid context id!\n"));
    6862         return VERR_INVALID_PARAMETER;
    6863     }
    6864     pContext = pState->papContexts[cid];
    6865     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    6866 
    6867     if (clearFlag & SVGA3D_CLEAR_COLOR)
    6868     {
    6869         GLfloat red, green, blue, alpha;
    6870 
    6871         vmsvgaColor2GLFloatArray(color, &red, &green, &blue, &alpha);
    6872 
    6873         /* Set the color clear value. */
    6874         glClearColor(red, green, blue, alpha);
    6875 
    6876         mask |= GL_COLOR_BUFFER_BIT;
    6877     }
    6878     if (clearFlag & SVGA3D_CLEAR_STENCIL)
    6879     {
    6880         /* @todo possibly the same problem as with glDepthMask */
    6881         glClearStencil(stencil);
    6882         mask |= GL_STENCIL_BUFFER_BIT;
    6883     }
    6884     if (clearFlag & SVGA3D_CLEAR_DEPTH)
    6885     {
    6886         glClearDepth((GLdouble)depth);
    6887         mask |= GL_DEPTH_BUFFER_BIT;
    6888 
    6889         /* glClear will not clear the depth buffer if writing is disabled. */
    6890         glGetBooleanv(GL_DEPTH_WRITEMASK, &fDepthWriteEnabled);
    6891         if (fDepthWriteEnabled == GL_FALSE)
    6892             glDepthMask(GL_TRUE);
    6893     }
    6894 
    6895     if (cRects)
    6896     {
    6897         /* Save the current scissor test bit and scissor box. */
    6898         glPushAttrib(GL_SCISSOR_BIT);
    6899         glEnable(GL_SCISSOR_TEST);
    6900         for (unsigned i=0; i < cRects; i++)
    6901         {
    6902             Log(("vmsvga3dCommandClear: rect %d (%d,%d)(%d,%d)\n", i, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
    6903             glScissor(pRect[i].x, pRect[i].y, pRect[i].w, pRect[i].h);
    6904             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6905             glClear(mask);
    6906             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6907         }
    6908         /* Restore the old scissor test bit and box */
    6909         glPopAttrib();
    6910     }
    6911     else
    6912     {
    6913         glClear(mask);
    6914         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    6915     }
    6916 
    6917     /* Restore depth write state. */
    6918     if (    (clearFlag & SVGA3D_CLEAR_DEPTH)
    6919         && fDepthWriteEnabled == GL_FALSE)
    6920         glDepthMask(GL_FALSE);
    6921 
    6922     return VINF_SUCCESS;
    6923 }
    6924 
    6925 /* Convert VMWare vertex declaration to its OpenGL equivalent. */
    6926 int vmsvga3dVertexDecl2OGL(SVGA3dVertexArrayIdentity &identity, GLint &size, GLenum &type, GLboolean &normalized)
    6927 {
    6928     normalized = GL_FALSE;
    6929     switch (identity.type)
    6930     {
    6931     case SVGA3D_DECLTYPE_FLOAT1:
    6932         size = 1;
    6933         type = GL_FLOAT;
    6934         break;
    6935     case SVGA3D_DECLTYPE_FLOAT2:
    6936         size = 2;
    6937         type = GL_FLOAT;
    6938         break;
    6939     case SVGA3D_DECLTYPE_FLOAT3:
    6940         size = 3;
    6941         type = GL_FLOAT;
    6942         break;
    6943     case SVGA3D_DECLTYPE_FLOAT4:
    6944         size = 4;
    6945         type = GL_FLOAT;
    6946         break;
    6947 
    6948     case SVGA3D_DECLTYPE_D3DCOLOR:
    6949         size = GL_BGRA;                 /* @note requires GL_ARB_vertex_array_bgra */
    6950         type = GL_UNSIGNED_BYTE;
    6951         normalized = GL_TRUE;   /* glVertexAttribPointer fails otherwise */
    6952         break;
    6953 
    6954     case SVGA3D_DECLTYPE_UBYTE4N:
    6955         normalized = GL_TRUE;
    6956         /* no break */
    6957     case SVGA3D_DECLTYPE_UBYTE4:
    6958         size = 4;
    6959         type = GL_UNSIGNED_BYTE;
    6960         break;
    6961 
    6962     case SVGA3D_DECLTYPE_SHORT2N:
    6963         normalized = GL_TRUE;
    6964         /* no break */
    6965     case SVGA3D_DECLTYPE_SHORT2:
    6966         size = 2;
    6967         type = GL_SHORT;
    6968         break;
    6969 
    6970     case SVGA3D_DECLTYPE_SHORT4N:
    6971         normalized = GL_TRUE;
    6972         /* no break */
    6973     case SVGA3D_DECLTYPE_SHORT4:
    6974         size = 4;
    6975         type = GL_SHORT;
    6976         break;
    6977 
    6978     case SVGA3D_DECLTYPE_USHORT4N:
    6979         normalized = GL_TRUE;
    6980         size = 4;
    6981         type = GL_UNSIGNED_SHORT;
    6982         break;
    6983 
    6984     case SVGA3D_DECLTYPE_USHORT2N:
    6985         normalized = GL_TRUE;
    6986         size = 2;
    6987         type = GL_UNSIGNED_SHORT;
    6988         break;
    6989 
    6990     case SVGA3D_DECLTYPE_UDEC3:
    6991         size = 3;
    6992         type = GL_UNSIGNED_INT_2_10_10_10_REV;    /* @todo correct? */
    6993         break;
    6994 
    6995     case SVGA3D_DECLTYPE_DEC3N:
    6996         normalized = true;
    6997         size = 3;
    6998         type = GL_INT_2_10_10_10_REV;    /* @todo correct? */
    6999         break;
    7000 
    7001     case SVGA3D_DECLTYPE_FLOAT16_2:
    7002         size = 2;
    7003         type = GL_HALF_FLOAT;
    7004         break;
    7005     case SVGA3D_DECLTYPE_FLOAT16_4:
    7006         size = 4;
    7007         type = GL_HALF_FLOAT;
    7008         break;
    7009     default:
    7010         AssertFailedReturn(VERR_INVALID_PARAMETER);
    7011     }
    7012 
    7013     //pVertexElement->Method      = identity.method;
    7014     //pVertexElement->Usage       = identity.usage;
    7015 
    7016     return VINF_SUCCESS;
    7017 }
    7018 
    7019 /* Convert VMWare primitive type to its OpenGL equivalent. */
    7020 /* Calculate the vertex count based on the primitive type and nr of primitives. */
    7021 int vmsvga3dPrimitiveType2OGL(SVGA3dPrimitiveType PrimitiveType, GLenum *pMode, uint32_t cPrimitiveCount, uint32_t *pcVertices)
    7022 {
    7023     switch (PrimitiveType)
    7024     {
    7025     case SVGA3D_PRIMITIVE_TRIANGLELIST:
    7026         *pMode      = GL_TRIANGLES;
    7027         *pcVertices = cPrimitiveCount * 3;
    7028         break;
    7029     case SVGA3D_PRIMITIVE_POINTLIST:
    7030         *pMode = GL_POINTS;
    7031         *pcVertices = cPrimitiveCount;
    7032         break;
    7033     case SVGA3D_PRIMITIVE_LINELIST:
    7034         *pMode = GL_LINES;
    7035         *pcVertices = cPrimitiveCount * 2;
    7036         break;
    7037     case SVGA3D_PRIMITIVE_LINESTRIP:
    7038         *pMode = GL_LINE_STRIP;
    7039         *pcVertices = cPrimitiveCount + 1;
    7040         break;
    7041     case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
    7042         *pMode = GL_TRIANGLE_STRIP;
    7043         *pcVertices = cPrimitiveCount + 2;
    7044         break;
    7045     case SVGA3D_PRIMITIVE_TRIANGLEFAN:
    7046         *pMode = GL_TRIANGLE_FAN;
    7047         *pcVertices = cPrimitiveCount + 2;
    7048         break;
    7049     default:
    7050         return VERR_INVALID_PARAMETER;
    7051     }
    7052     return VINF_SUCCESS;
    7053 }
    7054 
    7055 int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t iVertexDeclBase, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl)
    7056 {
    7057     unsigned            sidVertex = pVertexDecl[0].array.surfaceId;
    7058     PVMSVGA3DSURFACE    pVertexSurface;
    7059 
    7060     AssertReturn(sidVertex < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    7061     AssertReturn(sidVertex < pState->cSurfaces && pState->papSurfaces[sidVertex]->id == sidVertex, VERR_INVALID_PARAMETER);
    7062 
    7063     pVertexSurface = pState->papSurfaces[sidVertex];
    7064     Log(("vmsvga3dDrawPrimitives: vertex surface %x\n", sidVertex));
    7065 
    7066     /* Create and/or bind the vertex buffer. */
    7067     if (pVertexSurface->oglId.buffer == OPENGL_INVALID_ID)
    7068     {
    7069         Log(("vmsvga3dDrawPrimitives: create vertex buffer fDirty=%d size=%x bytes\n", pVertexSurface->fDirty, pVertexSurface->pMipmapLevels[0].cbSurface));
    7070 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    7071         PVMSVGA3DCONTEXT pSavedCtx = pContext;
    7072         pContext = &pState->SharedCtx;
    7073         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7074 #endif
    7075 
    7076         pState->ext.glGenBuffers(1, &pVertexSurface->oglId.buffer);
    7077         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7078 
    7079         pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer);
    7080         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7081 
    7082         Assert(pVertexSurface->fDirty);
    7083         /* @todo rethink usage dynamic/static */
    7084         pState->ext.glBufferData(GL_ARRAY_BUFFER, pVertexSurface->pMipmapLevels[0].cbSurface, pVertexSurface->pMipmapLevels[0].pSurfaceData, GL_DYNAMIC_DRAW);
    7085         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7086 
    7087         pVertexSurface->pMipmapLevels[0].fDirty = false;
    7088         pVertexSurface->fDirty = false;
    7089 
    7090         pVertexSurface->flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
    7091 
    7092 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    7093         pState->ext.glBindBuffer(GL_ARRAY_BUFFER, OPENGL_INVALID_ID);
    7094         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7095 
    7096         pContext = pSavedCtx;
    7097         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7098 #endif
    7099     }
    7100 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    7101     else
    7102 #endif
    7103     {
    7104         Assert(pVertexSurface->fDirty == false);
    7105         pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer);
    7106         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7107     }
    7108 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    7109     pVertexSurface->idAssociatedContext = pContext->id;
    7110     LogFlow(("vmsvga3dDrawPrimitivesProcessVertexDecls: sid=%x idAssociatedContext %#x -> %#x\n", pVertexSurface->id, pVertexSurface->idAssociatedContext, pContext->id));
    7111 #endif
    7112 
    7113     /* Setup the vertex declarations. */
    7114     for (unsigned iVertex = 0; iVertex < numVertexDecls; iVertex++)
    7115     {
    7116         GLint size;
    7117         GLenum type;
    7118         GLboolean normalized;
    7119         GLuint index = iVertexDeclBase + iVertex;
    7120 
    7121         Log(("vmsvga3dDrawPrimitives: array index %d type=%s (%d) method=%s (%d) usage=%s (%d) usageIndex=%d stride=%d offset=%d\n", index, vmsvgaDeclType2String(pVertexDecl[iVertex].identity.type), pVertexDecl[iVertex].identity.type, vmsvgaDeclMethod2String(pVertexDecl[iVertex].identity.method), pVertexDecl[iVertex].identity.method, vmsvgaDeclUsage2String(pVertexDecl[iVertex].identity.usage), pVertexDecl[iVertex].identity.usage, pVertexDecl[iVertex].identity.usageIndex, pVertexDecl[iVertex].array.stride, pVertexDecl[iVertex].array.offset));
    7122 
    7123         int rc = vmsvga3dVertexDecl2OGL(pVertexDecl[iVertex].identity, size, type, normalized);
    7124         AssertRCReturn(rc, rc);
    7125 
    7126         if (pContext->state.shidVertex != SVGA_ID_INVALID)
    7127         {
    7128             /* Use numbered vertex arrays when shaders are active. */
    7129             pState->ext.glEnableVertexAttribArray(index);
    7130             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7131             pState->ext.glVertexAttribPointer(index, size, type, normalized, pVertexDecl[iVertex].array.stride,
    7132                                               (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
    7133             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7134             /* case SVGA3D_DECLUSAGE_COLOR:    @todo color component order not identical!! test GL_BGRA!!  */
    7135         }
    7136         else
    7137         {
    7138             /* Use the predefined selection of vertex streams for the fixed pipeline. */
    7139             switch (pVertexDecl[iVertex].identity.usage)
    7140             {
    7141             case SVGA3D_DECLUSAGE_POSITION:
    7142                 glEnableClientState(GL_VERTEX_ARRAY);
    7143                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7144                 glVertexPointer(size, type, pVertexDecl[iVertex].array.stride,
    7145                                 (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
    7146                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7147                 break;
    7148             case SVGA3D_DECLUSAGE_BLENDWEIGHT:
    7149                 AssertFailed();
    7150                 break;
    7151             case SVGA3D_DECLUSAGE_BLENDINDICES:
    7152                 AssertFailed();
    7153                 break;
    7154             case SVGA3D_DECLUSAGE_NORMAL:
    7155                 glEnableClientState(GL_NORMAL_ARRAY);
    7156                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7157                 glNormalPointer(type, pVertexDecl[iVertex].array.stride,
    7158                                 (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
    7159                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7160                 break;
    7161             case SVGA3D_DECLUSAGE_PSIZE:
    7162                 AssertFailed();
    7163                 break;
    7164             case SVGA3D_DECLUSAGE_TEXCOORD:
    7165                 /* Specify the affected texture unit. */
    7166 #if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x103
    7167                 glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
    7168 #else
    7169                 pState->ext.glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
    7170 #endif
    7171                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    7172                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7173                 glTexCoordPointer(size, type, pVertexDecl[iVertex].array.stride,
    7174                                   (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
    7175                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7176                 break;
    7177             case SVGA3D_DECLUSAGE_TANGENT:
    7178                 AssertFailed();
    7179                 break;
    7180             case SVGA3D_DECLUSAGE_BINORMAL:
    7181                 AssertFailed();
    7182                 break;
    7183             case SVGA3D_DECLUSAGE_TESSFACTOR:
    7184                 AssertFailed();
    7185                 break;
    7186             case SVGA3D_DECLUSAGE_POSITIONT:
    7187                 AssertFailed(); /* see position_transformed in Wine */
    7188                 break;
    7189             case SVGA3D_DECLUSAGE_COLOR:    /** @todo color component order not identical!! test GL_BGRA!! */
    7190                 glEnableClientState(GL_COLOR_ARRAY);
    7191                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7192                 glColorPointer(size, type, pVertexDecl[iVertex].array.stride,
    7193                                (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
    7194                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7195                 break;
    7196             case SVGA3D_DECLUSAGE_FOG:
    7197                 glEnableClientState(GL_FOG_COORD_ARRAY);
    7198                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7199                 pState->ext.glFogCoordPointer(type, pVertexDecl[iVertex].array.stride,
    7200                                               (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
    7201                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7202                 break;
    7203             case SVGA3D_DECLUSAGE_DEPTH:
    7204                 AssertFailed();
    7205                 break;
    7206             case SVGA3D_DECLUSAGE_SAMPLE:
    7207                 AssertFailed();
    7208                 break;
    7209             case SVGA3D_DECLUSAGE_MAX: AssertFailed(); break; /* shut up gcc */
    7210             }
    7211         }
    7212 
    7213 #ifdef LOG_ENABLED
    7214         if (pVertexDecl[iVertex].array.stride == 0)
    7215             Log(("vmsvga3dDrawPrimitives: stride == 0! Can be valid\n"));
    7216 #endif
    7217     }
    7218 
    7219     return VINF_SUCCESS;
    7220 }
    7221 
    7222 int vmsvga3dDrawPrimitivesCleanupVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t iVertexDeclBase, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl)
    7223 {
    7224     /* Setup the vertex declarations. */
    7225     for (unsigned iVertex = 0; iVertex < numVertexDecls; iVertex++)
    7226     {
    7227         if (pContext->state.shidVertex != SVGA_ID_INVALID)
    7228         {
    7229             /* Use numbered vertex arrays when shaders are active. */
    7230             pState->ext.glDisableVertexAttribArray(iVertexDeclBase + iVertex);
    7231             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7232         }
    7233         else
    7234         {
    7235             /* Use the predefined selection of vertex streams for the fixed pipeline. */
    7236             switch (pVertexDecl[iVertex].identity.usage)
    7237             {
    7238             case SVGA3D_DECLUSAGE_POSITION:
    7239                 glDisableClientState(GL_VERTEX_ARRAY);
    7240                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7241                 break;
    7242             case SVGA3D_DECLUSAGE_BLENDWEIGHT:
    7243                 break;
    7244             case SVGA3D_DECLUSAGE_BLENDINDICES:
    7245                 break;
    7246             case SVGA3D_DECLUSAGE_NORMAL:
    7247                 glDisableClientState(GL_NORMAL_ARRAY);
    7248                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7249                 break;
    7250             case SVGA3D_DECLUSAGE_PSIZE:
    7251                 break;
    7252             case SVGA3D_DECLUSAGE_TEXCOORD:
    7253                 /* Specify the affected texture unit. */
    7254 #if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x103
    7255                 glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
    7256 #else
    7257                 pState->ext.glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
    7258 #endif
    7259                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    7260                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7261                 break;
    7262             case SVGA3D_DECLUSAGE_TANGENT:
    7263                 break;
    7264             case SVGA3D_DECLUSAGE_BINORMAL:
    7265                 break;
    7266             case SVGA3D_DECLUSAGE_TESSFACTOR:
    7267                 break;
    7268             case SVGA3D_DECLUSAGE_POSITIONT:
    7269                 break;
    7270             case SVGA3D_DECLUSAGE_COLOR:    /* @todo color component order not identical!! */
    7271                 glDisableClientState(GL_COLOR_ARRAY);
    7272                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7273                 break;
    7274             case SVGA3D_DECLUSAGE_FOG:
    7275                 glDisableClientState(GL_FOG_COORD_ARRAY);
    7276                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7277                 break;
    7278             case SVGA3D_DECLUSAGE_DEPTH:
    7279                 break;
    7280             case SVGA3D_DECLUSAGE_SAMPLE:
    7281                 break;
    7282             case SVGA3D_DECLUSAGE_MAX: AssertFailed(); break; /* shut up gcc */
    7283             }
    7284         }
    7285     }
    7286     /* Unbind the vertex buffer after usage. */
    7287     pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
    7288     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7289     return VINF_SUCCESS;
    7290 }
    7291 
    7292 int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl, uint32_t numRanges, SVGA3dPrimitiveRange *pRange, uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
    7293 {
    7294     PVMSVGA3DCONTEXT             pContext;
    7295     PVMSVGA3DSTATE               pState = pThis->svga.p3dState;
    7296     AssertReturn(pState, VERR_INTERNAL_ERROR);
    7297     int                          rc = VERR_NOT_IMPLEMENTED;
    7298     uint32_t                     iCurrentVertex;
    7299 
    7300     Log(("vmsvga3dDrawPrimitives cid=%x numVertexDecls=%d numRanges=%d, cVertexDivisor=%d\n", cid, numVertexDecls, numRanges, cVertexDivisor));
    7301 
    7302     AssertReturn(numVertexDecls && numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS, VERR_INVALID_PARAMETER);
    7303     AssertReturn(numRanges && numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES, VERR_INVALID_PARAMETER);
    7304     AssertReturn(!cVertexDivisor || cVertexDivisor == numVertexDecls, VERR_INVALID_PARAMETER);
    7305     /* @todo */
    7306     Assert(!cVertexDivisor);
    7307 
    7308     if (    cid >= pState->cContexts
    7309         ||  pState->papContexts[cid]->id != cid)
    7310     {
    7311         Log(("vmsvga3dDrawPrimitives invalid context id!\n"));
    7312         return VERR_INVALID_PARAMETER;
    7313     }
    7314     pContext = pState->papContexts[cid];
    7315     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7316 
    7317     /* Flush any shader changes. */
    7318     if (pContext->pShaderContext)
    7319     {
    7320         uint32_t rtHeight = 0;
    7321 
    7322         if (pContext->sidRenderTarget != SVGA_ID_INVALID)
    7323         {
    7324             PVMSVGA3DSURFACE pRenderTarget = pState->papSurfaces[pContext->sidRenderTarget];
    7325             rtHeight = pRenderTarget->pMipmapLevels[0].size.height;
    7326         }
    7327 
    7328         ShaderUpdateState(pContext->pShaderContext, rtHeight);
    7329     }
    7330 
    7331     /* Process all vertex declarations. Each vertex buffer is represented by one stream. */
    7332     iCurrentVertex   = 0;
    7333     while (iCurrentVertex < numVertexDecls)
    7334     {
    7335         uint32_t sidVertex = SVGA_ID_INVALID;
    7336         uint32_t iVertex;
    7337 
    7338         for (iVertex = iCurrentVertex; iVertex < numVertexDecls; iVertex++)
    7339         {
    7340             if (    sidVertex != SVGA_ID_INVALID
    7341                 &&  pVertexDecl[iVertex].array.surfaceId != sidVertex
    7342                )
    7343                 break;
    7344             sidVertex = pVertexDecl[iVertex].array.surfaceId;
    7345         }
    7346 
    7347         rc = vmsvga3dDrawPrimitivesProcessVertexDecls(pState, pContext, iCurrentVertex, iVertex - iCurrentVertex, &pVertexDecl[iCurrentVertex]);
    7348         AssertRCReturn(rc, rc);
    7349 
    7350         iCurrentVertex = iVertex;
    7351     }
    7352 
    7353     /* Now draw the primitives. */
    7354     for (unsigned iPrimitive = 0; iPrimitive < numRanges; iPrimitive++)
    7355     {
    7356         GLenum           modeDraw;
    7357         unsigned         sidIndex  = pRange[iPrimitive].indexArray.surfaceId;
    7358         PVMSVGA3DSURFACE pIndexSurface = NULL;
    7359         unsigned         cVertices;
    7360 
    7361         Log(("Primitive %d: type %s\n", iPrimitive, vmsvga3dPrimitiveType2String(pRange[iPrimitive].primType)));
    7362         rc = vmsvga3dPrimitiveType2OGL(pRange[iPrimitive].primType, &modeDraw, pRange[iPrimitive].primitiveCount, &cVertices);
    7363         if (RT_FAILURE(rc))
    7364         {
    7365             AssertRC(rc);
    7366             goto internal_error;
    7367         }
    7368 
    7369         if (sidIndex != SVGA3D_INVALID_ID)
    7370         {
    7371             AssertMsg(pRange[iPrimitive].indexWidth == sizeof(uint32_t) || pRange[iPrimitive].indexWidth == sizeof(uint16_t), ("Unsupported primitive width %d\n", pRange[iPrimitive].indexWidth));
    7372 
    7373             if (    sidIndex >= SVGA3D_MAX_SURFACE_IDS
    7374                 ||  sidIndex >= pState->cSurfaces
    7375                 ||  pState->papSurfaces[sidIndex]->id != sidIndex)
    7376             {
    7377                 Assert(sidIndex < SVGA3D_MAX_SURFACE_IDS);
    7378                 Assert(sidIndex < pState->cSurfaces && pState->papSurfaces[sidIndex]->id == sidIndex);
    7379                 rc = VERR_INVALID_PARAMETER;
    7380                 goto internal_error;
    7381             }
    7382             pIndexSurface = pState->papSurfaces[sidIndex];
    7383             Log(("vmsvga3dDrawPrimitives: index surface %x\n", sidIndex));
    7384 
    7385             if (pIndexSurface->oglId.buffer == OPENGL_INVALID_ID)
    7386             {
    7387                 Log(("vmsvga3dDrawPrimitives: create index buffer fDirty=%d size=%x bytes\n", pIndexSurface->fDirty, pIndexSurface->pMipmapLevels[0].cbSurface));
    7388 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    7389                 pContext = &pState->SharedCtx;
    7390                 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7391 #endif
    7392 
    7393                 pState->ext.glGenBuffers(1, &pIndexSurface->oglId.buffer);
    7394                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7395 
    7396                 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer);
    7397                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7398 
    7399                 Assert(pIndexSurface->fDirty);
    7400 
    7401                 /* @todo rethink usage dynamic/static */
    7402                 pState->ext.glBufferData(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->pMipmapLevels[0].cbSurface, pIndexSurface->pMipmapLevels[0].pSurfaceData, GL_DYNAMIC_DRAW);
    7403                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7404 
    7405                 pIndexSurface->pMipmapLevels[0].fDirty = false;
    7406                 pIndexSurface->fDirty = false;
    7407 
    7408                 pIndexSurface->flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
    7409 
    7410 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    7411                 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OPENGL_INVALID_ID);
    7412                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7413 
    7414                 pContext = pState->papContexts[cid];
    7415                 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7416 #endif
    7417             }
    7418 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    7419             else
    7420 #endif
    7421             {
    7422                 Assert(pIndexSurface->fDirty == false);
    7423 
    7424                 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer);
    7425                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7426             }
    7427 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
    7428             LogFlow(("vmsvga3dDrawPrimitives: sid=%x idAssociatedContext %#x -> %#x\n", pIndexSurface->id, pIndexSurface->idAssociatedContext, pContext->id));
    7429             pIndexSurface->idAssociatedContext = pContext->id;
    7430 #endif
    7431         }
    7432 
    7433         if (!pIndexSurface)
    7434         {
    7435             /* Render without an index buffer */
    7436             Log(("DrawPrimitive %x cPrimitives=%d cVertices=%d index index bias=%d\n", modeDraw, pRange[iPrimitive].primitiveCount, cVertices, pRange[iPrimitive].indexBias));
    7437             glDrawArrays(modeDraw, pRange[iPrimitive].indexBias, cVertices);
    7438         }
    7439         else
    7440         {
    7441             Assert(pRange[iPrimitive].indexBias >= 0);  /* @todo */
    7442             Assert(pRange[iPrimitive].indexWidth == pRange[iPrimitive].indexArray.stride);
    7443 
    7444             /* Render with an index buffer */
    7445             Log(("DrawIndexedPrimitive %x cPrimitives=%d cVertices=%d hint.first=%d hint.last=%d index offset=%d primitivecount=%d index width=%d index bias=%d\n", modeDraw, pRange[iPrimitive].primitiveCount, cVertices, pVertexDecl[0].rangeHint.first,  pVertexDecl[0].rangeHint.last,  pRange[iPrimitive].indexArray.offset, pRange[iPrimitive].primitiveCount,  pRange[iPrimitive].indexWidth, pRange[iPrimitive].indexBias));
    7446             if (pRange[iPrimitive].indexBias == 0)
    7447                 glDrawElements(modeDraw,
    7448                                cVertices,
    7449                                (pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
    7450                                (GLvoid *)(uintptr_t)pRange[iPrimitive].indexArray.offset);   /* byte offset in indices buffer */
    7451             else
    7452                 pState->ext.glDrawElementsBaseVertex(modeDraw,
    7453                                                      cVertices,
    7454                                                      (pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
    7455                                                      (GLvoid *)(uintptr_t)pRange[iPrimitive].indexArray.offset, /* byte offset in indices buffer */
    7456                                                      pRange[iPrimitive].indexBias);  /* basevertex */
    7457 
    7458             /* Unbind the index buffer after usage. */
    7459             pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    7460             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7461         }
    7462         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    7463     }
    7464 
    7465 internal_error:
    7466 
    7467     /* Deactivate the vertex declarations. */
    7468     iCurrentVertex   = 0;
    7469     while (iCurrentVertex < numVertexDecls)
    7470     {
    7471         uint32_t sidVertex = SVGA_ID_INVALID;
    7472         uint32_t iVertex;
    7473 
    7474         for (iVertex = iCurrentVertex; iVertex < numVertexDecls; iVertex++)
    7475         {
    7476             if (    sidVertex != SVGA_ID_INVALID
    7477                 &&  pVertexDecl[iVertex].array.surfaceId != sidVertex
    7478                )
    7479                 break;
    7480             sidVertex = pVertexDecl[iVertex].array.surfaceId;
    7481         }
    7482 
    7483         rc = vmsvga3dDrawPrimitivesCleanupVertexDecls(pState, pContext, iCurrentVertex, iVertex - iCurrentVertex, &pVertexDecl[iCurrentVertex]);
    7484         AssertRCReturn(rc, rc);
    7485 
    7486         iCurrentVertex = iVertex;
    7487     }
    7488 #ifdef DEBUG
    7489     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
    7490     {
    7491         if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
    7492         {
    7493             GLint activeTexture = 0;
    7494             GLint activeTextureUnit = 0;
    7495 
    7496             glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTextureUnit);
    7497             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    7498             pState->ext.glActiveTexture(GL_TEXTURE0 + i);
    7499             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    7500 
    7501             glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    7502             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    7503             pState->ext.glActiveTexture(activeTextureUnit);
    7504             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    7505 
    7506 # if 0 /* Aren't we checking whether 'activeTexture' on texture unit 'i' matches what we expected?  This works if only one unit is active, but if both are it _will_ fail for one of them. */
    7507             if (pContext->aSidActiveTexture[activeTextureUnit - GL_TEXTURE0] != SVGA3D_INVALID_ID)
    7508             {
    7509                 PVMSVGA3DSURFACE pTexture;
    7510                 pTexture = pState->papSurfaces[pContext->aSidActiveTexture[activeTextureUnit - GL_TEXTURE0]];
    7511 
    7512                 AssertMsg(pTexture->oglId.texture == (GLuint)activeTexture, ("%x vs %x unit %d - %d\n", pTexture->oglId.texture, activeTexture, i, activeTextureUnit - GL_TEXTURE0));
    7513             }
    7514 # else
    7515             PVMSVGA3DSURFACE pTexture = pState->papSurfaces[pContext->aSidActiveTexture[i]];
    7516             AssertMsg(pTexture->id == pContext->aSidActiveTexture[i], ("%x vs %x\n", pTexture->id == pContext->aSidActiveTexture[i]));
    7517             AssertMsg(pTexture->oglId.texture == (GLuint)activeTexture,
    7518                       ("%x vs %x unit %d (active unit %d) sid=%x\n", pTexture->oglId.texture, activeTexture, i,
    7519                        activeTextureUnit - GL_TEXTURE0, pContext->aSidActiveTexture[i]));
    7520 # endif
    7521         }
    7522     }
    7523 #endif
    7524 
    7525 #ifdef DEBUG_GFX_WINDOW
    7526     if (pContext->aSidActiveTexture[0])
    7527     {
    7528         SVGA3dCopyRect rect;
    7529 
    7530         rect.srcx = rect.srcy = rect.x = rect.y = 0;
    7531         rect.w = 800;
    7532         rect.h = 600;
    7533         vmsvga3dCommandPresent(pThis, pContext->sidRenderTarget, 0, NULL);
    7534     }
    7535 #endif
    7536     return rc;
    7537 }
    7538 
    7539 
    7540 int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dShaderType type, uint32_t cbData, uint32_t *pShaderData)
    7541 {
    7542     PVMSVGA3DCONTEXT      pContext;
    7543     PVMSVGA3DSHADER       pShader;
    7544     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    7545     AssertReturn(pState, VERR_NO_MEMORY);
    7546     int                   rc;
    7547 
    7548     Log(("vmsvga3dShaderDefine cid=%x shid=%x type=%s cbData=%x\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cbData));
    7549     Log3(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
    7550 
    7551     if (    cid >= pState->cContexts
    7552         ||  pState->papContexts[cid]->id != cid)
    7553     {
    7554         Log(("vmsvga3dShaderDefine invalid context id!\n"));
    7555         return VERR_INVALID_PARAMETER;
    7556     }
    7557     pContext = pState->papContexts[cid];
    7558     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7559 
    7560     AssertReturn(shid < SVGA3D_MAX_SHADER_IDS, VERR_INVALID_PARAMETER);
    7561     if (type == SVGA3D_SHADERTYPE_VS)
    7562     {
    7563         if (shid >= pContext->cVertexShaders)
    7564         {
    7565             void *pvNew = RTMemRealloc(pContext->paVertexShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
    7566             AssertReturn(pvNew, VERR_NO_MEMORY);
    7567             pContext->paVertexShader = (PVMSVGA3DSHADER)pvNew;
    7568             memset(&pContext->paVertexShader[pContext->cVertexShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cVertexShaders));
    7569             for (uint32_t i = pContext->cVertexShaders; i < shid + 1; i++)
    7570                 pContext->paVertexShader[i].id = SVGA3D_INVALID_ID;
    7571             pContext->cVertexShaders = shid + 1;
    7572         }
    7573         /* If one already exists with this id, then destroy it now. */
    7574         if (pContext->paVertexShader[shid].id != SVGA3D_INVALID_ID)
    7575             vmsvga3dShaderDestroy(pThis, cid, shid, pContext->paVertexShader[shid].type);
    7576 
    7577         pShader = &pContext->paVertexShader[shid];
    7578     }
    7579     else
    7580     {
    7581         Assert(type == SVGA3D_SHADERTYPE_PS);
    7582         if (shid >= pContext->cPixelShaders)
    7583         {
    7584             void *pvNew = RTMemRealloc(pContext->paPixelShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
    7585             AssertReturn(pvNew, VERR_NO_MEMORY);
    7586             pContext->paPixelShader = (PVMSVGA3DSHADER)pvNew;
    7587             memset(&pContext->paPixelShader[pContext->cPixelShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cPixelShaders));
    7588             for (uint32_t i = pContext->cPixelShaders; i < shid + 1; i++)
    7589                 pContext->paPixelShader[i].id = SVGA3D_INVALID_ID;
    7590             pContext->cPixelShaders = shid + 1;
    7591         }
    7592         /* If one already exists with this id, then destroy it now. */
    7593         if (pContext->paPixelShader[shid].id != SVGA3D_INVALID_ID)
    7594             vmsvga3dShaderDestroy(pThis, cid, shid, pContext->paPixelShader[shid].type);
    7595 
    7596         pShader = &pContext->paPixelShader[shid];
    7597     }
    7598 
    7599     memset(pShader, 0, sizeof(*pShader));
    7600     pShader->id     = shid;
    7601     pShader->cid    = cid;
    7602     pShader->type   = type;
    7603     pShader->cbData = cbData;
    7604     pShader->pShaderProgram = RTMemAllocZ(cbData);
    7605     AssertReturn(pShader->pShaderProgram, VERR_NO_MEMORY);
    7606     memcpy(pShader->pShaderProgram, pShaderData, cbData);
    7607 
    7608 #ifdef DUMP_SHADER_DISASSEMBLY
    7609     LPD3DXBUFFER pDisassembly;
    7610     HRESULT hr = D3DXDisassembleShader((const DWORD *)pShaderData, FALSE, NULL, &pDisassembly);
    7611     if (hr == D3D_OK)
    7612     {
    7613         Log(("Shader disassembly:\n%s\n", pDisassembly->GetBufferPointer()));
    7614         pDisassembly->Release();
    7615     }
    7616 #endif
    7617 
    7618     switch (type)
    7619     {
    7620     case SVGA3D_SHADERTYPE_VS:
    7621         rc = ShaderCreateVertexShader(pContext->pShaderContext, (const uint32_t *)pShaderData, &pShader->u.pVertexShader);
    7622         break;
    7623 
    7624     case SVGA3D_SHADERTYPE_PS:
    7625         rc = ShaderCreatePixelShader(pContext->pShaderContext, (const uint32_t *)pShaderData, &pShader->u.pPixelShader);
    7626         break;
    7627 
    7628     default:
    7629         AssertFailedReturn(VERR_INVALID_PARAMETER);
    7630     }
    7631     if (rc != VINF_SUCCESS)
    7632     {
    7633         RTMemFree(pShader->pShaderProgram);
    7634         memset(pShader, 0, sizeof(*pShader));
    7635         pShader->id = SVGA3D_INVALID_ID;
    7636     }
    7637 
    7638     return rc;
    7639 }
    7640 
    7641 int vmsvga3dShaderDestroy(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
    7642 {
    7643     PVMSVGA3DCONTEXT      pContext;
    7644     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    7645     AssertReturn(pState, VERR_NO_MEMORY);
    7646     PVMSVGA3DSHADER       pShader = NULL;
    7647     int                   rc;
    7648 
    7649     Log(("vmsvga3dShaderDestroy cid=%x shid=%x type=%s\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL"));
    7650 
    7651     if (    cid >= pState->cContexts
    7652         ||  pState->papContexts[cid]->id != cid)
    7653     {
    7654         Log(("vmsvga3dShaderDestroy invalid context id!\n"));
    7655         return VERR_INVALID_PARAMETER;
    7656     }
    7657     pContext = pState->papContexts[cid];
    7658     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7659 
    7660     if (type == SVGA3D_SHADERTYPE_VS)
    7661     {
    7662         if (    shid < pContext->cVertexShaders
    7663             &&  pContext->paVertexShader[shid].id == shid)
    7664         {
    7665             pShader = &pContext->paVertexShader[shid];
    7666             rc = ShaderDestroyVertexShader(pContext->pShaderContext, pShader->u.pVertexShader);
    7667             AssertRC(rc);
    7668         }
    7669     }
    7670     else
    7671     {
    7672         Assert(type == SVGA3D_SHADERTYPE_PS);
    7673         if (    shid < pContext->cPixelShaders
    7674             &&  pContext->paPixelShader[shid].id == shid)
    7675         {
    7676             pShader = &pContext->paPixelShader[shid];
    7677             rc = ShaderDestroyPixelShader(pContext->pShaderContext, pShader->u.pPixelShader);
    7678             AssertRC(rc);
    7679         }
    7680     }
    7681 
    7682     if (pShader)
    7683     {
    7684         if (pShader->pShaderProgram)
    7685             RTMemFree(pShader->pShaderProgram);
    7686         memset(pShader, 0, sizeof(*pShader));
    7687         pShader->id = SVGA3D_INVALID_ID;
    7688     }
    7689     else
    7690         AssertFailedReturn(VERR_INVALID_PARAMETER);
    7691 
    7692     return VINF_SUCCESS;
    7693 }
    7694 
    7695 int vmsvga3dShaderSet(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
    7696 {
    7697     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    7698     AssertReturn(pState, VERR_NO_MEMORY);
    7699     int                 rc;
    7700 
    7701     Log(("vmsvga3dShaderSet cid=%x type=%s shid=%d\n", cid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", shid));
    7702 
    7703     if (   !pContext
    7704         && cid < pState->cContexts
    7705         && pState->papContexts[cid]->id == cid)
    7706         pContext = pState->papContexts[cid];
    7707     else if (!pContext)
    7708     {
    7709         AssertMsgFailed(("cid=%#x cContexts=%#x\n", cid, pState->cContexts));
    7710         Log(("vmsvga3dShaderSet invalid context id!\n"));
    7711         return VERR_INVALID_PARAMETER;
    7712     }
    7713     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7714 
    7715     if (type == SVGA3D_SHADERTYPE_VS)
    7716     {
    7717         /* Save for vm state save/restore. */
    7718         pContext->state.shidVertex = shid;
    7719         pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_VERTEXSHADER;
    7720 
    7721         if (    shid < pContext->cVertexShaders
    7722             &&  pContext->paVertexShader[shid].id == shid)
    7723         {
    7724             PVMSVGA3DSHADER pShader = &pContext->paVertexShader[shid];
    7725             Assert(type == pShader->type);
    7726 
    7727             rc = ShaderSetVertexShader(pContext->pShaderContext, pShader->u.pVertexShader);
    7728             AssertRCReturn(rc, rc);
    7729         }
    7730         else
    7731         if (shid == SVGA_ID_INVALID)
    7732         {
    7733             /* Unselect shader. */
    7734             rc = ShaderSetVertexShader(pContext->pShaderContext, NULL);
    7735             AssertRCReturn(rc, rc);
    7736         }
    7737         else
    7738             AssertFailedReturn(VERR_INVALID_PARAMETER);
    7739     }
    7740     else
    7741     {
    7742         /* Save for vm state save/restore. */
    7743         pContext->state.shidPixel = shid;
    7744         pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_PIXELSHADER;
    7745 
    7746         Assert(type == SVGA3D_SHADERTYPE_PS);
    7747         if (    shid < pContext->cPixelShaders
    7748             &&  pContext->paPixelShader[shid].id == shid)
    7749         {
    7750             PVMSVGA3DSHADER pShader = &pContext->paPixelShader[shid];
    7751             Assert(type == pShader->type);
    7752 
    7753             rc = ShaderSetPixelShader(pContext->pShaderContext, pShader->u.pPixelShader);
    7754             AssertRCReturn(rc, rc);
    7755         }
    7756         else
    7757         if (shid == SVGA_ID_INVALID)
    7758         {
    7759             /* Unselect shader. */
    7760             rc = ShaderSetPixelShader(pContext->pShaderContext, NULL);
    7761             AssertRCReturn(rc, rc);
    7762         }
    7763         else
    7764             AssertFailedReturn(VERR_INVALID_PARAMETER);
    7765     }
    7766 
    7767     return VINF_SUCCESS;
    7768 }
    7769 
    7770 int vmsvga3dShaderSetConst(PVGASTATE pThis, uint32_t cid, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
    7771 {
    7772     PVMSVGA3DCONTEXT      pContext;
    7773     PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
    7774     AssertReturn(pState, VERR_NO_MEMORY);
    7775     int                   rc;
    7776 
    7777     Log(("vmsvga3dShaderSetConst cid=%x reg=%x type=%s cregs=%d ctype=%x\n", cid, reg, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cRegisters, ctype));
    7778 
    7779     if (    cid >= pState->cContexts
    7780         ||  pState->papContexts[cid]->id != cid)
    7781     {
    7782         Log(("vmsvga3dShaderSetConst invalid context id!\n"));
    7783         return VERR_INVALID_PARAMETER;
    7784     }
    7785     pContext = pState->papContexts[cid];
    7786     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    7787 
    7788     for (uint32_t i = 0; i < cRegisters; i++)
    7789     {
    7790 #ifdef LOG_ENABLED
    7791         switch (ctype)
    7792         {
    7793             case SVGA3D_CONST_TYPE_FLOAT:
    7794             {
    7795                 float *pValuesF = (float *)pValues;
    7796                 Log(("Constant %d: value=%d-%d-%d-%d\n", reg + i, (int)(pValuesF[i*4 + 0] * 100.0), (int)(pValuesF[i*4 + 1] * 100.0), (int)(pValuesF[i*4 + 2] * 100.0), (int)(pValuesF[i*4 + 3] * 100.0)));
    7797                 break;
    7798             }
    7799 
    7800             case SVGA3D_CONST_TYPE_INT:
    7801                 Log(("Constant %d: value=%x-%x-%x-%x\n", reg + i, pValues[i*4 + 0], pValues[i*4 + 1], pValues[i*4 + 2], pValues[i*4 + 3]));
    7802                 break;
    7803 
    7804             case SVGA3D_CONST_TYPE_BOOL:
    7805                 Log(("Constant %d: value=%x-%x-%x-%x\n", reg + i, pValues[i*4 + 0], pValues[i*4 + 1], pValues[i*4 + 2], pValues[i*4 + 3]));
    7806                 break;
    7807         }
    7808 #endif
    7809         vmsvga3dSaveShaderConst(pContext, reg + i, type, ctype, pValues[i*4 + 0], pValues[i*4 + 1], pValues[i*4 + 2], pValues[i*4 + 3]);
    7810     }
    7811 
    7812     switch (type)
    7813     {
    7814     case SVGA3D_SHADERTYPE_VS:
    7815         switch (ctype)
    7816         {
    7817         case SVGA3D_CONST_TYPE_FLOAT:
    7818             rc = ShaderSetVertexShaderConstantF(pContext->pShaderContext, reg, (const float *)pValues, cRegisters);
    7819             break;
    7820 
    7821         case SVGA3D_CONST_TYPE_INT:
    7822             rc = ShaderSetVertexShaderConstantI(pContext->pShaderContext, reg, (const int32_t *)pValues, cRegisters);
    7823             break;
    7824 
    7825         case SVGA3D_CONST_TYPE_BOOL:
    7826             rc = ShaderSetVertexShaderConstantB(pContext->pShaderContext, reg, (const uint8_t *)pValues, cRegisters);
    7827             break;
    7828 
    7829         default:
    7830             AssertFailedReturn(VERR_INVALID_PARAMETER);
    7831         }
    7832         AssertRCReturn(rc, rc);
    7833         break;
    7834 
    7835     case SVGA3D_SHADERTYPE_PS:
    7836         switch (ctype)
    7837         {
    7838         case SVGA3D_CONST_TYPE_FLOAT:
    7839             rc = ShaderSetPixelShaderConstantF(pContext->pShaderContext, reg, (const float *)pValues, cRegisters);
    7840             break;
    7841 
    7842         case SVGA3D_CONST_TYPE_INT:
    7843             rc = ShaderSetPixelShaderConstantI(pContext->pShaderContext, reg, (const int32_t *)pValues, cRegisters);
    7844             break;
    7845 
    7846         case SVGA3D_CONST_TYPE_BOOL:
    7847             rc = ShaderSetPixelShaderConstantB(pContext->pShaderContext, reg, (const uint8_t *)pValues, cRegisters);
    7848             break;
    7849 
    7850         default:
    7851             AssertFailedReturn(VERR_INVALID_PARAMETER);
    7852         }
    7853         AssertRCReturn(rc, rc);
    7854         break;
    7855 
    7856     default:
    7857         AssertFailedReturn(VERR_INVALID_PARAMETER);
    7858     }
    7859 
    7860     return VINF_SUCCESS;
    7861 }
    7862 
    7863 
    7864 int vmsvga3dQueryBegin(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type)
    7865 {
    7866     AssertFailed();
    7867     return VERR_NOT_IMPLEMENTED;
    7868 }
    7869 
    7870 int vmsvga3dQueryEnd(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type, SVGAGuestPtr guestResult)
    7871 {
    7872     AssertFailed();
    7873     return VERR_NOT_IMPLEMENTED;
    7874 }
    7875 
    7876 int vmsvga3dQueryWait(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type, SVGAGuestPtr guestResult)
    7877 {
    7878     AssertFailed();
    7879     return VERR_NOT_IMPLEMENTED;
    7880 }
    7881 
     993void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface, PVMSVGAPACKPARAMS pSave);
     994void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
     995                               PCVMSVGAPACKPARAMS pSave);
     996
     997/** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
     998 * @{ */
     999/** When clear, the  context is created using the default OpenGL profile.
     1000 * When set, it's created using the alternative profile.  The latter is only
     1001 * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set.  */
     1002#define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE    RT_BIT_32(0)
     1003/** Defining the shared context.  */
     1004#define VMSVGA3D_DEF_CTX_F_SHARED_CTX       RT_BIT_32(1)
     1005/** Defining the init time context (EMT).  */
     1006#define VMSVGA3D_DEF_CTX_F_INIT             RT_BIT_32(2)
     1007/** @} */
     1008int  vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
     1009#endif /* VMSVGA3D_OPENGL */
     1010
     1011
     1012/* DevVGA-SVGA3d-shared.cpp: */
     1013uint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
     1014                                 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4);
     1015
     1016
     1017#endif
     1018
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp

    r57139 r57149  
    3838#include <iprt/uuid.h>
    3939#include <iprt/mem.h>
    40 #include <iprt/avl.h>
    41 
    42 #include <VBox/VMMDev.h>
    43 #include <VBox/VBoxVideo.h>
    44 #include <VBox/bioslogo.h>
     40
     41#include <VBox/VBoxVideo.h> /* required by DevVGA.h */
    4542
    4643/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
     
    4946#include "DevVGA-SVGA.h"
    5047#include "DevVGA-SVGA3d.h"
    51 #include "vmsvga/svga_reg.h"
    52 #include "vmsvga/svga3d_reg.h"
    53 #include "vmsvga/svga3d_shaderdefs.h"
    54 
    55 #ifdef RT_OS_WINDOWS
    56 # include <GL/gl.h>
    57 # include "vmsvga_glext/wglext.h"
    58 
    59 #elif defined(RT_OS_DARWIN)
    60 # include <OpenGL/OpenGL.h>
    61 # include <OpenGL/gl3.h>
    62 # include <OpenGL/gl3ext.h>
    63 # define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
    64 # include <OpenGL/gl.h>
    65 # include <OpenGL/glext.h>
    66 # include "DevVGA-SVGA3d-cocoa.h"
    67 /* work around conflicting definition of GLhandleARB in VMware's glext.h */
    68 //#define GL_ARB_shader_objects
    69 // HACK
    70 typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
    71 typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
    72 typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
    73 # define GL_RGBA_S3TC 0x83A2
    74 # define GL_ALPHA8_EXT 0x803c
    75 # define GL_LUMINANCE8_EXT 0x8040
    76 # define GL_LUMINANCE16_EXT 0x8042
    77 # define GL_LUMINANCE4_ALPHA4_EXT 0x8043
    78 # define GL_LUMINANCE8_ALPHA8_EXT 0x8045
    79 # define GL_INT_2_10_10_10_REV 0x8D9F
    80 #else
    81 # include <X11/Xlib.h>
    82 # include <X11/Xatom.h>
    83 # include <GL/gl.h>
    84 # include <GL/glx.h>
    85 # include <GL/glext.h>
    86 # define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103
    87 #endif
     48#include "DevVGA-SVGA3d-internal.h"
     49
    8850#ifdef DUMP_SHADER_DISASSEMBLY
    8951# include <d3dx9shader.h>
    9052#endif
    91 #include "vmsvga_glext/glext.h"
    92 
    93 #include "shaderlib/shaderlib.h"
    9453
    9554#include <stdlib.h>
    9655#include <math.h>
    97 #include <float.h>
     56#include <float.h>  /* FLT_MIN */
    9857
    9958
     
    10160*   Defined Constants And Macros                                               *
    10261*******************************************************************************/
    103 /** Experimental: Create a dedicated context for handling surfaces in, thus
    104  * avoiding orphaned surfaces after context destruction.
    105  *
    106  * This cures, for instance, an assertion on fedora 21 that happens in
    107  * vmsvga3dSurfaceStretchBlt if the login screen and the desktop has different
    108  * sizes.  The context of the login screen seems to have just been destroyed
    109  * earlier and I believe the driver/X/whoever is attemting to strech the old
    110  * screen content onto the new sized screen.
    111  *
    112  * @remarks This probably comes at a slight preformance expense, as we currently
    113  *          switches context when setting up the surface the first time.  Not sure
    114  *          if we really need to, but as this is an experiment, I'm playing it safe.
    115  */
    116 #define VMSVGA3D_OGL_WITH_SHARED_CTX
    117 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    118 /** Fake surface ID for the shared context. */
    119 # define VMSVGA3D_SHARED_CTX_ID     UINT32_C(0xffffeeee)
    120 #endif
    121 
    122 /** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
    123  * Turns out that on Linux gl.h may often define the first 2-4 OpenGL versions
    124  * worth of extensions, but missing out on a function pointer of fifteen.  This
    125  * causes headache for us when we use the function pointers below.  This hack
    126  * changes the code to call the known problematic functions directly.
    127  * The value is ((x)<<16 | (y))  where x and y are taken from the GL_VERSION_x_y.
    128  */
    129 #ifndef VBOX_VMSVGA3D_GL_HACK_LEVEL
    130 # define VBOX_VMSVGA3D_GL_HACK_LEVEL   0
    131 #endif
    132 
    13362#ifndef VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE
    13463# define VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE 1.0
     
    15988#define D3D_TO_OGL_Y_COORD_MIPLEVEL(ptrMipLevel, y_coordinate)      (ptrMipLevel->size.height - (y_coordinate))
    16089
    161 #define OPENGL_INVALID_ID               0
    162 
    16390//#define MANUAL_FLIP_SURFACE_DATA
    16491/* Enable to render the result of DrawPrimitive in a seperate window. */
    16592//#define DEBUG_GFX_WINDOW
    166 
    167 
    168 /** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
    169  * @{ */
    170 /** When clear, the  context is created using the default OpenGL profile.
    171  * When set, it's created using the alternative profile.  The latter is only
    172  * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set.  */
    173 #define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE    RT_BIT_32(0)
    174 /** Defining the shared context.  */
    175 #define VMSVGA3D_DEF_CTX_F_SHARED_CTX       RT_BIT_32(1)
    176 /** Defining the init time context (EMT).  */
    177 #define VMSVGA3D_DEF_CTX_F_INIT             RT_BIT_32(2)
    178 /** @} */
    179 
    180 
    181 #define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState)                          \
    182     do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0)
    183 
    184 /** @def VMSVGA3D_SET_CURRENT_CONTEXT
    185  * Makes sure the @a pContext is the active OpenGL context.
    186  * @parm    pState      The VMSVGA3d state.
    187  * @parm    pContext    The new context.
    188  */
    189 #ifdef RT_OS_WINDOWS
    190 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
    191     do {  \
    192         if ((pState)->idActiveContext != (pContext)->id) \
    193         { \
    194             BOOL fMakeCurrentRc = wglMakeCurrent((pContext)->hdc, (pContext)->hglrc); \
    195             Assert(fMakeCurrentRc == TRUE); \
    196             LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
    197             (pState)->idActiveContext = (pContext)->id; \
    198         } \
    199     } while (0)
    200 
    201 #elif defined(RT_OS_DARWIN)
    202 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
    203     do {  \
    204         if ((pState)->idActiveContext != (pContext)->id) \
    205         { \
    206             vmsvga3dCocoaViewMakeCurrentContext((pContext)->cocoaView, (pContext)->cocoaContext); \
    207             LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
    208             (pState)->idActiveContext = (pContext)->id; \
    209         } \
    210     } while (0)
    211 #else
    212 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
    213     do {  \
    214         if ((pState)->idActiveContext != (pContext)->id) \
    215         { \
    216             Bool fMakeCurrentRc = glXMakeCurrent((pState)->display, \
    217                                                  (pContext)->window, \
    218                                                  (pContext)->glxContext); \
    219             Assert(fMakeCurrentRc == True); \
    220             LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
    221             (pState)->idActiveContext = (pContext)->id; \
    222         } \
    223     } while (0)
    224 #endif
    225 
    226 /** @def VMSVGA3D_CLEAR_GL_ERRORS
    227  * Clears all pending OpenGL errors.
    228  *
    229  * If I understood this correctly, OpenGL maintains a bitmask internally and
    230  * glGetError gets the next bit (clearing it) from the bitmap and translates it
    231  * into a GL_XXX constant value which it then returns.  A single OpenGL call can
    232  * set more than one bit, and they stick around across calls, from what I
    233  * understand.
    234  *
    235  * So in order to be able to use glGetError to check whether a function
    236  * succeeded, we need to call glGetError until all error bits have been cleared.
    237  * This macro does that (in all types of builds).
    238  *
    239  * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
    240  */
    241 #define VMSVGA3D_CLEAR_GL_ERRORS() \
    242     do { \
    243         if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \
    244         { \
    245             uint32_t iErrorClearingLoopsLeft = 64; \
    246             while (glGetError() != GL_NO_ERROR && iErrorClearingLoopsLeft > 0) \
    247                 iErrorClearingLoopsLeft--; \
    248         } \
    249     } while (0)
    250 
    251 /** @def VMSVGA3D_GET_LAST_GL_ERROR
    252  * Gets the last OpenGL error, stores it in a_pContext->lastError and returns
    253  * it.
    254  *
    255  * @returns Same as glGetError.
    256  * @param   a_pContext  The context to store the error in.
    257  *
    258  * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    259  */
    260 #define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())
    261 
    262 /** @def VMSVGA3D_GL_SUCCESS
    263  * Checks whether VMSVGA3D_GET_LAST_GL_ERROR() return GL_NO_ERROR.
    264  *
    265  * Will call glGetError() and store the result in a_pContext->lastError.
    266  * Will predict GL_NO_ERROR outcome.
    267  *
    268  * @returns True on success, false on error.
    269  * @parm    a_pContext  The context to store the error in.
    270  *
    271  * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN
    272  */
    273 #define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))
    274 
    275 /** @def VMSVGA3D_GL_COMPLAIN
    276  * Complains about one or more OpenGL errors (first in a_pContext->lastError).
    277  *
    278  * Strict builds will trigger an assertion, while other builds will put the
    279  * first few occurences in the release log.
    280  *
    281  * All GL errors will be cleared after invocation.  Assumes lastError
    282  * is an error, will not check for GL_NO_ERROR.
    283  *
    284  * @param   a_pState        The 3D state structure.
    285  * @param   a_pContext      The context that holds the first error.
    286  * @param   a_LogRelDetails Argument list for LogRel or similar that describes
    287  *                          the operation in greater detail.
    288  *
    289  * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
    290  */
    291 #ifdef VBOX_STRICT
    292 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
    293     do { \
    294         AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \
    295                   ("idActiveContext=%#x id=%x\n", (a_pState)->idActiveContext, (a_pContext)->id)); \
    296         RTAssertMsg2Weak a_LogRelDetails; \
    297         GLenum iNextError; \
    298         while ((iNextError = glGetError()) != GL_NO_ERROR) \
    299             RTAssertMsg2Weak("next error: %#x\n", iNextError); \
    300         AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \
    301     } while (0)
    302 #else
    303 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
    304     do { \
    305         LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id)); \
    306         GLenum iNextError; \
    307         while ((iNextError = glGetError()) != GL_NO_ERROR) \
    308             LogRelMax(32, (" - also error %#x ", iNextError)); \
    309         LogRelMax(32, a_LogRelDetails); \
    310     } while (0)
    311 #endif
    312 
    313 /** @def VMSVGA3D_GL_GET_AND_COMPLAIN
    314  * Combination of VMSVGA3D_GET_GL_ERROR and VMSVGA3D_GL_COMPLAIN, assuming that
    315  * there is a pending error.
    316  *
    317  * @param   a_pState    The 3D state structure.
    318  * @param   a_pContext  The context that holds the first error.
    319  * @param   a_LogRelDetails Argument list for LogRel or similar that describes
    320  *                          the operation in greater detail.
    321  *
    322  * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    323  */
    324 #define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
    325     do { \
    326         VMSVGA3D_GET_GL_ERROR(a_pContext); \
    327         VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
    328     } while (0)
    329 
    330 /** @def VMSVGA3D_GL_ASSERT_SUCCESS
    331  * Asserts that VMSVGA3D_GL_IS_SUCCESS is true, complains if not.
    332  *
    333  * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
    334  * logging in non-strict builds.
    335  *
    336  * @param   a_pState    The 3D state structure.
    337  * @param   a_pContext  The context that holds the first error.
    338  * @param   a_LogRelDetails Argument list for LogRel or similar that describes
    339  *                          the operation in greater detail.
    340  *
    341  * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    342  */
    343 #define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \
    344     if (VMSVGA3D_GL_IS_SUCCESS(a_pContext)) \
    345     { /* likely */ } \
    346     else do { \
    347         VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
    348     } while (0)
    349 
    350 /** @def VMSVGA3D_ASSERT_GL_CALL_EX
    351  * Executes the specified OpenGL API call and asserts that it succeeded, variant
    352  * with extra logging flexibility.
    353  *
    354  * ASSUMES no GL errors pending prior to invocation - caller should use
    355  * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
    356  *
    357  * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
    358  * logging in non-strict builds.
    359  *
    360  * @param   a_GlCall    Expression making an OpenGL call.
    361  * @param   a_pState    The 3D state structure.
    362  * @param   a_pContext  The context that holds the first error.
    363  * @param   a_LogRelDetails Argument list for LogRel or similar that describes
    364  *                          the operation in greater detail.
    365  *
    366  * @sa VMSVGA3D_ASSERT_GL_CALL, VMSVGA3D_GL_ASSERT_SUCCESS,
    367  *     VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    368  */
    369 #define VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, a_LogRelDetails) \
    370     do { \
    371         (a_GlCall); \
    372         VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails); \
    373     } while (0)
    374 
    375 /** @def VMSVGA3D_ASSERT_GL_CALL
    376  * Executes the specified OpenGL API call and asserts that it succeeded.
    377  *
    378  * ASSUMES no GL errors pending prior to invocation - caller should use
    379  * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
    380  *
    381  * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
    382  * logging in non-strict builds.
    383  *
    384  * @param   a_GlCall    Expression making an OpenGL call.
    385  * @param   a_pState    The 3D state structure.
    386  * @param   a_pContext  The context that holds the first error.
    387  *
    388  * @sa VMSVGA3D_ASSERT_GL_CALL_EX, VMSVGA3D_GL_ASSERT_SUCCESS,
    389  *     VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
    390  */
    391 #define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \
    392     VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, ("%s\n", #a_GlCall))
    393 
    394 
    395 /** @def VMSVGA3D_CHECK_LAST_ERROR
    396  * Checks that the last OpenGL error code indicates success.
    397  *
    398  * Will assert and return VERR_INTERNAL_ERROR in strict builds, in other
    399  * builds it will do nothing and is a NOOP.
    400  *
    401  * @parm    pState      The VMSVGA3d state.
    402  * @parm    pContext    The context.
    403  *
    404  * @todo    Replace with proper error handling, it's crazy to return
    405  *          VERR_INTERNAL_ERROR in strict builds and just barge on ahead in
    406  *          release builds.
    407  */
    408 #ifdef VBOX_STRICT
    409 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do {                   \
    410     Assert((pState)->idActiveContext == (pContext)->id);                    \
    411     (pContext)->lastError = glGetError();                                   \
    412     AssertMsgReturn((pContext)->lastError == GL_NO_ERROR, \
    413                     ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError), \
    414                     VERR_INTERNAL_ERROR); \
    415     } while (0)
    416 #else
    417 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext)                        do { } while (0)
    418 #endif
    419 
    420 /** @def VMSVGA3D_CHECK_LAST_ERROR_WARN
    421  * Checks that the last OpenGL error code indicates success.
    422  *
    423  * Will assert in strict builds, otherwise it's a NOOP.
    424  *
    425  * @parm    pState      The VMSVGA3d state.
    426  * @parm    pContext    The new context.
    427  */
    428 #ifdef VBOX_STRICT
    429 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do {              \
    430     Assert((pState)->idActiveContext == (pContext)->id);                    \
    431     (pContext)->lastError = glGetError();                                   \
    432     AssertMsg((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError)); \
    433     } while (0)
    434 #else
    435 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext)                   do { } while (0)
    436 #endif
    43793
    43894
     
    481137
    482138/*******************************************************************************
    483 *   Structures, Typedefs and Globals.                                          *
    484 *******************************************************************************/
    485 typedef struct
    486 {
    487     SVGA3dSize              size;
    488     uint32_t                cbSurface;
    489     uint32_t                cbSurfacePitch;
    490     void                   *pSurfaceData;
    491     bool                    fDirty;
    492 } VMSVGA3DMIPMAPLEVEL, *PVMSVGA3DMIPMAPLEVEL;
    493 
    494 /**
    495  * SSM descriptor table for the VMSVGA3DMIPMAPLEVEL structure.
    496  */
    497 static SSMFIELD const g_aVMSVGA3DMIPMAPLEVELFields[] =
    498 {
    499     SSMFIELD_ENTRY(                 VMSVGA3DMIPMAPLEVEL, size),
    500     SSMFIELD_ENTRY(                 VMSVGA3DMIPMAPLEVEL, cbSurface),
    501     SSMFIELD_ENTRY(                 VMSVGA3DMIPMAPLEVEL, cbSurfacePitch),
    502     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DMIPMAPLEVEL, pSurfaceData),
    503     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DMIPMAPLEVEL, fDirty),
    504     SSMFIELD_ENTRY_TERM()
    505 };
    506 
    507 typedef struct
    508 {
    509     uint32_t                id;
    510 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    511     uint32_t                idWeakContextAssociation;
    512 #else
    513     uint32_t                idAssociatedContext;
    514 #endif
    515     uint32_t                flags;
    516     SVGA3dSurfaceFormat     format;
    517     GLint                   internalFormatGL;
    518     GLint                   formatGL;
    519     GLint                   typeGL;
    520     union
    521     {
    522         GLuint              texture;
    523         GLuint              buffer;
    524         GLuint              renderbuffer;
    525     } oglId;
    526     SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
    527     uint32_t                cFaces;
    528     PVMSVGA3DMIPMAPLEVEL    pMipmapLevels;
    529     uint32_t                multiSampleCount;
    530     SVGA3dTextureFilter     autogenFilter;
    531     uint32_t                cbBlock;        /* block/pixel size in bytes */
    532     /* Dirty state; surface was manually updated. */
    533     bool                    fDirty;
    534 } VMSVGA3DSURFACE, *PVMSVGA3DSURFACE;
    535 
    536 /**
    537  * SSM descriptor table for the VMSVGA3DSURFACE structure.
    538  */
    539 static SSMFIELD const g_aVMSVGA3DSURFACEFields[] =
    540 {
    541     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, id),
    542 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    543     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idWeakContextAssociation),
    544 #else
    545     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idAssociatedContext),
    546 #endif
    547     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, flags),
    548     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format),
    549     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, internalFormatGL),
    550     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, formatGL),
    551     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, typeGL),
    552     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, id),
    553     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, faces),
    554     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cFaces),
    555     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, pMipmapLevels),
    556     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, multiSampleCount),
    557     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, autogenFilter),
    558     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cbBlock),
    559     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fDirty),
    560     SSMFIELD_ENTRY_TERM()
    561 };
    562 
    563 typedef struct
    564 {
    565     uint32_t                        id;
    566     uint32_t                        cid;
    567     SVGA3dShaderType                type;
    568     uint32_t                        cbData;
    569     void                           *pShaderProgram;
    570     union
    571     {
    572         void                       *pVertexShader;
    573         void                       *pPixelShader;
    574     } u;
    575 } VMSVGA3DSHADER, *PVMSVGA3DSHADER;
    576 
    577 /**
    578  * SSM descriptor table for the VMSVGA3DSHADER structure.
    579  */
    580 static SSMFIELD const g_aVMSVGA3DSHADERFields[] =
    581 {
    582     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, id),
    583     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, cid),
    584     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, type),
    585     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, cbData),
    586     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, pShaderProgram),
    587     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, u.pVertexShader),
    588     SSMFIELD_ENTRY_TERM()
    589 };
    590 
    591 typedef struct
    592 {
    593     bool        fValid;
    594     float       matrix[16];
    595 } VMSVGATRANSFORMSTATE, *PVMSVGATRANSFORMSTATE;
    596 
    597 typedef struct
    598 {
    599     bool            fValid;
    600     SVGA3dMaterial  material;
    601 } VMSVGAMATERIALSTATE, *PVMSVGAMATERIALSTATE;
    602 
    603 typedef struct
    604 {
    605     bool            fValid;
    606     float           plane[4];
    607 } VMSVGACLIPPLANESTATE, *PVMSVGACLIPPLANESTATE;
    608 
    609 typedef struct
    610 {
    611     bool            fEnabled;
    612     bool            fValidData;
    613     SVGA3dLightData data;
    614 } VMSVGALIGHTSTATE, *PVMSVGALIGHTSTATE;
    615 
    616 typedef struct
    617 {
    618     bool                    fValid;
    619     SVGA3dShaderConstType   ctype;
    620     uint32_t                value[4];
    621 } VMSVGASHADERCONST, *PVMSVGASHADERCONST;
    622 
    623 /**
    624  * SSM descriptor table for the VMSVGASHADERCONST structure.
    625  */
    626 static SSMFIELD const g_aVMSVGASHADERCONSTFields[] =
    627 {
    628     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, fValid),
    629     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, ctype),
    630     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, value),
    631     SSMFIELD_ENTRY_TERM()
    632 };
    633 
    634 #define VMSVGA3D_UPDATE_SCISSORRECT     RT_BIT(0)
    635 #define VMSVGA3D_UPDATE_ZRANGE          RT_BIT(1)
    636 #define VMSVGA3D_UPDATE_VIEWPORT        RT_BIT(2)
    637 #define VMSVGA3D_UPDATE_VERTEXSHADER    RT_BIT(3)
    638 #define VMSVGA3D_UPDATE_PIXELSHADER     RT_BIT(4)
    639 #define VMSVGA3D_UPDATE_TRANSFORM       RT_BIT(5)
    640 #define VMSVGA3D_UPDATE_MATERIAL        RT_BIT(6)
    641 
    642 typedef struct VMSVGA3DCONTEXT
    643 {
    644     uint32_t                id;
    645 #ifdef RT_OS_WINDOWS
    646     /* Device context of the context window. */
    647     HDC                     hdc;
    648     /* OpenGL rendering context handle. */
    649     HGLRC                   hglrc;
    650     /* Device context window handle. */
    651     HWND                    hwnd;
    652 #elif defined(RT_OS_DARWIN)
    653     /* OpenGL rendering context */
    654     NativeNSOpenGLContextRef cocoaContext;
    655     NativeNSViewRef          cocoaView;
    656     bool                    fOtherProfile;
    657 #else
    658     /** XGL rendering context handle */
    659     GLXContext              glxContext;
    660     /** Device context window handle */
    661     Window                  window;
    662     /** flag whether the window is mapped (=visible) */
    663     bool                    fMapped;
    664 #endif
    665     /* Framebuffer object associated with this context. */
    666     GLuint                  idFramebuffer;
    667     /* Read and draw framebuffer objects for various operations. */
    668     GLuint                  idReadFramebuffer;
    669     GLuint                  idDrawFramebuffer;
    670     /* Last GL error recorded. */
    671     GLenum                  lastError;
    672 
    673     /* Current active render target (if any) */
    674     uint32_t                sidRenderTarget;
    675     /* Current selected texture surfaces (if any) */
    676     uint32_t                aSidActiveTexture[SVGA3D_MAX_TEXTURE_STAGE];
    677     /* Per context pixel and vertex shaders. */
    678     uint32_t                cPixelShaders;
    679     PVMSVGA3DSHADER         paPixelShader;
    680     uint32_t                cVertexShaders;
    681     PVMSVGA3DSHADER         paVertexShader;
    682     void                   *pShaderContext;
    683     /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
    684     struct
    685     {
    686         uint32_t                u32UpdateFlags;
    687 
    688         SVGA3dRenderState       aRenderState[SVGA3D_RS_MAX];
    689         SVGA3dTextureState      aTextureState[SVGA3D_MAX_TEXTURE_STAGE][SVGA3D_TS_MAX];
    690         VMSVGATRANSFORMSTATE    aTransformState[SVGA3D_TRANSFORM_MAX];
    691         VMSVGAMATERIALSTATE     aMaterial[SVGA3D_FACE_MAX];
    692         VMSVGACLIPPLANESTATE    aClipPlane[SVGA3D_CLIPPLANE_MAX];
    693         VMSVGALIGHTSTATE        aLightData[SVGA3D_MAX_LIGHTS];
    694 
    695         uint32_t                aRenderTargets[SVGA3D_RT_MAX];
    696         SVGA3dRect              RectScissor;
    697         SVGA3dRect              RectViewPort;
    698         SVGA3dZRange            zRange;
    699         uint32_t                shidPixel;
    700         uint32_t                shidVertex;
    701 
    702         uint32_t                cPixelShaderConst;
    703         PVMSVGASHADERCONST      paPixelShaderConst;
    704         uint32_t                cVertexShaderConst;
    705         PVMSVGASHADERCONST      paVertexShaderConst;
    706     } state;
    707 } VMSVGA3DCONTEXT, *PVMSVGA3DCONTEXT;
    708 
    709 /**
    710  * SSM descriptor table for the VMSVGA3DCONTEXT structure.
    711  */
    712 static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
    713 {
    714     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, id),
    715 #ifdef RT_OS_WINDOWS
    716     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hdc),
    717     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hglrc),
    718     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, hwnd),
    719 #endif
    720 
    721     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, idFramebuffer),
    722     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, idReadFramebuffer),
    723     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, idDrawFramebuffer),
    724     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, lastError),
    725 
    726     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, sidRenderTarget),
    727     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, aSidActiveTexture),
    728     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, cPixelShaders),
    729     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, paPixelShader),
    730     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, cVertexShaders),
    731     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, paVertexShader),
    732     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, pShaderContext),
    733     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.u32UpdateFlags),
    734 
    735     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aRenderState),
    736     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aTextureState),
    737     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aTransformState),
    738     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aMaterial),
    739     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aClipPlane),
    740     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aLightData),
    741 
    742     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aRenderTargets),
    743     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.RectScissor),
    744     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.RectViewPort),
    745     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.zRange),
    746     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.shidPixel),
    747     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.shidVertex),
    748     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.cPixelShaderConst),
    749     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, state.paPixelShaderConst),
    750     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.cVertexShaderConst),
    751     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, state.paVertexShaderConst),
    752     SSMFIELD_ENTRY_TERM()
    753 };
    754 
    755 /**
    756  * VMSVGA3d state data.
    757  *
    758  * Allocated on the heap and pointed to by VMSVGAState::p3dState.
    759  */
    760 typedef struct VMSVGA3DSTATE
    761 {
    762 #ifdef RT_OS_WINDOWS
    763     /** Window Thread. */
    764     R3PTRTYPE(RTTHREAD)     pWindowThread;
    765     DWORD                   idWindowThread;
    766     HMODULE                 hInstance;
    767     /** Window request semaphore. */
    768     RTSEMEVENT              WndRequestSem;
    769 #elif defined(RT_OS_LINUX)
    770     /* The X display */
    771     Display                 *display;
    772     R3PTRTYPE(RTTHREAD)    pWindowThread;
    773     bool                    bTerminate;
    774 #endif
    775 
    776     float                   fGLVersion;
    777     /* Current active context. */
    778     uint32_t                idActiveContext;
    779 
    780     struct
    781     {
    782         PFNGLISRENDERBUFFERPROC                         glIsRenderbuffer;
    783         PFNGLBINDRENDERBUFFERPROC                       glBindRenderbuffer;
    784         PFNGLDELETERENDERBUFFERSPROC                    glDeleteRenderbuffers;
    785         PFNGLGENRENDERBUFFERSPROC                       glGenRenderbuffers;
    786         PFNGLRENDERBUFFERSTORAGEPROC                    glRenderbufferStorage;
    787         PFNGLGETRENDERBUFFERPARAMETERIVPROC             glGetRenderbufferParameteriv;
    788         PFNGLISFRAMEBUFFERPROC                          glIsFramebuffer;
    789         PFNGLBINDFRAMEBUFFERPROC                        glBindFramebuffer;
    790         PFNGLDELETEFRAMEBUFFERSPROC                     glDeleteFramebuffers;
    791         PFNGLGENFRAMEBUFFERSPROC                        glGenFramebuffers;
    792         PFNGLCHECKFRAMEBUFFERSTATUSPROC                 glCheckFramebufferStatus;
    793         PFNGLFRAMEBUFFERTEXTURE1DPROC                   glFramebufferTexture1D;
    794         PFNGLFRAMEBUFFERTEXTURE2DPROC                   glFramebufferTexture2D;
    795         PFNGLFRAMEBUFFERTEXTURE3DPROC                   glFramebufferTexture3D;
    796         PFNGLFRAMEBUFFERRENDERBUFFERPROC                glFramebufferRenderbuffer;
    797         PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC    glGetFramebufferAttachmentParameteriv;
    798         PFNGLGENERATEMIPMAPPROC                         glGenerateMipmap;
    799         PFNGLBLITFRAMEBUFFERPROC                        glBlitFramebuffer;
    800         PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC         glRenderbufferStorageMultisample;
    801         PFNGLFRAMEBUFFERTEXTURELAYERPROC                glFramebufferTextureLayer;
    802         PFNGLPOINTPARAMETERFPROC                        glPointParameterf;
    803 #if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
    804         PFNGLBLENDCOLORPROC                             glBlendColor;
    805         PFNGLBLENDEQUATIONPROC                          glBlendEquation;
    806 #endif
    807         PFNGLBLENDEQUATIONSEPARATEPROC                  glBlendEquationSeparate;
    808         PFNGLBLENDFUNCSEPARATEPROC                      glBlendFuncSeparate;
    809         PFNGLSTENCILOPSEPARATEPROC                      glStencilOpSeparate;
    810         PFNGLSTENCILFUNCSEPARATEPROC                    glStencilFuncSeparate;
    811         PFNGLBINDBUFFERPROC                             glBindBuffer;
    812         PFNGLDELETEBUFFERSPROC                          glDeleteBuffers;
    813         PFNGLGENBUFFERSPROC                             glGenBuffers;
    814         PFNGLBUFFERDATAPROC                             glBufferData;
    815         PFNGLMAPBUFFERPROC                              glMapBuffer;
    816         PFNGLUNMAPBUFFERPROC                            glUnmapBuffer;
    817         PFNGLENABLEVERTEXATTRIBARRAYPROC                glEnableVertexAttribArray;
    818         PFNGLDISABLEVERTEXATTRIBARRAYPROC               glDisableVertexAttribArray;
    819         PFNGLVERTEXATTRIBPOINTERPROC                    glVertexAttribPointer;
    820         PFNGLFOGCOORDPOINTERPROC                        glFogCoordPointer;
    821         PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC        glDrawElementsInstancedBaseVertex;
    822         PFNGLDRAWELEMENTSBASEVERTEXPROC                 glDrawElementsBaseVertex;
    823         PFNGLACTIVETEXTUREPROC                          glActiveTexture;
    824 #if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
    825         PFNGLCLIENTACTIVETEXTUREPROC                    glClientActiveTexture;
    826 #endif
    827         PFNGLGETPROGRAMIVARBPROC                        glGetProgramivARB;
    828         PFNGLPROVOKINGVERTEXPROC                        glProvokingVertex;
    829         bool                                            fEXT_stencil_two_side;
    830     } ext;
    831 
    832     struct
    833     {
    834         GLint                           maxActiveLights;
    835         GLint                           maxTextureBufferSize;
    836         GLint                           maxTextures;
    837         GLint                           maxClipDistances;
    838         GLint                           maxColorAttachments;
    839         GLint                           maxRectangleTextureSize;
    840         GLint                           maxTextureAnisotropy;
    841         GLint                           maxVertexShaderInstructions;
    842         GLint                           maxFragmentShaderInstructions;
    843         GLint                           maxVertexShaderTemps;
    844         GLint                           maxFragmentShaderTemps;
    845         GLfloat                         flPointSize[2];
    846         SVGA3dPixelShaderVersion        fragmentShaderVersion;
    847         SVGA3dVertexShaderVersion       vertexShaderVersion;
    848         bool                            fS3TCSupported;
    849     } caps;
    850 
    851     uint32_t                cContexts;
    852     PVMSVGA3DCONTEXT       *papContexts;
    853     uint32_t                cSurfaces;
    854     PVMSVGA3DSURFACE       *papSurfaces;
    855 #ifdef DEBUG_GFX_WINDOW_TEST_CONTEXT
    856     uint32_t                idTestContext;
    857 #endif
    858     /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
    859      * Free with RTStrFree. */
    860     R3PTRTYPE(char *)       pszExtensions;
    861 
    862     /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
    863      * Free with RTStrFree.
    864      *
    865      * This is used to detect shader model version since some implementations
    866      * (darwin) hides extensions that have made it into core and probably a
    867      * bunch of others when using a OpenGL core profile instead of a legacy one */
    868     R3PTRTYPE(char *)       pszOtherExtensions;
    869     /** The version of the other GL profile. */
    870     float                   fOtherGLVersion;
    871 
    872     /** Shader talk back interface. */
    873     VBOXVMSVGASHADERIF      ShaderIf;
    874 
    875 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    876     /** The shared context. */
    877     VMSVGA3DCONTEXT         SharedCtx;
    878 #endif
    879 } VMSVGA3DSTATE;
    880 
    881 /**
    882  * SSM descriptor table for the VMSVGA3DSTATE structure.
    883  */
    884 static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
    885 {
    886 #ifdef RT_OS_WINDOWS
    887     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, pWindowThread),
    888     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, idWindowThread),
    889     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, hInstance),
    890     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, WndRequestSem),
    891 #elif defined(RT_OS_LINUX)
    892     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, display),
    893     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, pWindowThread),
    894     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, bTerminate),
    895 #endif
    896     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, fGLVersion),
    897     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, idActiveContext),
    898 
    899     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, ext),
    900     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, caps),
    901 
    902     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cContexts),
    903     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papContexts),
    904     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cSurfaces),
    905     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papSurfaces),
    906     SSMFIELD_ENTRY_TERM()
    907 };
    908 
    909 
    910 /** Save and setup everything. */
    911 #define VMSVGA3D_PARANOID_TEXTURE_PACKING
    912 
    913 /**
    914  * Saved texture packing parameters (shared by both pack and unpack).
    915  */
    916 typedef struct VMSVGAPACKPARAMS
    917 {
    918     GLint       iAlignment;
    919     GLint       cxRow;
    920 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
    921     GLint       cyImage;
    922     GLboolean   fSwapBytes;
    923     GLboolean   fLsbFirst;
    924     GLint       cSkipRows;
    925     GLint       cSkipPixels;
    926     GLint       cSkipImages;
    927 #endif
    928 } VMSVGAPACKPARAMS;
    929 /** Pointer to saved texture packing parameters. */
    930 typedef VMSVGAPACKPARAMS *PVMSVGAPACKPARAMS;
    931 /** Pointer to const saved texture packing parameters. */
    932 typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
    933 
    934 
    935 /*******************************************************************************
    936139*   Global Variables                                                           *
    937140*******************************************************************************/
     
    959162*******************************************************************************/
    960163static int  vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
    961 static int  vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
    962164static int  vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid);
    963165static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha);
    964 static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    965                                   PVMSVGAPACKPARAMS pSave);
    966 static void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    967                                       PCVMSVGAPACKPARAMS pSave);
    968166
    969167/* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */
     
    18861084}
    18871085
    1888 /* Shared functions that depend on private structure definitions. */
    1889 #define VMSVGA3D_OPENGL
    1890 #include "DevVGA-SVGA3d-shared.h"
    18911086
    18921087/**
     
    32862481 * @param   pSave               Where to save stuff.
    32872482 */
    3288 static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    3289                                   PVMSVGAPACKPARAMS pSave)
     2483void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface, PVMSVGAPACKPARAMS pSave)
    32902484{
    32912485    /*
     
    33612555 * @param   pSave               Where stuff was saved.
    33622556 */
    3363 static void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
    3364                                       PCVMSVGAPACKPARAMS pSave)
     2557void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
     2558                               PCVMSVGAPACKPARAMS pSave)
    33652559{
    33662560    NOREF(pSurface);
     
    42873481 * @param   fFlags          VMSVGA3D_DEF_CTX_F_XXX.
    42883482 */
    4289 static int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags)
     3483int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags)
    42903484{
    42913485    int                     rc;
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp

    r57148 r57149  
    11/* $Id$ */
    22/** @file
    3  * DevVMWare - VMWare SVGA device, shared part.
    4  *
    5  * @remarks This is code that's very similar on both for OpenGL and D3D
    6  *          backends, so instead of moving backend specific structures
    7  *          into header files with #ifdefs and stuff, we just include
    8  *          the code into the backend implementation source file.
     3 * DevSVGA3d - VMWare SVGA device, 3D parts - Saved state and assocated stuff.
    94 */
    105
     
    2116 */
    2217
    23 #ifndef ___DevVGA_SVGA3d_shared_h___
    24 #define ___DevVGA_SVGA3d_shared_h___
    25 
    26 /**
    27  * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.
    28  *
    29  * This will allocate heap buffers if necessary, thus increasing the memory
    30  * usage of the process.
    31  *
    32  * @todo Would be interesting to share this code with the saved state code.
    33  *
    34  * @returns VBox status code.
    35  * @param   pState              The 3D state structure.
    36  * @param   pSurface            The surface to refresh the heap buffers for.
    37  */
    38 static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
    39 {
    40     /*
    41      * Currently we've got trouble retreving bit for DEPTHSTENCIL
    42      * surfaces both for OpenGL and D3D, so skip these here (don't
    43      * wast memory on them).
    44      */
    45     uint32_t const fSwitchFlags = pSurface->flags
    46                                 & (  SVGA3D_SURFACE_HINT_INDEXBUFFER  | SVGA3D_SURFACE_HINT_VERTEXBUFFER
    47                                    | SVGA3D_SURFACE_HINT_TEXTURE      | SVGA3D_SURFACE_HINT_RENDERTARGET
    48                                    | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);
    49     if (   fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL
    50         && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))
    51     {
    52 
    53 #ifdef VMSVGA3D_OPENGL
    54         /*
    55          * Change OpenGL context to the one the surface is associated with.
    56          */
    57 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
    58         PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
    59         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    60 # else
    61         /** @todo stricter checks for associated context */
    62         uint32_t cid = pSurface->idAssociatedContext;
    63         if (    cid >= pState->cContexts
    64             ||  pState->papContexts[cid]->id != cid)
    65         {
    66             Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    67             AssertFailedReturn(VERR_INVALID_PARAMETER);
    68         }
    69         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    70         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    71 # endif
    72 #endif
    73 
    74         /*
    75          * Work thru each mipmap level for each face.
    76          */
    77         for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    78         {
    79             Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
    80             PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
    81             for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
    82             {
    83 #ifdef VMSVGA3D_DIRECT3D
    84                 if (pSurface->u.pSurface)
    85 #else
    86                 if (pSurface->oglId.texture != OPENGL_INVALID_ID)
    87 #endif
    88                 {
    89                     Assert(pMipmapLevel->cbSurface);
    90                     Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */
    91 
    92                     /*
    93                      * Make sure we've got surface memory buffer.
    94                      */
    95                     uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;
    96                     if (!pbDst)
    97                     {
    98                         pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);
    99                         AssertReturn(pbDst, VERR_NO_MEMORY);
    100                     }
    101 
    102 #ifdef VMSVGA3D_DIRECT3D
    103                     /*
    104                      * D3D specifics.
    105                      */
    106                     HRESULT  hr;
    107                     switch (fSwitchFlags)
    108                     {
    109                         case SVGA3D_SURFACE_HINT_TEXTURE:
    110                         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    111                         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    112                         {
    113                             /*
    114                              * Lock the buffer and make it accessible to memcpy.
    115                              */
    116                             D3DLOCKED_RECT LockedRect;
    117                             if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
    118                             {
    119                                 if (pSurface->bounce.pTexture)
    120                                 {
    121                                     if (    !pSurface->fDirty
    122                                         &&  fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)
    123                                         &&  i == 0 /* only the first time */)
    124                                     {
    125                                         /** @todo stricter checks for associated context */
    126                                         uint32_t cid = pSurface->idAssociatedContext;
    127                                         if (   cid >= pState->cContexts
    128                                             || pState->papContexts[cid]->id != cid)
    129                                         {
    130                                             Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
    131                                             AssertFailedReturn(VERR_INVALID_PARAMETER);
    132                                         }
    133                                         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    134 
    135                                         IDirect3DSurface9 *pDst = NULL;
    136                                         hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);
    137                                         AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    138 
    139                                         IDirect3DSurface9 *pSrc = NULL;
    140                                         hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
    141                                         AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    142 
    143                                         hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);
    144                                         AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    145 
    146                                         pSrc->Release();
    147                                         pDst->Release();
    148                                     }
    149 
    150                                     hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
    151                                                                              &LockedRect,
    152                                                                              NULL,
    153                                                                              D3DLOCK_READONLY);
    154                                 }
    155                                 else
    156                                     hr = pSurface->u.pTexture->LockRect(i, /* texture level */
    157                                                                         &LockedRect,
    158                                                                         NULL,
    159                                                                         D3DLOCK_READONLY);
    160                             }
    161                             else
    162                                 hr = pSurface->u.pSurface->LockRect(&LockedRect,
    163                                                                     NULL,
    164                                                                     D3DLOCK_READONLY);
    165                             AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    166 
    167                             /*
    168                              * Copy the data.  Take care in case the pitch differs.
    169                              */
    170                             if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)
    171                                 memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);
    172                             else
    173                                 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
    174                                     memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,
    175                                            (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,
    176                                            pMipmapLevel->cbSurfacePitch);
    177 
    178                             /*
    179                              * Release the buffer.
    180                              */
    181                             if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
    182                             {
    183                                 if (pSurface->bounce.pTexture)
    184                                 {
    185                                     hr = pSurface->bounce.pTexture->UnlockRect(i);
    186                                     AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    187                                 }
    188                                 else
    189                                     hr = pSurface->u.pTexture->UnlockRect(i);
    190                             }
    191                             else
    192                                 hr = pSurface->u.pSurface->UnlockRect();
    193                             AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
    194                             break;
    195                         }
    196 
    197                         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    198                         {
    199                             void *pvD3DData = NULL;
    200                             hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
    201                             AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);
    202 
    203                             memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
    204 
    205                             hr = pSurface->u.pVertexBuffer->Unlock();
    206                             AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));
    207                             break;
    208                         }
    209 
    210                         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    211                         {
    212                             void *pvD3DData = NULL;
    213                             hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
    214                             AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);
    215 
    216                             memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
    217 
    218                             hr = pSurface->u.pIndexBuffer->Unlock();
    219                             AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));
    220                             break;
    221                         }
    222 
    223                         default:
    224                             AssertMsgFailed(("%#x\n", fSwitchFlags));
    225                     }
    226 
    227 #elif defined(VMSVGA3D_OPENGL)
    228                     /*
    229                      * OpenGL specifics.
    230                      */
    231                     switch (fSwitchFlags)
    232                     {
    233                         case SVGA3D_SURFACE_HINT_TEXTURE:
    234                         case SVGA3D_SURFACE_HINT_RENDERTARGET:
    235                         case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
    236                         {
    237                             GLint activeTexture;
    238                             glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
    239                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    240 
    241                             glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
    242                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    243 
    244                             /* Set row length and alignment of the output data. */
    245                             VMSVGAPACKPARAMS SavedParams;
    246                             vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
    247 
    248                             glGetTexImage(GL_TEXTURE_2D,
    249                                           i,
    250                                           pSurface->formatGL,
    251                                           pSurface->typeGL,
    252                                           pbDst);
    253                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    254 
    255                             vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
    256 
    257                             /* Restore the old active texture. */
    258                             glBindTexture(GL_TEXTURE_2D, activeTexture);
    259                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    260                             break;
    261                         }
    262 
    263                         case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
    264                         case SVGA3D_SURFACE_HINT_INDEXBUFFER:
    265                         {
    266                             pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
    267                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    268 
    269                             void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
    270                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    271                             if (RT_VALID_PTR(pvSrc))
    272                                 memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);
    273                             else
    274                                 AssertPtr(pvSrc);
    275 
    276                             pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
    277                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    278 
    279                             pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
    280                             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    281                             break;
    282                         }
    283 
    284                         default:
    285                             AssertMsgFailed(("%#x\n", fSwitchFlags));
    286                     }
    287 #else
    288 # error "misconfigured"
    289 #endif
    290                 }
    291                 /* else: There is no data in hardware yet, so whatever we got is already current. */
    292             }
    293         }
    294     }
    295 
    296     return VINF_SUCCESS;
    297 }
    298 
    299 
    300 /**
    301  * Updates the heap buffers for all surfaces or one specific one.
    302  *
    303  * @param   pThis               The VGA device instance data.
    304  * @param   sid                 The surface ID, UINT32_MAX if all.
    305  * @thread  VMSVGAFIFO
    306  */
    307 void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)
    308 {
    309     PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    310     AssertReturnVoid(pState);
    311 
    312     if (sid == UINT32_MAX)
    313     {
    314         uint32_t cSurfaces = pState->cSurfaces;
    315         for (sid = 0; sid < cSurfaces; sid++)
    316         {
    317             PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    318             if (pSurface && pSurface->id == sid)
    319                 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
    320         }
    321     }
    322     else if (sid < pState->cSurfaces)
    323     {
    324         PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    325         if (pSurface && pSurface->id == sid)
    326             vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
    327     }
    328 }
     18
     19/*******************************************************************************
     20*   Header Files                                                               *
     21*******************************************************************************/
     22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
     23#include <VBox/vmm/pdmdev.h>
     24#include <VBox/err.h>
     25#include <VBox/log.h>
     26
     27#include <iprt/assert.h>
     28#include <iprt/mem.h>
     29
     30#include <VBox/vmm/pgm.h> /* required by DevVGA.h */
     31#include <VBox/VBoxVideo.h> /* required by DevVGA.h */
     32
     33/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
     34#include "DevVGA.h"
     35
     36#include "DevVGA-SVGA.h"
     37#include "DevVGA-SVGA3d.h"
     38#define VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
     39#include "DevVGA-SVGA3d-internal.h"
     40
    32941
    33042
     
    1147859}
    1148860
    1149 static uint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
     861uint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
    1150862{
    1151863    /* Choose a sane upper limit. */
     
    1193905}
    1194906
    1195 
    1196 
    1197 static const char * const g_apszTransformTypes[] =
    1198 {
    1199     "SVGA3D_TRANSFORM_INVALID",
    1200     "SVGA3D_TRANSFORM_WORLD",
    1201     "SVGA3D_TRANSFORM_VIEW",
    1202     "SVGA3D_TRANSFORM_PROJECTION",
    1203     "SVGA3D_TRANSFORM_TEXTURE0",
    1204     "SVGA3D_TRANSFORM_TEXTURE1",
    1205     "SVGA3D_TRANSFORM_TEXTURE2",
    1206     "SVGA3D_TRANSFORM_TEXTURE3",
    1207     "SVGA3D_TRANSFORM_TEXTURE4",
    1208     "SVGA3D_TRANSFORM_TEXTURE5",
    1209     "SVGA3D_TRANSFORM_TEXTURE6",
    1210     "SVGA3D_TRANSFORM_TEXTURE7",
    1211     "SVGA3D_TRANSFORM_WORLD1",
    1212     "SVGA3D_TRANSFORM_WORLD2",
    1213     "SVGA3D_TRANSFORM_WORLD3",
    1214 };
    1215 
    1216 static const char * const g_apszFaces[] =
    1217 {
    1218     "SVGA3D_FACE_INVALID",
    1219     "SVGA3D_FACE_NONE",
    1220     "SVGA3D_FACE_FRONT",
    1221     "SVGA3D_FACE_BACK",
    1222     "SVGA3D_FACE_FRONT_BACK",
    1223 };
    1224 
    1225 static const char * const g_apszLightTypes[] =
    1226 {
    1227     "SVGA3D_LIGHTTYPE_INVALID",
    1228     "SVGA3D_LIGHTTYPE_POINT",
    1229     "SVGA3D_LIGHTTYPE_SPOT1",
    1230     "SVGA3D_LIGHTTYPE_SPOT2",
    1231     "SVGA3D_LIGHTTYPE_DIRECTIONAL",
    1232 };
    1233 
    1234 static const char * const g_apszRenderTargets[] =
    1235 {
    1236     "SVGA3D_RT_DEPTH",
    1237     "SVGA3D_RT_STENCIL",
    1238     "SVGA3D_RT_COLOR0",
    1239     "SVGA3D_RT_COLOR1",
    1240     "SVGA3D_RT_COLOR2",
    1241     "SVGA3D_RT_COLOR3",
    1242     "SVGA3D_RT_COLOR4",
    1243     "SVGA3D_RT_COLOR5",
    1244     "SVGA3D_RT_COLOR6",
    1245     "SVGA3D_RT_COLOR7",
    1246 };
    1247 
    1248 static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
    1249 {
    1250     char szTmp[128];
    1251 
    1252     pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
    1253 #ifdef RT_OS_WINDOWS
    1254     pHlp->pfnPrintf(pHlp, "hwnd:                    %p\n", pContext->hwnd);
    1255     if (fVerbose)
    1256         vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
    1257 # ifdef VMSVGA3D_DIRECT3D
    1258     pHlp->pfnPrintf(pHlp, "pDevice:                 %p\n", pContext->pDevice);
    1259 # else
    1260     pHlp->pfnPrintf(pHlp, "hdc:                     %p\n", pContext->hdc);
    1261     pHlp->pfnPrintf(pHlp, "hglrc:                   %p\n", pContext->hglrc);
    1262 # endif
    1263 #else
    1264 /** @todo Other hosts... */
    1265 #endif
    1266     pHlp->pfnPrintf(pHlp, "sidRenderTarget:         %#x\n", pContext->sidRenderTarget);
    1267 
    1268     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
    1269         if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
    1270             pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]:    %#x\n", i, pContext->aSidActiveTexture[i]);
    1271 
    1272     pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
    1273 
    1274     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
    1275         if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
    1276             pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
    1277                             vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
    1278 
    1279     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
    1280         for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
    1281             if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
    1282                 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
    1283                                 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
    1284 
    1285     AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
    1286     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
    1287         if (pContext->state.aTransformState[i].fValid)
    1288         {
    1289             pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
    1290             for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
    1291                 pHlp->pfnPrintf(pHlp,
    1292                                 (j % 4) == 0 ? "    [ " FLOAT_FMT_STR : (j % 4) < 3  ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
    1293                                 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
    1294         }
    1295 
    1296     AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
    1297     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
    1298         if (pContext->state.aMaterial[i].fValid)
    1299         {
    1300             pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
    1301                             g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
    1302             pHlp->pfnPrintf(pHlp, "    diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1303                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
    1304                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
    1305                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
    1306                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
    1307             pHlp->pfnPrintf(pHlp, "    ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1308                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
    1309                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
    1310                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
    1311                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
    1312             pHlp->pfnPrintf(pHlp, "    specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1313                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
    1314                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
    1315                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
    1316                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
    1317             pHlp->pfnPrintf(pHlp, "    emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1318                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
    1319                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
    1320                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
    1321                             FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
    1322         }
    1323 
    1324     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
    1325         if (pContext->state.aClipPlane[i].fValid)
    1326             pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1327                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
    1328                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
    1329                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
    1330                             FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
    1331 
    1332     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
    1333         if (pContext->state.aLightData[i].fValidData)
    1334         {
    1335             pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
    1336                             i,
    1337                             pContext->state.aLightData[i].fEnabled,
    1338                             pContext->state.aLightData[i].data.inWorldSpace,
    1339                             (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
    1340                             ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
    1341                             pContext->state.aLightData[i].data.type);
    1342             pHlp->pfnPrintf(pHlp, "    diffuse  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1343                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
    1344                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
    1345                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
    1346                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
    1347             pHlp->pfnPrintf(pHlp, "    specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1348                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
    1349                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
    1350                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
    1351                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
    1352             pHlp->pfnPrintf(pHlp, "    ambient  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1353                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
    1354                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
    1355                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
    1356                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
    1357             pHlp->pfnPrintf(pHlp, "    position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1358                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
    1359                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
    1360                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
    1361                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
    1362             pHlp->pfnPrintf(pHlp, "    direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
    1363                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
    1364                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
    1365                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
    1366                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
    1367             pHlp->pfnPrintf(pHlp, "    range=" FLOAT_FMT_STR "  falloff=" FLOAT_FMT_STR "\n",
    1368                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
    1369                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
    1370             pHlp->pfnPrintf(pHlp, "    attenuation0=" FLOAT_FMT_STR "  attenuation1=" FLOAT_FMT_STR "  attenuation2=" FLOAT_FMT_STR "\n",
    1371                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
    1372                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
    1373                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
    1374             pHlp->pfnPrintf(pHlp, "    theta=" FLOAT_FMT_STR "  phi=" FLOAT_FMT_STR "\n",
    1375                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
    1376                             FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
    1377         }
    1378 
    1379     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
    1380         if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
    1381             pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
    1382                             i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
    1383                             pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
    1384 
    1385     pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
    1386                     pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
    1387                     pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
    1388     pHlp->pfnPrintf(pHlp, "zRange:        (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
    1389                     FLOAT_FMT_ARGS(pContext->state.zRange.min),
    1390                     FLOAT_FMT_ARGS(pContext->state.zRange.max));
    1391     pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
    1392     pHlp->pfnPrintf(pHlp, "shidPixel:               %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
    1393     pHlp->pfnPrintf(pHlp, "shidVertex:              %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
    1394 
    1395     for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
    1396     {
    1397         uint32_t            cConsts  = iWhich == 0 ? pContext->state.cPixelShaderConst   : pContext->state.cVertexShaderConst;
    1398         PVMSVGASHADERCONST  paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst  : pContext->state.paVertexShaderConst;
    1399         const char         *pszName  = iWhich      ?                "paPixelShaderConst" :                "paVertexShaderConst";
    1400 
    1401         for (uint32_t i = 0; i < cConsts; i++)
    1402             if (paConsts[i].fValid)
    1403             {
    1404                 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
    1405                     pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
    1406                                     pszName, i, i,
    1407                                     FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
    1408                                     FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
    1409                 else
    1410                     pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
    1411                                     pszName, i, i,
    1412                                     paConsts[i].value[0], paConsts[i].value[1],
    1413                                     paConsts[i].value[2], paConsts[i].value[3],
    1414                                     paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
    1415                                     : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
    1416             }
    1417     }
    1418 
    1419     for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
    1420     {
    1421         uint32_t        cShaders  = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
    1422         PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
    1423         const char     *pszName   = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
    1424         for (uint32_t i = 0; i < cShaders; i++)
    1425             if (paShaders[i].id == i)
    1426             {
    1427                 pHlp->pfnPrintf(pHlp, "%s[%u]:   id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
    1428                                 pszName, i,
    1429                                 paShaders[i].id,
    1430                                 paShaders[i].cid,
    1431                                 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
    1432                                 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
    1433                                 paShaders[i].type,
    1434                                 paShaders[i].cbData,
    1435                                 paShaders[i].pShaderProgram);
    1436             }
    1437     }
    1438 }
    1439 
    1440 
    1441 void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
    1442 {
    1443     /* Warning! This code is currently racing papContexts reallocation! */
    1444     /* Warning! This code is currently racing papContexts reallocation! */
    1445     /* Warning! This code is currently racing papContexts reallocation! */
    1446     VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
    1447     if (pState)
    1448     {
    1449         /*
    1450          * Deal with a specific request first.
    1451          */
    1452         if (cid != UINT32_MAX)
    1453         {
    1454             if (cid < pState->cContexts)
    1455             {
    1456                 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    1457                 if (pContext && pContext->id == cid)
    1458                 {
    1459                     vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
    1460                     return;
    1461                 }
    1462             }
    1463             pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
    1464         }
    1465         else
    1466         {
    1467             /*
    1468              * Dump all.
    1469              */
    1470             uint32_t cContexts = pState->cContexts;
    1471             pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
    1472             for (cid = 0; cid < cContexts; cid++)
    1473             {
    1474                 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    1475                 if (pContext && pContext->id == cid)
    1476                 {
    1477                     pHlp->pfnPrintf(pHlp, "\n");
    1478                     vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
    1479                 }
    1480             }
    1481         }
    1482     }
    1483 }
    1484 
    1485 /** Values for SVGA3dTextureFilter, prefix SVGA3D_TEX_FILTER_. */
    1486 static const char * const g_apszTexureFilters[] =
    1487 {
    1488     "NONE",
    1489     "NEAREST",
    1490     "LINEAR",
    1491     "ANISOTROPIC",
    1492     "FLATCUBIC",
    1493     "GAUSSIANCUBIC",
    1494     "PYRAMIDALQUAD",
    1495     "GAUSSIANQUAD",
    1496 };
    1497 
    1498 /** SVGA3dSurfaceFlags values, prefix SVGA3D_SURFACE_. */
    1499 static VMSVGAINFOFLAGS32 const g_aSvga3DSurfaceFlags[] =
    1500 {
    1501     { SVGA3D_SURFACE_CUBEMAP            , "CUBEMAP" },
    1502     { SVGA3D_SURFACE_HINT_STATIC        , "HINT_STATIC" },
    1503     { SVGA3D_SURFACE_HINT_DYNAMIC       , "HINT_DYNAMIC" },
    1504     { SVGA3D_SURFACE_HINT_INDEXBUFFER   , "HINT_INDEXBUFFER" },
    1505     { SVGA3D_SURFACE_HINT_VERTEXBUFFER  , "HINT_VERTEXBUFFER" },
    1506     { SVGA3D_SURFACE_HINT_TEXTURE       , "HINT_TEXTURE" },
    1507     { SVGA3D_SURFACE_HINT_RENDERTARGET  , "HINT_RENDERTARGET" },
    1508     { SVGA3D_SURFACE_HINT_DEPTHSTENCIL  , "HINT_DEPTHSTENCIL" },
    1509     { SVGA3D_SURFACE_HINT_WRITEONLY     , "HINT_WRITEONLY" },
    1510     { SVGA3D_SURFACE_MASKABLE_ANTIALIAS , "MASKABLE_ANTIALIAS" },
    1511     { SVGA3D_SURFACE_AUTOGENMIPMAPS     , "AUTOGENMIPMAPS" },
    1512 };
    1513 
    1514 
    1515 #ifdef VMSVGA3D_DIRECT3D
    1516 
    1517 /** Values for D3DFORMAT, prefix D3DFMT_. */
    1518 static VMSVGAINFOENUM const g_aD3DFormats[] =
    1519 {
    1520     { D3DFMT_UNKNOWN        , "UNKNOWN" },
    1521     { D3DFMT_R8G8B8         , "R8G8B8" },
    1522     { D3DFMT_A8R8G8B8       , "A8R8G8B8" },
    1523     { D3DFMT_X8R8G8B8       , "X8R8G8B8" },
    1524     { D3DFMT_R5G6B5         , "R5G6B5" },
    1525     { D3DFMT_X1R5G5B5       , "X1R5G5B5" },
    1526     { D3DFMT_A1R5G5B5       , "A1R5G5B5" },
    1527     { D3DFMT_A4R4G4B4       , "A4R4G4B4" },
    1528     { D3DFMT_R3G3B2         , "R3G3B2" },
    1529     { D3DFMT_A8             , "A8" },
    1530     { D3DFMT_A8R3G3B2       , "A8R3G3B2" },
    1531     { D3DFMT_X4R4G4B4       , "X4R4G4B4" },
    1532     { D3DFMT_A2B10G10R10    , "A2B10G10R10" },
    1533     { D3DFMT_A8B8G8R8       , "A8B8G8R8" },
    1534     { D3DFMT_X8B8G8R8       , "X8B8G8R8" },
    1535     { D3DFMT_G16R16         , "G16R16" },
    1536     { D3DFMT_A2R10G10B10    , "A2R10G10B10" },
    1537     { D3DFMT_A16B16G16R16   , "A16B16G16R16" },
    1538     { D3DFMT_A8P8           , "A8P8" },
    1539     { D3DFMT_P8             , "P8" },
    1540     { D3DFMT_L8             , "L8" },
    1541     { D3DFMT_A8L8           , "A8L8" },
    1542     { D3DFMT_A4L4           , "A4L4" },
    1543     { D3DFMT_V8U8           , "V8U8" },
    1544     { D3DFMT_L6V5U5         , "L6V5U5" },
    1545     { D3DFMT_X8L8V8U8       , "X8L8V8U8" },
    1546     { D3DFMT_Q8W8V8U8       , "Q8W8V8U8" },
    1547     { D3DFMT_V16U16         , "V16U16" },
    1548     { D3DFMT_A2W10V10U10    , "A2W10V10U10" },
    1549     { D3DFMT_D16_LOCKABLE   , "D16_LOCKABLE" },
    1550     { D3DFMT_D32            , "D32" },
    1551     { D3DFMT_D15S1          , "D15S1" },
    1552     { D3DFMT_D24S8          , "D24S8" },
    1553     { D3DFMT_D24X8          , "D24X8" },
    1554     { D3DFMT_D24X4S4        , "D24X4S4" },
    1555     { D3DFMT_D16            , "D16" },
    1556     { D3DFMT_L16            , "L16" },
    1557     { D3DFMT_D32F_LOCKABLE  , "D32F_LOCKABLE" },
    1558     { D3DFMT_D24FS8         , "D24FS8" },
    1559     { D3DFMT_VERTEXDATA     , "VERTEXDATA" },
    1560     { D3DFMT_INDEX16        , "INDEX16" },
    1561     { D3DFMT_INDEX32        , "INDEX32" },
    1562     { D3DFMT_Q16W16V16U16   , "Q16W16V16U16" },
    1563     { D3DFMT_R16F           , "R16F" },
    1564     { D3DFMT_G16R16F        , "G16R16F" },
    1565     { D3DFMT_A16B16G16R16F  , "A16B16G16R16F" },
    1566     { D3DFMT_R32F           , "R32F" },
    1567     { D3DFMT_G32R32F        , "G32R32F" },
    1568     { D3DFMT_A32B32G32R32F  , "A32B32G32R32F" },
    1569     { D3DFMT_CxV8U8         , "CxV8U8" },
    1570     /* Fourcc values, MSB is in the right most char:  */
    1571     { D3DFMT_MULTI2_ARGB8   , "MULTI2_ARGB8" },
    1572     { D3DFMT_DXT1           , "DXT1" },
    1573     { D3DFMT_DXT2           , "DXT2" },
    1574     { D3DFMT_YUY2           , "YUY2" },
    1575     { D3DFMT_DXT3           , "DXT3" },
    1576     { D3DFMT_DXT4           , "DXT4" },
    1577     { D3DFMT_DXT5           , "DXT5" },
    1578     { D3DFMT_G8R8_G8B8      , "G8R8_G8B8" },
    1579     { D3DFMT_R8G8_B8G8      , "R8G8_B8G8" },
    1580     { D3DFMT_UYVY           , "UYVY" },
    1581     { D3DFMT_FORCE_DWORD    , "FORCE_DWORD" }, /* UINT32_MAX */
    1582 };
    1583 VMSVGAINFOENUMMAP_MAKE(static, g_D3DFormat2String, g_aD3DFormats, "D3DFMT_");
    1584 
    1585 /** Values for D3DMULTISAMPLE_TYPE, prefix D3DMULTISAMPLE_. */
    1586 static VMSVGAINFOENUM const g_aD3DMultiSampleTypes[] =
    1587 {
    1588     { D3DMULTISAMPLE_NONE           , "NONE" },
    1589     { D3DMULTISAMPLE_NONMASKABLE    , "NONMASKABLE" },
    1590     { D3DMULTISAMPLE_2_SAMPLES      , "2_SAMPLES" },
    1591     { D3DMULTISAMPLE_3_SAMPLES      , "3_SAMPLES" },
    1592     { D3DMULTISAMPLE_4_SAMPLES      , "4_SAMPLES" },
    1593     { D3DMULTISAMPLE_5_SAMPLES      , "5_SAMPLES" },
    1594     { D3DMULTISAMPLE_6_SAMPLES      , "6_SAMPLES" },
    1595     { D3DMULTISAMPLE_7_SAMPLES      , "7_SAMPLES" },
    1596     { D3DMULTISAMPLE_8_SAMPLES      , "8_SAMPLES" },
    1597     { D3DMULTISAMPLE_9_SAMPLES      , "9_SAMPLES" },
    1598     { D3DMULTISAMPLE_10_SAMPLES     , "10_SAMPLES" },
    1599     { D3DMULTISAMPLE_11_SAMPLES     , "11_SAMPLES" },
    1600     { D3DMULTISAMPLE_12_SAMPLES     , "12_SAMPLES" },
    1601     { D3DMULTISAMPLE_13_SAMPLES     , "13_SAMPLES" },
    1602     { D3DMULTISAMPLE_14_SAMPLES     , "14_SAMPLES" },
    1603     { D3DMULTISAMPLE_15_SAMPLES     , "15_SAMPLES" },
    1604     { D3DMULTISAMPLE_16_SAMPLES     , "16_SAMPLES" },
    1605     { D3DMULTISAMPLE_FORCE_DWORD    , "FORCE_DWORD" },
    1606 };
    1607 VMSVGAINFOENUMMAP_MAKE(static, g_D3DMultiSampleType2String, g_aD3DMultiSampleTypes, "D3DMULTISAMPLE_");
    1608 
    1609 /** D3DUSAGE_XXX flag value, prefix D3DUSAGE_. */
    1610 static VMSVGAINFOFLAGS32 const g_aD3DUsageFlags[] =
    1611 {
    1612     { D3DUSAGE_RENDERTARGET                     , "RENDERTARGET" },
    1613     { D3DUSAGE_DEPTHSTENCIL                     , "DEPTHSTENCIL" },
    1614     { D3DUSAGE_WRITEONLY                        , "WRITEONLY" },
    1615     { D3DUSAGE_SOFTWAREPROCESSING               , "SOFTWAREPROCESSING" },
    1616     { D3DUSAGE_DONOTCLIP                        , "DONOTCLIP" },
    1617     { D3DUSAGE_POINTS                           , "POINTS" },
    1618     { D3DUSAGE_RTPATCHES                        , "RTPATCHES" },
    1619     { D3DUSAGE_NPATCHES                         , "NPATCHES" },
    1620     { D3DUSAGE_DYNAMIC                          , "DYNAMIC" },
    1621     { D3DUSAGE_AUTOGENMIPMAP                    , "AUTOGENMIPMAP" },
    1622     { D3DUSAGE_RESTRICTED_CONTENT               , "RESTRICTED_CONTENT" },
    1623     { D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER  , "RESTRICT_SHARED_RESOURCE_DRIVER" },
    1624     { D3DUSAGE_RESTRICT_SHARED_RESOURCE         , "RESTRICT_SHARED_RESOURCE" },
    1625     { D3DUSAGE_DMAP                             , "DMAP" },
    1626     { D3DUSAGE_NONSECURE                        , "NONSECURE" },
    1627     { D3DUSAGE_TEXTAPI                          , "TEXTAPI" },
    1628 };
    1629 
    1630 
    1631 /**
    1632  * Release all shared surface objects.
    1633  */
    1634 static DECLCALLBACK(int) vmsvga3dInfoSharedObjectCallback(PAVLU32NODECORE pNode, void *pvUser)
    1635 {
    1636     PVMSVGA3DSHAREDSURFACE  pSharedSurface = (PVMSVGA3DSHAREDSURFACE)pNode;
    1637     PCDBGFINFOHLP           pHlp           = (PCDBGFINFOHLP)pvUser;
    1638 
    1639     pHlp->pfnPrintf(pHlp, "Shared surface:          %#x  pv=%p\n", pSharedSurface->Core.Key, pSharedSurface->u.pCubeTexture);
    1640 
    1641     return 0;
    1642 }
    1643 
    1644 #elif defined(VMSVGA3D_OPENGL)
    1645     /** @todo   */
    1646 
    1647 #else
    1648 # error "Build config error."
    1649 #endif
    1650 
    1651 
    1652 static void vmsvga3dInfoSurfaceWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
    1653                                          bool fVerbose, uint32_t cxAscii, bool fInvY)
    1654 {
    1655     char szTmp[128];
    1656 
    1657     pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : "");
    1658 #if defined(VMSVGA3D_OPENGL) && defined(VMSVGA3D_OGL_WITH_SHARED_CTX)
    1659     pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation);
    1660 #else
    1661     pHlp->pfnPrintf(pHlp, "idAssociatedContext:     %#x\n", pSurface->idAssociatedContext);
    1662 #endif
    1663     pHlp->pfnPrintf(pHlp, "Format:                  %s\n",
    1664                     vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, (int)pSurface->format, false, &g_SVGA3dSurfaceFormat2String));
    1665     pHlp->pfnPrintf(pHlp, "Flags:                   %#x", pSurface->flags);
    1666     vmsvga3dInfoU32Flags(pHlp, pSurface->flags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags));
    1667     pHlp->pfnPrintf(pHlp, "\n");
    1668     if (pSurface->cFaces == 0)
    1669         pHlp->pfnPrintf(pHlp, "Faces:                   %u\n", pSurface->cFaces);
    1670     for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    1671     {
    1672         Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
    1673         if (pSurface->faces[iFace].numMipLevels == 0)
    1674             pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels:  %u\n", iFace, pSurface->faces[iFace].numMipLevels);
    1675 
    1676         uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
    1677         for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
    1678         {
    1679             pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s  cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x",
    1680                             iFace, iLevel, iMipmap, iMipmap < 10 ? " " : "",
    1681                             pSurface->pMipmapLevels[iMipmap].size.width,
    1682                             pSurface->pMipmapLevels[iMipmap].size.height,
    1683                             pSurface->pMipmapLevels[iMipmap].size.depth,
    1684                             pSurface->pMipmapLevels[iMipmap].cbSurface,
    1685                             pSurface->pMipmapLevels[iMipmap].cbSurfacePitch);
    1686             if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
    1687                 pHlp->pfnPrintf(pHlp, " pvData=%p", pSurface->pMipmapLevels[iMipmap].pSurfaceData);
    1688             if (pSurface->pMipmapLevels[iMipmap].fDirty)
    1689                 pHlp->pfnPrintf(pHlp, " dirty");
    1690             pHlp->pfnPrintf(pHlp, "\n");
    1691         }
    1692     }
    1693 
    1694     pHlp->pfnPrintf(pHlp, "cbBlock:                 %u (%#x)\n", pSurface->cbBlock, pSurface->cbBlock);
    1695     pHlp->pfnPrintf(pHlp, "Multi-sample count:      %u\n", pSurface->multiSampleCount);
    1696     pHlp->pfnPrintf(pHlp, "Autogen filter:          %s\n",
    1697                     vmsvgaFormatEnumValue(szTmp, sizeof(szTmp), NULL, pSurface->autogenFilter,
    1698                                           "SVGA3D_TEX_FILTER_", g_apszTexureFilters, RT_ELEMENTS(g_apszTexureFilters)));
    1699 
    1700 #ifdef VMSVGA3D_DIRECT3D
    1701     pHlp->pfnPrintf(pHlp, "formatD3D:               %s\n",
    1702                     vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->formatD3D, true, &g_D3DFormat2String));
    1703     pHlp->pfnPrintf(pHlp, "fUsageD3D:               %#x", pSurface->fUsageD3D);
    1704     vmsvga3dInfoU32Flags(pHlp, pSurface->fUsageD3D, "D3DUSAGE_", g_aD3DUsageFlags, RT_ELEMENTS(g_aD3DUsageFlags));
    1705     pHlp->pfnPrintf(pHlp, "\n");
    1706     pHlp->pfnPrintf(pHlp, "multiSampleTypeD3D:      %s\n",
    1707                     vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->multiSampleTypeD3D,
    1708                                             true, &g_D3DMultiSampleType2String));
    1709     if (pSurface->hSharedObject != NULL)
    1710         pHlp->pfnPrintf(pHlp, "hSharedObject:           %p\n", pSurface->hSharedObject);
    1711     if (pSurface->pQuery)
    1712         pHlp->pfnPrintf(pHlp, "pQuery:                  %p\n", pSurface->pQuery);
    1713     if (pSurface->u.pSurface)
    1714         pHlp->pfnPrintf(pHlp, "u.pXxxx:                 %p\n", pSurface->u.pSurface);
    1715     if (pSurface->bounce.pTexture)
    1716         pHlp->pfnPrintf(pHlp, "bounce.pXxxx:            %p\n", pSurface->bounce.pTexture);
    1717     RTAvlU32DoWithAll(&pSurface->pSharedObjectTree, true /*fFromLeft*/, vmsvga3dInfoSharedObjectCallback, (void *)pHlp);
    1718     pHlp->pfnPrintf(pHlp, "fStencilAsTexture:       %RTbool\n", pSurface->fStencilAsTexture);
    1719 
    1720 #elif defined(VMSVGA3D_OPENGL)
    1721     /** @todo   */
    1722 #else
    1723 # error "Build config error."
    1724 #endif
    1725 
    1726     if (fVerbose)
    1727         for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    1728         {
    1729             uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
    1730             for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
    1731                 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
    1732                 {
    1733                     if (  ASMMemIsAll8(pSurface->pMipmapLevels[iMipmap].pSurfaceData,
    1734                                        pSurface->pMipmapLevels[iMipmap].cbSurface, 0) == NULL)
    1735                         pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: all zeros ---\n", iFace, iLevel, iMipmap);
    1736                     else
    1737                     {
    1738                         pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: cx=%u, cy=%u, cz=%u ---\n",
    1739                                         iFace, iLevel, iMipmap,
    1740                                         pSurface->pMipmapLevels[iMipmap].size.width,
    1741                                         pSurface->pMipmapLevels[iMipmap].size.height,
    1742                                         pSurface->pMipmapLevels[iMipmap].size.depth);
    1743                         vmsvga3dAsciiPrint(vmsvga3dAsciiPrintlnInfo, (void *)pHlp,
    1744                                            pSurface->pMipmapLevels[iMipmap].pSurfaceData,
    1745                                            pSurface->pMipmapLevels[iMipmap].cbSurface,
    1746                                            pSurface->pMipmapLevels[iMipmap].size.width,
    1747                                            pSurface->pMipmapLevels[iMipmap].size.height,
    1748                                            pSurface->pMipmapLevels[iMipmap].cbSurfacePitch,
    1749                                            pSurface->format,
    1750                                            fInvY,
    1751                                            cxAscii, cxAscii * 3 / 4);
    1752                     }
    1753                 }
    1754         }
    1755 }
    1756 
    1757 
    1758 void vmsvga3dInfoSurfaceWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t sid, bool fVerbose, uint32_t cxAscii, bool fInvY)
    1759 {
    1760     /* Warning! This code is currently racing papSurfaces reallocation! */
    1761     /* Warning! This code is currently racing papSurfaces reallocation! */
    1762     /* Warning! This code is currently racing papSurfaces reallocation! */
    1763     VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
    1764     if (pState)
    1765     {
    1766         /*
    1767          * Deal with a specific request first.
    1768          */
    1769         if (sid != UINT32_MAX)
    1770         {
    1771             if (sid < pState->cSurfaces)
    1772             {
    1773                 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    1774                 if (pSurface && pSurface->id == sid)
    1775                 {
    1776                     if (fVerbose)
    1777                         vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, sid);
    1778                     vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
    1779                     return;
    1780                 }
    1781             }
    1782             pHlp->pfnPrintf(pHlp, "Surface ID %#x not found.\n", sid);
    1783         }
    1784         else
    1785         {
    1786             /*
    1787              * Dump all.
    1788              */
    1789             if (fVerbose)
    1790                 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, UINT32_MAX);
    1791             uint32_t cSurfaces = pState->cSurfaces;
    1792             pHlp->pfnPrintf(pHlp, "cSurfaces=%d\n", cSurfaces);
    1793             for (sid = 0; sid < cSurfaces; sid++)
    1794             {
    1795                 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    1796                 if (pSurface && pSurface->id == sid)
    1797                 {
    1798                     pHlp->pfnPrintf(pHlp, "\n");
    1799                     vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
    1800                 }
    1801             }
    1802         }
    1803     }
    1804 
    1805 }
    1806 
    1807 
    1808 #endif /* !___DevVGA_SVGA3d_shared_h___ */
    1809 
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp

    r57083 r57149  
    3333#include <iprt/avl.h>
    3434
    35 #include <VBox/VMMDev.h>
    36 #include <VBox/VBoxVideo.h>
    37 #include <VBox/bioslogo.h>
     35#include <VBox/VBoxVideo.h> /* required by DevVGA.h */
    3836
    3937/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
     
    4240#include "DevVGA-SVGA.h"
    4341#include "DevVGA-SVGA3d.h"
    44 #include "vmsvga/svga_reg.h"
    45 #include "vmsvga/svga3d_reg.h"
    46 #include "vmsvga/svga3d_shaderdefs.h"
     42#define VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
     43#include "DevVGA-SVGA3d-internal.h"
    4744
    4845
     
    5148*   Structures and Typedefs                                                    *
    5249*******************************************************************************/
    53 #define     VMSVGA3D_WNDCLASSNAME       "VMSVGA3DWNDCLS"
     50# define VMSVGA3D_WNDCLASSNAME  "VMSVGA3DWNDCLS"
    5451
    5552static LONG WINAPI vmsvga3dWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     
    118115
    119116
     117
    120118#ifdef RT_OS_WINDOWS
    121119
     
    304302
    305303#endif /* RT_OS_WINDOWS */
    306 
    307 
    308 void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)
    309 {
    310     for (uint32_t i = 0; i < cFlags; i++)
    311         if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)
    312         {
    313             Assert(paFlags[i].fFlags);
    314             pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);
    315             fFlags &= ~paFlags[i].fFlags;
    316             if (!fFlags)
    317                 return;
    318         }
    319     if (fFlags)
    320         pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);
    321 }
    322 
    323 
    324 /**
    325  * Worker for vmsvgaR3Info that display details of a host window.
    326  *
    327  * @param   pHlp            The output methods.
    328  * @param   idHostWindow    The host window handle/id/whatever.
    329  */
    330 void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)
    331 {
    332 #ifdef RT_OS_WINDOWS
    333     HWND hwnd = (HWND)(uintptr_t)idHostWindow;
    334     Assert((uintptr_t)hwnd == idHostWindow);
    335     if (hwnd != NULL)
    336     {
    337         WINDOWINFO Info;
    338         RT_ZERO(Info);
    339         Info.cbSize = sizeof(Info);
    340         if (GetWindowInfo(hwnd, &Info))
    341         {
    342             pHlp->pfnPrintf(pHlp, "     Window rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
    343                             Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,
    344                             Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);
    345             pHlp->pfnPrintf(pHlp, "     Client rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
    346                             Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,
    347                             Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);
    348             pHlp->pfnPrintf(pHlp, "     Style:         %#x", Info.dwStyle);
    349             static const VMSVGAINFOFLAGS32 g_aStyles[] =
    350             {
    351                 { WS_POPUP        , "POPUP" },
    352                 { WS_CHILD        , "CHILD" },
    353                 { WS_MINIMIZE     , "MINIMIZE" },
    354                 { WS_VISIBLE      , "VISIBLE" },
    355                 { WS_DISABLED     , "DISABLED" },
    356                 { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },
    357                 { WS_CLIPCHILDREN , "CLIPCHILDREN" },
    358                 { WS_MAXIMIZE     , "MAXIMIZE" },
    359                 { WS_BORDER       , "BORDER" },
    360                 { WS_DLGFRAME     , "DLGFRAME" },
    361                 { WS_VSCROLL      , "VSCROLL" },
    362                 { WS_HSCROLL      , "HSCROLL" },
    363                 { WS_SYSMENU      , "SYSMENU" },
    364                 { WS_THICKFRAME   , "THICKFRAME" },
    365                 { WS_GROUP        , "GROUP" },
    366                 { WS_TABSTOP      , "TABSTOP" },
    367             };
    368             vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));
    369             pHlp->pfnPrintf(pHlp, "\n");
    370 
    371             pHlp->pfnPrintf(pHlp, "     ExStyle:       %#x", Info.dwExStyle);
    372             static const VMSVGAINFOFLAGS32 g_aExStyles[] =
    373             {
    374                 { WS_EX_DLGMODALFRAME,   "DLGMODALFRAME" },
    375                 { 0x00000002,            "DRAGDETECT" },
    376                 { WS_EX_NOPARENTNOTIFY,  "NOPARENTNOTIFY" },
    377                 { WS_EX_TOPMOST,         "TOPMOST" },
    378                 { WS_EX_ACCEPTFILES,     "ACCEPTFILES" },
    379                 { WS_EX_TRANSPARENT,     "TRANSPARENT" },
    380                 { WS_EX_MDICHILD,        "MDICHILD" },
    381                 { WS_EX_TOOLWINDOW,      "TOOLWINDOW" },
    382                 { WS_EX_WINDOWEDGE,      "WINDOWEDGE" },
    383                 { WS_EX_CLIENTEDGE,      "CLIENTEDGE" },
    384                 { WS_EX_CONTEXTHELP,     "CONTEXTHELP" },
    385                 { WS_EX_RIGHT,           "RIGHT" },
    386                 /*{ WS_EX_LEFT,            "LEFT" }, = 0 */
    387                 { WS_EX_RTLREADING,      "RTLREADING" },
    388                 /*{ WS_EX_LTRREADING,      "LTRREADING" }, = 0 */
    389                 { WS_EX_LEFTSCROLLBAR,   "LEFTSCROLLBAR" },
    390                 /*{ WS_EX_RIGHTSCROLLBAR,  "RIGHTSCROLLBAR" }, = 0 */
    391                 { WS_EX_CONTROLPARENT,   "CONTROLPARENT" },
    392                 { WS_EX_STATICEDGE,      "STATICEDGE" },
    393                 { WS_EX_APPWINDOW,       "APPWINDOW" },
    394                 { WS_EX_LAYERED,         "LAYERED" },
    395                 { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },
    396                 { WS_EX_LAYOUTRTL,       "LAYOUTRTL" },
    397                 { WS_EX_COMPOSITED,      "COMPOSITED" },
    398                 { WS_EX_NOACTIVATE,      "NOACTIVATE" },
    399             };
    400             vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));
    401             pHlp->pfnPrintf(pHlp, "\n");
    402 
    403             pHlp->pfnPrintf(pHlp, "     Window Status: %#x\n", Info.dwWindowStatus);
    404             if (Info.cxWindowBorders || Info.cyWindowBorders)
    405                 pHlp->pfnPrintf(pHlp, "     Borders:       cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);
    406             pHlp->pfnPrintf(pHlp, "     Window Type:   %#x\n", Info.atomWindowType);
    407             pHlp->pfnPrintf(pHlp, "     Creator Ver:   %#x\n", Info.wCreatorVersion);
    408         }
    409         else
    410             pHlp->pfnPrintf(pHlp, "     GetWindowInfo: last error %d\n", GetLastError());
    411     }
    412 #else
    413     pHlp->pfnPrintf(pHlp, "    Windows info:   Not implemented on this platform\n");
    414 #endif
    415 
    416 }
    417 
    418 
    419 /**
    420  * Looks up an enum value in a translation table.
    421  *
    422  * @returns The value name.
    423  * @param   iValue              The value to name.
    424  * @param   pEnumMap            Enum value to string mapping.
    425  */
    426 const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)
    427 {
    428     PCVMSVGAINFOENUM paValues = pEnumMap->paValues;
    429 
    430 #ifdef VBOX_STRICT
    431     /*
    432      * Check that it's really sorted, or the binary lookup won't work right.
    433      */
    434     if (!*pEnumMap->pfAsserted)
    435     {
    436         *pEnumMap->pfAsserted = true;
    437         for (uint32_t i = 1; i < pEnumMap->cValues; i++)
    438             Assert(paValues[i - 1].iValue <= paValues[i].iValue);
    439     }
    440 #endif
    441 
    442     /*
    443      * Binary search
    444      */
    445     uint32_t iStart = 0;
    446     uint32_t iEnd   = (uint32_t)pEnumMap->cValues;
    447     for (;;)
    448     {
    449         uint32_t i = iStart + (iEnd - iStart) / 2;
    450         if (iValue < paValues[i].iValue)
    451         {
    452             if (i > iStart)
    453                 iEnd = i;
    454             else
    455                 break;
    456         }
    457         else if (iValue > paValues[i].iValue)
    458         {
    459             i++;
    460             if (i < iEnd)
    461                 iStart = i;
    462             else
    463                 break;
    464         }
    465         else
    466             return paValues[i].pszName;
    467     }
    468     return NULL;
    469 }
    470 
    471 
    472 /**
    473  * Formats an enum value as a string, sparse mapping table.
    474  *
    475  * @returns pszBuffer.
    476  * @param   pszBuffer           The output buffer.
    477  * @param   cbBuffer            The size of the output buffer.
    478  * @param   pszName             The variable name, optional.
    479  * @param   iValue              The enum value.
    480  * @param   fPrefix             Whether to prepend the prefix or not.
    481  * @param   pEnumMap            Enum value to string mapping.
    482  */
    483 char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
    484                               bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)
    485 {
    486     const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);
    487     const char *pszPrefix    = fPrefix ? pEnumMap->pszPrefix : "";
    488     if (pszValueName)
    489     {
    490         if (pszName)
    491             RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);
    492         else
    493             RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);
    494         return pszBuffer;
    495     }
    496 
    497     if (pszName)
    498         RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
    499     else
    500         RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
    501     return pszBuffer;
    502 }
    503 
    504 
    505 /**
    506  * Formats an enum value as a string.
    507  *
    508  * @returns pszBuffer.
    509  * @param   pszBuffer           The output buffer.
    510  * @param   cbBuffer            The size of the output buffer.
    511  * @param   pszName             The variable name, optional.
    512  * @param   uValue              The enum value.
    513  * @param   pszPrefix           The prefix of the enum values.  Empty string if
    514  *                              none.  This helps reduce the memory footprint
    515  *                              as well as the source code size.
    516  * @param   papszValues         One to one string mapping of the enum values.
    517  * @param   cValues             The number of values in the mapping.
    518  */
    519 char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
    520                             const char *pszPrefix, const char * const *papszValues, size_t cValues)
    521 {
    522     if (uValue < cValues)
    523     {
    524         if (pszName)
    525             RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
    526         else
    527             RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
    528     }
    529     else
    530     {
    531         if (pszName)
    532             RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
    533         else
    534             RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
    535     }
    536     return pszBuffer;
    537 }
    538 
    539 
    540 /**
    541  * DBGF info printer for vmsvga3dAsciiPrint.
    542  *
    543  * @param   pszLine             The line to print.
    544  * @param   pvUser              The debug info helpers.
    545  */
    546 DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
    547 {
    548     PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
    549     pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
    550 }
    551 
    552 
    553 /**
    554  * Log printer for vmsvga3dAsciiPrint.
    555  *
    556  * @param   pszLine             The line to print.
    557  * @param   pvUser              Ignored.
    558  */
    559 DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
    560 {
    561     size_t cch = strlen(pszLine);
    562     while (cch > 0 && pszLine[cch - 1] == ' ')
    563         cch--;
    564     RTLogPrintf("%.*s\n", cch, pszLine);
    565     NOREF(pvUser);
    566 }
    567 
    568 
    569 void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
    570                         uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
    571                         uint32_t cchMaxX, uint32_t cchMaxY)
    572 {
    573     /*
    574      * Skip stuff we can't or won't need to handle.
    575      */
    576     if (!cx || !cy)
    577         return;
    578     switch (enmFormat)
    579     {
    580         /* Compressed. */
    581         case SVGA3D_DXT1:
    582         case SVGA3D_DXT2:
    583         case SVGA3D_DXT3:
    584         case SVGA3D_DXT4:
    585         case SVGA3D_DXT5:
    586             return;
    587         /* Generic. */
    588         case SVGA3D_BUFFER:
    589             return;
    590         default:
    591             break; /* ok */
    592     }
    593 
    594     /*
    595      * Figure the pixel conversion factors.
    596      */
    597     uint32_t cxPerChar = cx / cchMaxX + 1;
    598     uint32_t cyPerChar = cy / cchMaxY + 1;
    599     /** @todo try keep aspect...   */
    600     uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
    601     uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
    602 
    603     /*
    604      * The very simple conversion we're doing in this function is based on
    605      * mapping a block of converted pixels to an ASCII character of similar
    606      * weigth.  We do that by summing up all the 8-bit gray scale pixels in
    607      * that block, applying a conversion factor and getting an index into an
    608      * array of increasingly weighty characters.
    609      */
    610     static const char       s_szPalette[] = "   ..`',:;icodxkO08XNWM";
    611     static const uint32_t   s_cchPalette  = sizeof(s_szPalette) - 1;
    612     uint32_t const          cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
    613 
    614     /*
    615      * Do the work
    616      */
    617     uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
    618     if (!pauScanline)
    619         return;
    620     char *pszLine = (char *)&pauScanline[cchLine];
    621     RTCPTRUNION uSrc;
    622     uSrc.pv              = pvImage;
    623     if (fInvY)
    624         uSrc.pu8 += (cy - 1) * cbScanline;
    625     uint32_t cyLeft = cy;
    626     uint32_t cyLeftInScanline = cyPerChar;
    627     bool     fHitFormatAssert = false;
    628     for (;;)
    629     {
    630         /*
    631          * Process the scanline.  This is tedious because of all the
    632          * different formats.  We generally ignore alpha, unless it's
    633          * all we've got to work with.
    634          * Color to 8-bit grayscale conversion is done by averaging.
    635          */
    636 #define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \
    637             do { \
    638                 for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
    639                 { \
    640                     a_RdExpr; \
    641                     pauScanline[xDst] += (a_AddExpr) & 0xff; \
    642                     Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
    643                     if (--cxLeftInChar == 0) \
    644                     { \
    645                         xDst++; \
    646                         cxLeftInChar = cxPerChar; \
    647                     } \
    648                 } \
    649             } while (0)
    650 
    651         switch (enmFormat)
    652         {
    653             /* Unsigned RGB and super/subsets. */
    654             case SVGA3D_X8R8G8B8:
    655             case SVGA3D_A8R8G8B8:
    656                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    657                                  (  ( u32Tmp        & 0xff) /* B */
    658                                   + ((u32Tmp >>  8) & 0xff) /* G */
    659                                   + ((u32Tmp >> 16) & 0xff) /* R */) / 3);
    660                 break;
    661             case SVGA3D_R5G6B5:
    662                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    663                                  ( ( u16Tmp         & 0x1f) * 8
    664                                  + ((u16Tmp >>  5)  & 0x3f) * 4
    665                                  + ( u16Tmp >> 11)          * 8 ) / 3 );
    666                 break;
    667             case SVGA3D_X1R5G5B5:
    668             case SVGA3D_A1R5G5B5:
    669                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    670                                  (  ( u16Tmp        & 0x1f) * 8
    671                                   + ((u16Tmp >> 5)  & 0x1f) * 8
    672                                   + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );
    673                 break;
    674             case SVGA3D_A4R4G4B4:
    675                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    676                                  (  ( u16Tmp        & 0xf) * 16
    677                                   + ((u16Tmp >> 4)  & 0xf) * 16
    678                                   + ((u16Tmp >> 8)  & 0xf) * 16) / 3 );
    679                 break;
    680             case SVGA3D_A16B16G16R16:
    681                 CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],
    682                                  (  ((u64Tmp >>  8) & 0xff) /* R */
    683                                   + ((u64Tmp >> 24) & 0xff) /* G */
    684                                   + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);
    685                 break;
    686             case SVGA3D_A2R10G10B10:
    687                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    688                                  (  ( u32Tmp        & 0x3ff) /* B */
    689                                   + ((u32Tmp >> 10) & 0x3ff) /* G */
    690                                   + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));
    691                 break;
    692             case SVGA3D_G16R16:
    693                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    694                                  (  (u32Tmp & 0xffff) /* R */
    695                                   + (u32Tmp >>   16 ) /* G */) / 0x200);
    696                 break;
    697 
    698             /* Depth. */
    699             case SVGA3D_Z_D32:
    700                 CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),
    701                                    (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))
    702                                  | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
    703                                  | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
    704                                  | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
    705                                  | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
    706                                  | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
    707                                  | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
    708                                  | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
    709                 break;
    710             case SVGA3D_Z_D16:
    711                 CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],
    712                                    ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))
    713                                  | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))
    714                                  | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))
    715                                  | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))
    716                                  | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))
    717                                  | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))
    718                                  | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))
    719                                  | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );
    720                 break;
    721             case SVGA3D_Z_D24S8:
    722                 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    723                                    (  u32Tmp        & 0xff) /* stencile */
    724                                  | ((~u32Tmp >> 18) & 0x3f));
    725                 break;
    726             case SVGA3D_Z_D15S1:
    727                 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    728                                    ( (u16Tmp & 0x01) << 7) /* stencile */
    729                                  | ((~u16Tmp >> 8) & 0x7f));
    730                 break;
    731 
    732             /* Pure alpha. */
    733             case SVGA3D_ALPHA8:
    734                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
    735                 break;
    736 
    737             /* Luminance */
    738             case SVGA3D_LUMINANCE8:
    739                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
    740                 break;
    741             case SVGA3D_LUMINANCE4_ALPHA4:
    742                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);
    743                 break;
    744             case SVGA3D_LUMINANCE16:
    745                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
    746                 break;
    747             case SVGA3D_LUMINANCE8_ALPHA8:
    748                 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
    749                 break;
    750 
    751             /* Not supported. */
    752             case SVGA3D_DXT1:
    753             case SVGA3D_DXT2:
    754             case SVGA3D_DXT3:
    755             case SVGA3D_DXT4:
    756             case SVGA3D_DXT5:
    757             case SVGA3D_BUFFER:
    758                 AssertFailedBreak();
    759 
    760             /* Not considered for implementation yet. */
    761             case SVGA3D_BUMPU8V8:
    762             case SVGA3D_BUMPL6V5U5:
    763             case SVGA3D_BUMPX8L8V8U8:
    764             case SVGA3D_BUMPL8V8U8:
    765             case SVGA3D_ARGB_S10E5:
    766             case SVGA3D_ARGB_S23E8:
    767             case SVGA3D_V8U8:
    768             case SVGA3D_Q8W8V8U8:
    769             case SVGA3D_CxV8U8:
    770             case SVGA3D_X8L8V8U8:
    771             case SVGA3D_A2W10V10U10:
    772             case SVGA3D_R_S10E5:
    773             case SVGA3D_R_S23E8:
    774             case SVGA3D_RG_S10E5:
    775             case SVGA3D_RG_S23E8:
    776             case SVGA3D_Z_D24X8:
    777             case SVGA3D_V16U16:
    778             case SVGA3D_UYVY:
    779             case SVGA3D_YUY2:
    780             case SVGA3D_NV12:
    781             case SVGA3D_AYUV:
    782             case SVGA3D_BC4_UNORM:
    783             case SVGA3D_BC5_UNORM:
    784             case SVGA3D_Z_DF16:
    785             case SVGA3D_Z_DF24:
    786             case SVGA3D_Z_D24S8_INT:
    787                 if (!fHitFormatAssert)
    788                 {
    789                     AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));
    790                     fHitFormatAssert = true;
    791                 }
    792                 /* fall thru */
    793             default:
    794                 /* Lazy programmer fallbacks. */
    795                 if (cbSrcPixel == 4)
    796                     CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
    797                                      (  ( u32Tmp        & 0xff)
    798                                       + ((u32Tmp >>  8) & 0xff)
    799                                       + ((u32Tmp >> 16) & 0xff)
    800                                       + ((u32Tmp >> 24) & 0xff) ) / 4);
    801                 else if (cbSrcPixel == 3)
    802                     CONVERT_SCANLINE(RT_NOTHING,
    803                                      (  (uint32_t)uSrc.pu8[xSrc * 4]
    804                                       + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
    805                                       + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
    806                 else if (cbSrcPixel == 2)
    807                     CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
    808                                      (  ( u16Tmp        & 0xf)
    809                                       + ((u16Tmp >>  4) & 0xf)
    810                                       + ((u16Tmp >>  8) & 0xf)
    811                                       + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );
    812                 else if (cbSrcPixel == 1)
    813                     CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
    814                 else
    815                     AssertFailed();
    816                 break;
    817 
    818         }
    819 
    820         /*
    821          * Print we've reached the end of a block in y direction or if we're at
    822          * the end of the image.
    823          */
    824         cyLeft--;
    825         if (--cyLeftInScanline == 0 || cyLeft == 0)
    826         {
    827             for (uint32_t i = 0; i < cchLine; i++)
    828             {
    829                 uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
    830                 pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
    831             }
    832             pszLine[cchLine] = '\0';
    833             pfnPrintLine(pszLine, pvUser);
    834 
    835             if (!cyLeft)
    836                 break;
    837             cyLeftInScanline = cyPerChar;
    838             RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
    839         }
    840 
    841         /*
    842          * Advance.
    843          */
    844         if (!fInvY)
    845             uSrc.pu8 += cbScanline;
    846         else
    847             uSrc.pu8 -= cbScanline;
    848     }
    849 }
    850 
    851 
    852 /**
    853  * List of render state names with type prefix.
    854  *
    855  * First char in the name is a type indicator:
    856  *      - '*' = requires special handling.
    857  *      - 'f' = SVGA3dbool
    858  *      - 'd' = uint32_t
    859  *      - 'r' = float
    860  *      - 'b' = SVGA3dBlendOp
    861  *      - 'c' = SVGA3dColor, SVGA3dColorMask
    862  *      - 'e' = SVGA3dBlendEquation
    863  *      - 'm' = SVGA3dColorMask
    864  *      - 'p' = SVGA3dCmpFunc
    865  *      - 's' = SVGA3dStencilOp
    866  *      - 'v' = SVGA3dVertexMaterial
    867  *      - 'w' = SVGA3dWrapFlags
    868  */
    869 static const char * const g_apszRenderStateNamesAndType[] =
    870 {
    871    "*" "INVALID",                       /*  invalid  */
    872    "f" "ZENABLE",                       /*  SVGA3dBool  */
    873    "f" "ZWRITEENABLE",                  /*  SVGA3dBool  */
    874    "f" "ALPHATESTENABLE",               /*  SVGA3dBool  */
    875    "f" "DITHERENABLE",                  /*  SVGA3dBool  */
    876    "f" "BLENDENABLE",                   /*  SVGA3dBool  */
    877    "f" "FOGENABLE",                     /*  SVGA3dBool  */
    878    "f" "SPECULARENABLE",                /*  SVGA3dBool  */
    879    "f" "STENCILENABLE",                 /*  SVGA3dBool  */
    880    "f" "LIGHTINGENABLE",                /*  SVGA3dBool  */
    881    "f" "NORMALIZENORMALS",              /*  SVGA3dBool  */
    882    "f" "POINTSPRITEENABLE",             /*  SVGA3dBool  */
    883    "f" "POINTSCALEENABLE",              /*  SVGA3dBool  */
    884    "x" "STENCILREF",                    /*  uint32_t  */
    885    "x" "STENCILMASK",                   /*  uint32_t  */
    886    "x" "STENCILWRITEMASK",              /*  uint32_t  */
    887    "r" "FOGSTART",                      /*  float  */
    888    "r" "FOGEND",                        /*  float  */
    889    "r" "FOGDENSITY",                    /*  float  */
    890    "r" "POINTSIZE",                     /*  float  */
    891    "r" "POINTSIZEMIN",                  /*  float  */
    892    "r" "POINTSIZEMAX",                  /*  float  */
    893    "r" "POINTSCALE_A",                  /*  float  */
    894    "r" "POINTSCALE_B",                  /*  float  */
    895    "r" "POINTSCALE_C",                  /*  float  */
    896    "c" "FOGCOLOR",                      /*  SVGA3dColor  */
    897    "c" "AMBIENT",                       /*  SVGA3dColor  */
    898    "*" "CLIPPLANEENABLE",               /*  SVGA3dClipPlanes  */
    899    "*" "FOGMODE",                       /*  SVGA3dFogMode  */
    900    "*" "FILLMODE",                      /*  SVGA3dFillMode  */
    901    "*" "SHADEMODE",                     /*  SVGA3dShadeMode  */
    902    "*" "LINEPATTERN",                   /*  SVGA3dLinePattern  */
    903    "b" "SRCBLEND",                      /*  SVGA3dBlendOp  */
    904    "b" "DSTBLEND",                      /*  SVGA3dBlendOp  */
    905    "e" "BLENDEQUATION",                 /*  SVGA3dBlendEquation  */
    906    "*" "CULLMODE",                      /*  SVGA3dFace  */
    907    "p" "ZFUNC",                         /*  SVGA3dCmpFunc  */
    908    "p" "ALPHAFUNC",                     /*  SVGA3dCmpFunc  */
    909    "p" "STENCILFUNC",                   /*  SVGA3dCmpFunc  */
    910    "s" "STENCILFAIL",                   /*  SVGA3dStencilOp  */
    911    "s" "STENCILZFAIL",                  /*  SVGA3dStencilOp  */
    912    "s" "STENCILPASS",                   /*  SVGA3dStencilOp  */
    913    "r" "ALPHAREF",                      /*  float  */
    914    "*" "FRONTWINDING",                  /*  SVGA3dFrontWinding  */
    915    "*" "COORDINATETYPE",                /*  SVGA3dCoordinateType  */
    916    "r" "ZBIAS",                         /*  float  */
    917    "f" "RANGEFOGENABLE",                /*  SVGA3dBool  */
    918    "c" "COLORWRITEENABLE",              /*  SVGA3dColorMask  */
    919    "f" "VERTEXMATERIALENABLE",          /*  SVGA3dBool  */
    920    "v" "DIFFUSEMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
    921    "v" "SPECULARMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
    922    "v" "AMBIENTMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
    923    "v" "EMISSIVEMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
    924    "c" "TEXTUREFACTOR",                 /*  SVGA3dColor  */
    925    "f" "LOCALVIEWER",                   /*  SVGA3dBool  */
    926    "f" "SCISSORTESTENABLE",             /*  SVGA3dBool  */
    927    "c" "BLENDCOLOR",                    /*  SVGA3dColor  */
    928    "f" "STENCILENABLE2SIDED",           /*  SVGA3dBool  */
    929    "p" "CCWSTENCILFUNC",                /*  SVGA3dCmpFunc  */
    930    "s" "CCWSTENCILFAIL",                /*  SVGA3dStencilOp  */
    931    "s" "CCWSTENCILZFAIL",               /*  SVGA3dStencilOp  */
    932    "s" "CCWSTENCILPASS",                /*  SVGA3dStencilOp  */
    933    "*" "VERTEXBLEND",                   /*  SVGA3dVertexBlendFlags  */
    934    "r" "SLOPESCALEDEPTHBIAS",           /*  float  */
    935    "r" "DEPTHBIAS",                     /*  float  */
    936    "r" "OUTPUTGAMMA",                   /*  float  */
    937    "f" "ZVISIBLE",                      /*  SVGA3dBool  */
    938    "f" "LASTPIXEL",                     /*  SVGA3dBool  */
    939    "f" "CLIPPING",                      /*  SVGA3dBool  */
    940    "w" "WRAP0",                         /*  SVGA3dWrapFlags  */
    941    "w" "WRAP1",                         /*  SVGA3dWrapFlags  */
    942    "w" "WRAP2",                         /*  SVGA3dWrapFlags  */
    943    "w" "WRAP3",                         /*  SVGA3dWrapFlags  */
    944    "w" "WRAP4",                         /*  SVGA3dWrapFlags  */
    945    "w" "WRAP5",                         /*  SVGA3dWrapFlags  */
    946    "w" "WRAP6",                         /*  SVGA3dWrapFlags  */
    947    "w" "WRAP7",                         /*  SVGA3dWrapFlags  */
    948    "w" "WRAP8",                         /*  SVGA3dWrapFlags  */
    949    "w" "WRAP9",                         /*  SVGA3dWrapFlags  */
    950    "w" "WRAP10",                        /*  SVGA3dWrapFlags  */
    951    "w" "WRAP11",                        /*  SVGA3dWrapFlags  */
    952    "w" "WRAP12",                        /*  SVGA3dWrapFlags  */
    953    "w" "WRAP13",                        /*  SVGA3dWrapFlags  */
    954    "w" "WRAP14",                        /*  SVGA3dWrapFlags  */
    955    "w" "WRAP15",                        /*  SVGA3dWrapFlags  */
    956    "f" "MULTISAMPLEANTIALIAS",          /*  SVGA3dBool  */
    957    "x" "MULTISAMPLEMASK",               /*  uint32_t  */
    958    "f" "INDEXEDVERTEXBLENDENABLE",      /*  SVGA3dBool  */
    959    "r" "TWEENFACTOR",                   /*  float  */
    960    "f" "ANTIALIASEDLINEENABLE",         /*  SVGA3dBool  */
    961    "c" "COLORWRITEENABLE1",             /*  SVGA3dColorMask  */
    962    "c" "COLORWRITEENABLE2",             /*  SVGA3dColorMask  */
    963    "c" "COLORWRITEENABLE3",             /*  SVGA3dColorMask  */
    964    "f" "SEPARATEALPHABLENDENABLE",      /*  SVGA3dBool  */
    965    "b" "SRCBLENDALPHA",                 /*  SVGA3dBlendOp  */
    966    "b" "DSTBLENDALPHA",                 /*  SVGA3dBlendOp  */
    967    "e" "BLENDEQUATIONALPHA",            /*  SVGA3dBlendEquation  */
    968    "*" "TRANSPARENCYANTIALIAS",         /*  SVGA3dTransparencyAntialiasType  */
    969    "f" "LINEAA",                        /*  SVGA3dBool  */
    970    "r" "LINEWIDTH",                     /*  float  */
    971 };
    972 
    973 
    974 /**
    975  * Formats a SVGA3dRenderState structure as a string.
    976  *
    977  * @returns pszBuffer.
    978  * @param   pszBuffer       Output string buffer.
    979  * @param   cbBuffer        Size of output buffer.
    980  * @param   pRenderState    The SVGA3d render state to format.
    981  */
    982 char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
    983 {
    984     uint32_t iState = pRenderState->state;
    985     if (iState != SVGA3D_RS_INVALID)
    986     {
    987         if (iState < RT_ELEMENTS(g_apszRenderStateNamesAndType))
    988         {
    989             const char *pszName = g_apszRenderStateNamesAndType[iState];
    990             char const  chType  = *pszName++;
    991 
    992             union
    993             {
    994                uint32_t  u;
    995                float     r;
    996                SVGA3dColorMask Color;
    997             } uValue;
    998             uValue.u = pRenderState->uintValue;
    999 
    1000             switch (chType)
    1001             {
    1002                 case 'f':
    1003                     if (uValue.u == 0)
    1004                         RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
    1005                     else if (uValue.u == 1)
    1006                         RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
    1007                     else
    1008                         RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
    1009                     break;
    1010                 case 'x':
    1011                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
    1012                     break;
    1013                 case 'r':
    1014                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
    1015                                 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
    1016                     break;
    1017                 case 'c': //SVGA3dColor, SVGA3dColorMask
    1018                     RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
    1019                                 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
    1020                     break;
    1021                 case 'w': //SVGA3dWrapFlags
    1022                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
    1023                                 uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
    1024                     break;
    1025                 default:
    1026                     AssertFailed();
    1027                 case 'b': //SVGA3dBlendOp
    1028                 case 'e': //SVGA3dBlendEquation
    1029                 case 'p': //SVGA3dCmpFunc
    1030                 case 's': //SVGA3dStencilOp
    1031                 case 'v': //SVGA3dVertexMaterial
    1032                 case '*':
    1033                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
    1034                     break;
    1035             }
    1036         }
    1037         else
    1038             RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
    1039     }
    1040     else
    1041         RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
    1042     return pszBuffer;
    1043 }
    1044 
    1045 /**
    1046  * Texture state names with type prefix.
    1047  */
    1048 static const char * const g_apszTextureStateNamesAndType[] =
    1049 {
    1050     "*" "INVALID",                      /*  invalid  */
    1051     "x" "BIND_TEXTURE",                 /*  SVGA3dSurfaceId  */
    1052     "m" "COLOROP",                      /*  SVGA3dTextureCombiner  */
    1053     "a" "COLORARG1",                    /*  SVGA3dTextureArgData  */
    1054     "a" "COLORARG2",                    /*  SVGA3dTextureArgData  */
    1055     "m" "ALPHAOP",                      /*  SVGA3dTextureCombiner  */
    1056     "a" "ALPHAARG1",                    /*  SVGA3dTextureArgData  */
    1057     "a" "ALPHAARG2",                    /*  SVGA3dTextureArgData  */
    1058     "e" "ADDRESSU",                     /*  SVGA3dTextureAddress  */
    1059     "e" "ADDRESSV",                     /*  SVGA3dTextureAddress  */
    1060     "l" "MIPFILTER",                    /*  SVGA3dTextureFilter  */
    1061     "l" "MAGFILTER",                    /*  SVGA3dTextureFilter  */
    1062     "m" "MINFILTER",                    /*  SVGA3dTextureFilter  */
    1063     "c" "BORDERCOLOR",                  /*  SVGA3dColor  */
    1064     "r" "TEXCOORDINDEX",                /*  uint32_t  */
    1065     "t" "TEXTURETRANSFORMFLAGS",        /*  SVGA3dTexTransformFlags  */
    1066     "g" "TEXCOORDGEN",                  /*  SVGA3dTextureCoordGen  */
    1067     "r" "BUMPENVMAT00",                 /*  float  */
    1068     "r" "BUMPENVMAT01",                 /*  float  */
    1069     "r" "BUMPENVMAT10",                 /*  float  */
    1070     "r" "BUMPENVMAT11",                 /*  float  */
    1071     "x" "TEXTURE_MIPMAP_LEVEL",         /*  uint32_t  */
    1072     "r" "TEXTURE_LOD_BIAS",             /*  float  */
    1073     "x" "TEXTURE_ANISOTROPIC_LEVEL",    /*  uint32_t  */
    1074     "e" "ADDRESSW",                     /*  SVGA3dTextureAddress  */
    1075     "r" "GAMMA",                        /*  float  */
    1076     "r" "BUMPENVLSCALE",                /*  float  */
    1077     "r" "BUMPENVLOFFSET",               /*  float  */
    1078     "a" "COLORARG0",                    /*  SVGA3dTextureArgData  */
    1079     "a" "ALPHAARG0"                     /*  SVGA3dTextureArgData */
    1080 };
    1081 
    1082 /**
    1083  * Formats a SVGA3dTextureState structure as a string.
    1084  *
    1085  * @returns pszBuffer.
    1086  * @param   pszBuffer       Output string buffer.
    1087  * @param   cbBuffer        Size of output buffer.
    1088  * @param   pTextureState   The SVGA3d texture state to format.
    1089  */
    1090 char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
    1091 {
    1092     /*
    1093      * Format the stage first.
    1094      */
    1095     char  *pszRet    = pszBuffer;
    1096     size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
    1097     if (cchPrefix < cbBuffer)
    1098     {
    1099         cbBuffer  -= cchPrefix;
    1100         pszBuffer += cchPrefix;
    1101     }
    1102     else
    1103         cbBuffer = 0;
    1104 
    1105     /*
    1106      * Format the name and value.
    1107      */
    1108     uint32_t iName = pTextureState->name;
    1109     if (iName != SVGA3D_TS_INVALID)
    1110     {
    1111         if (iName < RT_ELEMENTS(g_apszTextureStateNamesAndType))
    1112         {
    1113             const char *pszName = g_apszTextureStateNamesAndType[iName];
    1114             char        chType  = *pszName++;
    1115 
    1116             union
    1117             {
    1118                uint32_t  u;
    1119                float     r;
    1120                SVGA3dColorMask Color;
    1121             } uValue;
    1122             uValue.u = pTextureState->value;
    1123 
    1124             switch (chType)
    1125             {
    1126                 case 'x':
    1127                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
    1128                     break;
    1129 
    1130                 case 'r':
    1131                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
    1132                                 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
    1133                     break;
    1134 
    1135                 case 'a': //SVGA3dTextureArgData
    1136                 {
    1137                     static const char * const s_apszValues[] =
    1138                     {
    1139                         "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
    1140                     };
    1141                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1142                                           "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1143                     break;
    1144                 }
    1145 
    1146                 case 'c': //SVGA3dColor, SVGA3dColorMask
    1147                     RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
    1148                                 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
    1149                     break;
    1150 
    1151                 case 'e': //SVGA3dTextureAddress
    1152                 {
    1153                     static const char * const s_apszValues[] =
    1154                     {
    1155                         "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
    1156                     };
    1157                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1158                                           "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1159                     break;
    1160                 }
    1161 
    1162                 case 'l': //SVGA3dTextureFilter
    1163                 {
    1164                     static const char * const s_apszValues[] =
    1165                     {
    1166                         "NONE", "NEAREST", "LINEAR",  "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
    1167                     };
    1168                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1169                                           "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1170                     break;
    1171                 }
    1172 
    1173                 case 'g': //SVGA3dTextureCoordGen
    1174                 {
    1175                     static const char * const s_apszValues[] =
    1176                     {
    1177                         "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
    1178                     };
    1179                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1180                                           "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1181                     break;
    1182                 }
    1183 
    1184                 case 'm': //SVGA3dTextureCombiner
    1185                 {
    1186                     static const char * const s_apszValues[] =
    1187                     {
    1188                         "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
    1189                         "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
    1190                         "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
    1191                         "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
    1192                         "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
    1193                     };
    1194                     vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
    1195                                           "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
    1196                     break;
    1197                 }
    1198 
    1199                 default:
    1200                     AssertFailed();
    1201                     RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
    1202                     break;
    1203             }
    1204         }
    1205         else
    1206             RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
    1207     }
    1208     else
    1209         RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
    1210     return pszRet;
    1211 }
    1212 
    1213 
    1214304
    1215305
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp

    r57082 r57149  
    3333#include <iprt/avl.h>
    3434
    35 #include <VBox/VMMDev.h>
    36 #include <VBox/VBoxVideo.h>
    37 #include <VBox/bioslogo.h>
     35#include <VBox/VBoxVideo.h> /* required by DevVGA.h */
    3836
    3937/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
     
    4240#include "DevVGA-SVGA.h"
    4341#include "DevVGA-SVGA3d.h"
    44 #include "vmsvga/svga_reg.h"
    45 #include "vmsvga/svga3d_reg.h"
    46 #include "vmsvga/svga3d_shaderdefs.h"
    47 
    48 #include <d3d9.h>
     42#include "DevVGA-SVGA3d-internal.h"
    4943
    5044/* Enable to disassemble defined shaders. */
     
    5751#endif
    5852
     53
     54/*******************************************************************************
     55*   Defined Constants And Macros                                               *
     56*******************************************************************************/
    5957/* Enable to render the result of DrawPrimitive in a seperate window. */
    6058//#define DEBUG_GFX_WINDOW
    6159
    62 /* Enable to use Wine to convert D3D to opengl */
    63 //#define VBOX_VMSVGA3D_WITH_OPENGL
    64 
    6560#define FOURCC_INTZ     (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z')
    6661#define FOURCC_NULL     (D3DFORMAT)MAKEFOURCC('N', 'U', 'L', 'L')
     62
    6763
    6864/*******************************************************************************
    6965*   Structures and Typedefs                                                    *
    7066*******************************************************************************/
    71 
    72 typedef struct
    73 {
    74     SVGA3dSize              size;
    75     uint32_t                cbSurface;
    76     uint32_t                cbSurfacePitch;
    77     void                   *pSurfaceData;
    78     bool                    fDirty;
    79 } VMSVGA3DMIPMAPLEVEL, *PVMSVGA3DMIPMAPLEVEL;
    80 
    81 /**
    82  * SSM descriptor table for the VMSVGA3DMIPMAPLEVEL structure.
    83  */
    84 static SSMFIELD const g_aVMSVGA3DMIPMAPLEVELFields[] =
    85 {
    86     SSMFIELD_ENTRY(                 VMSVGA3DMIPMAPLEVEL, size),
    87     SSMFIELD_ENTRY(                 VMSVGA3DMIPMAPLEVEL, cbSurface),
    88     SSMFIELD_ENTRY(                 VMSVGA3DMIPMAPLEVEL, cbSurfacePitch),
    89     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DMIPMAPLEVEL, pSurfaceData),
    90     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DMIPMAPLEVEL, fDirty),
    91     SSMFIELD_ENTRY_TERM()
    92 };
    93 
    94 typedef struct
    95 {
    96     /* Key is context id. */
    97     AVLU32NODECORE          Core;
    98     union
    99     {
    100         IDirect3DSurface9          *pSurface;
    101         IDirect3DTexture9          *pTexture;
    102         IDirect3DCubeTexture9      *pCubeTexture;
    103     } u;
    104 } VMSVGA3DSHAREDSURFACE, *PVMSVGA3DSHAREDSURFACE;
    105 
    106 typedef struct
    107 {
    108     uint32_t                id;
    109     uint32_t                idAssociatedContext;
    110     uint32_t                flags;
    111     SVGA3dSurfaceFormat     format;
    112     SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
    113     uint32_t                cFaces;
    114     PVMSVGA3DMIPMAPLEVEL    pMipmapLevels;
    115     uint32_t                multiSampleCount;
    116     SVGA3dTextureFilter     autogenFilter;
    117     D3DFORMAT               formatD3D;
    118     DWORD                   fUsageD3D;
    119     D3DMULTISAMPLE_TYPE     multiSampleTypeD3D;
    120     uint32_t                cbBlock;        /* block/pixel size in bytes */
    121     /* Dirty state; surface was manually updated. */
    122     bool                    fDirty;
    123     /* Handle for shared objects (currently only textures & render targets). */
    124     HANDLE                  hSharedObject;
    125     /** Event query inserted after each GPU operation that updates or uses this surface. */
    126     IDirect3DQuery9        *pQuery;
    127     union
    128     {
    129         IDirect3DSurface9          *pSurface;
    130         IDirect3DCubeTexture9      *pCubeTexture;
    131         IDirect3DIndexBuffer9      *pIndexBuffer;
    132         IDirect3DTexture9          *pTexture;
    133         IDirect3DVertexBuffer9     *pVertexBuffer;
    134     } u;
    135     union
    136     {
    137         IDirect3DTexture9          *pTexture;
    138     } bounce;
    139     AVLU32TREE              pSharedObjectTree;
    140     bool                    fStencilAsTexture;
    141 } VMSVGA3DSURFACE, *PVMSVGA3DSURFACE;
    142 
    143 /**
    144  * SSM descriptor table for the VMSVGA3DSURFACE structure.
    145  */
    146 static SSMFIELD const g_aVMSVGA3DSURFACEFields[] =
    147 {
    148     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, id),
    149     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idAssociatedContext),
    150     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, flags),
    151     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format),
    152     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, faces),
    153     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cFaces),
    154     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, pMipmapLevels),
    155     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, multiSampleCount),
    156     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, autogenFilter),
    157     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format),
    158     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, formatD3D),
    159     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fUsageD3D),
    160     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, multiSampleTypeD3D),
    161     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, cbBlock),
    162     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fDirty),
    163     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, hSharedObject),
    164     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, pQuery),
    165     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, u.pSurface),
    166     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSURFACE, bounce.pTexture),
    167     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, pSharedObjectTree),
    168     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSURFACE, fStencilAsTexture),
    169     SSMFIELD_ENTRY_TERM()
    170 };
    171 
    172 typedef struct
    173 {
    174     uint32_t                        id;
    175     uint32_t                        cid;
    176     SVGA3dShaderType                type;
    177     uint32_t                        cbData;
    178     void                           *pShaderProgram;
    179     union
    180     {
    181         IDirect3DVertexShader9     *pVertexShader;
    182         IDirect3DPixelShader9      *pPixelShader;
    183     } u;
    184 } VMSVGA3DSHADER, *PVMSVGA3DSHADER;
    185 
    186 /**
    187  * SSM descriptor table for the VMSVGA3DSHADER structure.
    188  */
    189 static SSMFIELD const g_aVMSVGA3DSHADERFields[] =
    190 {
    191     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, id),
    192     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, cid),
    193     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, type),
    194     SSMFIELD_ENTRY(                 VMSVGA3DSHADER, cbData),
    195     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, pShaderProgram),
    196     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSHADER, u.pVertexShader),
    197     SSMFIELD_ENTRY_TERM()
    198 };
    199 
    200 typedef struct
    201 {
    202     bool        fValid;
    203     float       matrix[16];
    204 } VMSVGATRANSFORMSTATE, *PVMSVGATRANSFORMSTATE;
    205 
    206 typedef struct
    207 {
    208     bool            fValid;
    209     SVGA3dMaterial  material;
    210 } VMSVGAMATERIALSTATE, *PVMSVGAMATERIALSTATE;
    211 
    212 typedef struct
    213 {
    214     bool            fValid;
    215     float           plane[4];
    216 } VMSVGACLIPPLANESTATE, *PVMSVGACLIPPLANESTATE;
    217 
    218 typedef struct
    219 {
    220     bool            fEnabled;
    221     bool            fValidData;
    222     SVGA3dLightData data;
    223 } VMSVGALIGHTSTATE, *PVMSVGALIGHTSTATE;
    224 
    225 typedef struct
    226 {
    227     bool                    fValid;
    228     SVGA3dShaderConstType   ctype;
    229     uint32_t                value[4];
    230 } VMSVGASHADERCONST, *PVMSVGASHADERCONST;
    231 
    232 /**
    233  * SSM descriptor table for the VMSVGASHADERCONST structure.
    234  */
    235 static SSMFIELD const g_aVMSVGASHADERCONSTFields[] =
    236 {
    237     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, fValid),
    238     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, ctype),
    239     SSMFIELD_ENTRY(                 VMSVGASHADERCONST, value),
    240     SSMFIELD_ENTRY_TERM()
    241 };
    242 
    243 #define VMSVGA3D_UPDATE_SCISSORRECT     RT_BIT(0)
    244 #define VMSVGA3D_UPDATE_ZRANGE          RT_BIT(1)
    245 #define VMSVGA3D_UPDATE_VIEWPORT        RT_BIT(2)
    246 #define VMSVGA3D_UPDATE_VERTEXSHADER    RT_BIT(3)
    247 #define VMSVGA3D_UPDATE_PIXELSHADER     RT_BIT(4)
    248 #define VMSVGA3D_UPDATE_TRANSFORM       RT_BIT(5)
    249 #define VMSVGA3D_UPDATE_MATERIAL        RT_BIT(6)
    250 
    251 typedef struct VMSVGA3DCONTEXT
    252 {
    253     uint32_t                id;
    254 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
    255     IDirect3DDevice9       *pDevice;
    256 #else
    257     IDirect3DDevice9Ex     *pDevice;
    258 #endif
    259     HWND                    hwnd;
    260     /* Current active render target (if any) */
    261     uint32_t                sidRenderTarget;
    262     /* Current selected texture surfaces (if any) */
    263     uint32_t                aSidActiveTexture[SVGA3D_MAX_TEXTURE_STAGE];
    264     /* Per context pixel and vertex shaders. */
    265     uint32_t                cPixelShaders;
    266     PVMSVGA3DSHADER         paPixelShader;
    267     uint32_t                cVertexShaders;
    268     PVMSVGA3DSHADER         paVertexShader;
    269     /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
    270     struct
    271     {
    272         uint32_t                u32UpdateFlags;
    273 
    274         SVGA3dRenderState       aRenderState[SVGA3D_RS_MAX];
    275         SVGA3dTextureState      aTextureState[SVGA3D_MAX_TEXTURE_STAGE][SVGA3D_TS_MAX];
    276         VMSVGATRANSFORMSTATE    aTransformState[SVGA3D_TRANSFORM_MAX];
    277         VMSVGAMATERIALSTATE     aMaterial[SVGA3D_FACE_MAX];
    278         VMSVGACLIPPLANESTATE    aClipPlane[SVGA3D_CLIPPLANE_MAX];
    279         VMSVGALIGHTSTATE        aLightData[SVGA3D_MAX_LIGHTS];
    280 
    281         uint32_t                aRenderTargets[SVGA3D_RT_MAX];
    282         SVGA3dRect              RectScissor;
    283         SVGA3dRect              RectViewPort;
    284         SVGA3dZRange            zRange;
    285         uint32_t                shidPixel;
    286         uint32_t                shidVertex;
    287 
    288         uint32_t                cPixelShaderConst;
    289         PVMSVGASHADERCONST      paPixelShaderConst;
    290         uint32_t                cVertexShaderConst;
    291         PVMSVGASHADERCONST      paVertexShaderConst;
    292     } state;
    293 } VMSVGA3DCONTEXT, *PVMSVGA3DCONTEXT;
    294 
    295 /**
    296  * SSM descriptor table for the VMSVGA3DCONTEXT structure.
    297  */
    298 static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
    299 {
    300     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, id),
    301     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, pDevice),
    302     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, hwnd),
    303     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, sidRenderTarget),
    304     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DCONTEXT, aSidActiveTexture),
    305     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, cPixelShaders),
    306     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, paPixelShader),
    307     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, cVertexShaders),
    308     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, paVertexShader),
    309     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.u32UpdateFlags),
    310 
    311     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aRenderState),
    312     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aTextureState),
    313     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aTransformState),
    314     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aMaterial),
    315     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aClipPlane),
    316     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aLightData),
    317 
    318     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.aRenderTargets),
    319     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.RectScissor),
    320     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.RectViewPort),
    321     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.zRange),
    322     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.shidPixel),
    323     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.shidVertex),
    324     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.cPixelShaderConst),
    325     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, state.paPixelShaderConst),
    326     SSMFIELD_ENTRY(                 VMSVGA3DCONTEXT, state.cVertexShaderConst),
    327     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DCONTEXT, state.paVertexShaderConst),
    328     SSMFIELD_ENTRY_TERM()
    329 };
    330 
    331 typedef struct VMSVGA3DSTATE
    332 {
    333 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
    334     IDirect3D9             *pD3D9;
    335 #else
    336     IDirect3D9Ex           *pD3D9;
    337 #endif
    338     D3DCAPS9                caps;
    339 
    340     /** Window Thread. */
    341     R3PTRTYPE(RTTHREAD)     pWindowThread;
    342     HMODULE                 hInstance;
    343     /** Window request semaphore. */
    344     RTSEMEVENT              WndRequestSem;
    345 
    346     /** The size of papContexts. */
    347     uint32_t                cContexts;
    348     /** The size of papSurfaces. */
    349     uint32_t                cSurfaces;
    350     /** Contexts indexed by ID.  Grown as needed. */
    351     PVMSVGA3DCONTEXT       *papContexts;
    352     /** Surfaces indexed by ID.  Grown as needed. */
    353     PVMSVGA3DSURFACE       *papSurfaces;
    354 
    355     bool                    fSupportedSurfaceINTZ;
    356     bool                    fSupportedSurfaceNULL;
    357 } VMSVGA3DSTATE;
    358 
    359 /**
    360  * SSM descriptor table for the VMSVGA3DSTATE structure.
    361  */
    362 static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
    363 {
    364     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, pD3D9),
    365     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, caps),
    366 
    367     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, pWindowThread),
    368     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, hInstance),
    369     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, WndRequestSem),
    370 
    371     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cContexts),
    372     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cSurfaces),
    373     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papContexts),
    374     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papSurfaces),
    375     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, fSupportedSurfaceINTZ),
    376     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, fSupportedSurfaceNULL),
    377     SSMFIELD_ENTRY_TERM()
    378 };
    37967
    38068typedef struct
     
    38573} VMSVGA3DFORMATSUPPORT;
    38674
    387 VMSVGA3DFORMATSUPPORT aFormatSupport[] =
     75
     76/*******************************************************************************
     77*   Global Variables                                                           *
     78*******************************************************************************/
     79static VMSVGA3DFORMATSUPPORT const g_aFormatSupport[] =
    38880{
    38981    {
     
    444136};
    445137
    446 VMSVGA3DFORMATSUPPORT aFeatureReject[] =
     138static VMSVGA3DFORMATSUPPORT const  g_aFeatureReject[] =
    447139{
    448140    {
     
    463155};
    464156
     157
     158/*******************************************************************************
     159*   Internal Functions                                                         *
     160*******************************************************************************/
    465161static void vmsvgaDumpD3DCaps(D3DCAPS9 *pCaps);
    466 static int vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
    467 
    468 RT_C_DECLS_BEGIN
    469 RT_C_DECLS_END
     162static int  vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
     163
     164
    470165
    471166int vmsvga3dInit(PVGASTATE pThis)
     
    505200        return VINF_SUCCESS;    /* already initialized (load state) */
    506201
    507 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
     202#ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    508203    pState->pD3D9 = Direct3DCreate9(D3D_SDK_VERSION);
    509204    AssertReturn(pState->pD3D9, VERR_INTERNAL_ERROR);
     
    630325}
    631326
    632 /* Shared functions that depend on private structure definitions. */
    633 #define VMSVGA3D_DIRECT3D
    634 #include "DevVGA-SVGA3d-shared.h"
    635 
    636327
    637328static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_t idx3dCaps, D3DFORMAT format)
     
    649340                                            format);
    650341
    651     for (unsigned i = 0; i < RT_ELEMENTS(aFormatSupport); i++)
     342    for (unsigned i = 0; i < RT_ELEMENTS(g_aFormatSupport); i++)
    652343    {
    653344        hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
    654345                                                D3DDEVTYPE_HAL,
    655346                                                D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
    656                                                 aFormatSupport[i].Usage,
    657                                                 aFormatSupport[i].ResourceType,
     347                                                g_aFormatSupport[i].Usage,
     348                                                g_aFormatSupport[i].ResourceType,
    658349                                                format);
    659350        if (hr == D3D_OK)
    660             result |= aFormatSupport[i].FormatOp;
     351            result |= g_aFormatSupport[i].FormatOp;
    661352    }
    662353
     
    664355    if (result)
    665356    {
    666         for (unsigned i = 0; i < RT_ELEMENTS(aFeatureReject); i++)
     357        for (unsigned i = 0; i < RT_ELEMENTS(g_aFeatureReject); i++)
    667358        {
    668359            hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
    669360                                                    D3DDEVTYPE_HAL,
    670361                                                    D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
    671                                                     aFeatureReject[i].Usage,
    672                                                     aFeatureReject[i].ResourceType,
     362                                                    g_aFeatureReject[i].Usage,
     363                                                    g_aFeatureReject[i].ResourceType,
    673364                                                    format);
    674365            if (hr != D3D_OK)
    675                 result |= aFeatureReject[i].FormatOp;
    676         }
    677     }
    678 
    679     /* @todo missing:
     366                result |= g_aFeatureReject[i].FormatOp;
     367        }
     368    }
     369
     370    /** @todo missing:
    680371     *
    681372     * SVGA3DFORMAT_OP_PIXELSIZE
     
    17481439}
    17491440
    1750 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
     1441#ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    17511442#define vmsvga3dSurfaceTrackUsage(a, b, c)
    17521443#define vmsvga3dSurfaceFlush(a, b)
    1753 #else
     1444#else /* !VBOX_VMSVGA3D_WITH_WINE_OPENGL */
    17541445/* Inject a query event into the D3D pipeline so we can check when usage of this surface has finished.
    17551446 * (D3D does not synchronize shared surface usage)
     
    18141505    return VINF_SUCCESS;
    18151506}
    1816 #endif /* VBOX_VMSVGA3D_WITH_OPENGL */
     1507#endif /* !VBOX_VMSVGA3D_WITH_WINE_OPENGL */
    18171508
    18181509int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
     
    18851576        vmsvga3dSurfaceFlush(pThis, pSurfaceDest);
    18861577
    1887 #ifndef VBOX_VMSVGA3D_WITH_OPENGL
     1578#ifndef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    18881579        if (    fSrcTexture
    18891580            &&  pSurfaceSrc->idAssociatedContext != cid)
     
    30102701    PresParam.PresentationInterval          = D3DPRESENT_INTERVAL_IMMEDIATE;
    30112702
    3012 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
     2703#ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    30132704    hr = pState->pD3D9->CreateDevice(D3DADAPTER_DEFAULT,
    30142705                                     D3DDEVTYPE_HAL,
     
    31632854}
    31642855
    3165 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
     2856#ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    31662857#define vmsvga3dContextTrackUsage(pThis, pContext)
    31672858#else
     
    33473038            PresParam.PresentationInterval          = D3DPRESENT_INTERVAL_IMMEDIATE;;
    33483039
    3349 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
     3040#ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    33503041            hr = pContext->pDevice->Reset(&PresParam);
    33513042            AssertMsgReturn(hr == D3D_OK, ("vmsvga3dChangeMode: Reset failed with %x\n", hr), VERR_INTERNAL_ERROR);
     
    44874178            }
    44884179
    4489 #ifndef VBOX_VMSVGA3D_WITH_OPENGL
     4180#ifndef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    44904181            if (pRenderTarget->idAssociatedContext != cid)
    44914182            {
     
    48504541                }
    48514542
    4852 #ifndef VBOX_VMSVGA3D_WITH_OPENGL
     4543#ifndef VBOX_VMSVGA3D_WITH_WINE_OPENGL
    48534544                if (pSurface->idAssociatedContext != cid)
    48544545                {
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h

    r57082 r57149  
     1/* $Id$ */
    12/** @file
    23 * DevVMWare - VMWare SVGA device - 3D part.
     
    4344/* DevVGA-SVGA.cpp: */
    4445void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR);
    45 int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pDest, int32_t cbDestPitch,
    46                       SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight);
     46int  vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pDest, int32_t cbDestPitch,
     47                       SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight);
    4748void vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(PVGASTATE pThis, uint32_t sid);
    4849
  • trunk/src/VBox/Devices/Makefile.kmk

    r56967 r57149  
    256256 ifdef VBOX_WITH_VMSVGA3D
    257257  VBoxDD_DEFS           += VBOX_WITH_VMSVGA3D
    258   VBoxDD_SOURCES        += Graphics/DevVGA-SVGA3d-shared.cpp
     258  VBoxDD_SOURCES        += \
     259        Graphics/DevVGA-SVGA3d-info.cpp \
     260        Graphics/DevVGA-SVGA3d-shared.cpp \
     261        Graphics/DevVGA-SVGA3d-savedstate.cpp
    259262  if  "$(KBUILD_TARGET)" == "win" && !defined(VBOX_WITH_VMSVGA3D_USE_OPENGL)
     263   VBoxDD_DEFS          += VMSVGA3D_DIRECT3D
    260264   VBoxDD_SOURCES       += Graphics/DevVGA-SVGA3d-win.cpp
    261265   VBoxDD_LIBS.win      += d3d9.lib $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
    262266   VBoxDD_LDFLAGS.win   += /DELAYLOAD:d3d9.dll
    263267  else
     268   VBoxDD_DEFS          += VMSVGA3D_OPENGL
    264269   VBoxDD_SOURCES       += \
    265270        Graphics/DevVGA-SVGA3d-ogl.cpp \
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