VirtualBox

Ignore:
Timestamp:
Jul 22, 2011 1:26:19 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73064
Message:

wddm/3d: 1. fix invalid visible rectreporting on swapchain destruction 2. single context for wine (disabled so far), 3 wine & 3d driver bugfixes

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp

    r37907 r38112  
    10231023}
    10241024
     1025#define VBOX_WDDM_SHRC_WO_NOTIFY
    10251026static BOOLEAN vboxWddmDalCheckAdd(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOLEAN fWrite)
    10261027{
    10271028    if (!pAlloc->hSharedHandle /* only shared resources matter */
    1028             || !fWrite) /* only write op matter */
    1029     {
     1029#ifdef VBOX_WDDM_SHRC_WO_NOTIFY
     1030            || !fWrite /* only write op matter */
     1031#endif
     1032            )
     1033    {
     1034#ifdef VBOX_WDDM_SHRC_WO_NOTIFY
    10301035        Assert(!pAlloc->DirtyAllocListEntry.pNext || (!fWrite && pAlloc->hSharedHandle && pAlloc->fDirtyWrite));
     1036#else
     1037        Assert(!pAlloc->DirtyAllocListEntry.pNext);
     1038#endif
    10311039        return FALSE;
    10321040    }
     
    17081716
    17091717    Assert(cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs || !cAllocsKm);
    1710 
     1718    HRESULT hr = S_OK;
    17111719    if (cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs)
    17121720    {
     
    17171725        DdiEscape.pPrivateDriverData = &Buf.SwapchainInfo;
    17181726        DdiEscape.PrivateDriverDataSize = RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[Buf.SwapchainInfo.SwapchainInfo.cAllocs]);
    1719         HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
     1727        hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
    17201728#ifdef DEBUG_misha
    17211729        Assert(hr == S_OK);
     
    17251733            pSwapchain->hSwapchainKm = Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm;
    17261734        }
    1727 
    1728         return hr;
    1729     }
     1735    }
     1736
    17301737    return S_OK;
    17311738}
     
    17771784        pSwapchain->aRTs[i].pAlloc->pSwapchain = NULL;
    17781785    }
     1786
     1787    /* first do a Km destroy to ensure all km->um region submissions are completed */
     1788    vboxWddmSwapchainKmDestroy(pDevice, pSwapchain);
     1789    vboxDispMpInternalCancel(&pDevice->DefaultContext, pSwapchain);
    17791790    vboxWddmSwapchainDestroyIf(pDevice, pSwapchain);
    1780     vboxWddmSwapchainKmDestroy(pDevice, pSwapchain);
    17811791    vboxWddmSwapchainInit(pSwapchain);
    17821792}
     
    28432853                    if (hr == S_OK)
    28442854                    {
    2845                         vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
    2846                         return TRUE;
     2855                        hr = vboxDispMpInternalInit();
     2856                        Assert(hr == S_OK);
     2857                        if (hr == S_OK)
     2858                        {
     2859                            vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
     2860                            return TRUE;
     2861                        }
    28472862                    }
    28482863                    VbglR3Term();
     
    28572872            vboxVDbgVEHandlerUnregister();
    28582873#endif
    2859             HRESULT hr = vboxDispCmTerm();
     2874            HRESULT hr = vboxDispMpInternalTerm();
    28602875            Assert(hr == S_OK);
    28612876            if (hr == S_OK)
    28622877            {
    2863                 VbglR3Term();
    2864                 /// @todo RTR3Term();
    2865                 return TRUE;
     2878                hr = vboxDispCmTerm();
     2879                Assert(hr == S_OK);
     2880                if (hr == S_OK)
     2881                {
     2882                    VbglR3Term();
     2883                    /// @todo RTR3Term();
     2884                    return TRUE;
     2885                }
    28662886            }
    28672887
     
    32993319            pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
    33003320
     3321            VBOXVDBG_BREAK_SHARED(pRc);
    33013322            VBOXVDBG_DUMP_SETTEXTURE(pRc);
    33023323        }
     
    33053326            pD3DIfTex = (IDirect3DCubeTexture9*)pRc->aAllocations[0].pD3DIf;
    33063327
     3328            VBOXVDBG_BREAK_SHARED(pRc);
    33073329            VBOXVDBG_DUMP_SETTEXTURE(pRc);
    33083330        }
     
    34333455    HRESULT hr = S_OK;
    34343456
    3435     VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice9If);
     3457    VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
    34363458
    34373459    if (!pDevice->cStreamSources)
     
    34913513    vboxWddmDalCheckAddRts(pDevice);
    34923514
    3493     VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice9If);
     3515    VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
    34943516
    34953517    vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
     
    35063528
    35073529    IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
    3508     VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice9If);
     3530    VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
    35093531
    35103532#ifdef DEBUG
     
    35423564    vboxWddmDalCheckAddRts(pDevice);
    35433565
    3544     VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice9If);
     3566    VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
    35453567
    35463568    vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
     
    36143636    hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
    36153637#else
    3616     VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice9If);
     3638    VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
    36173639
    36183640#ifdef DEBUG
     
    36623684    vboxWddmDalCheckAddRts(pDevice);
    36633685
    3664     VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice9If);
     3686    VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
    36653687
    36663688    Assert(hr == S_OK);
     
    41914213                    Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
    41924214                }
     4215
     4216                VBOXVDBG_DUMP_LOCK_ST(pData);
    41934217            }
    41944218        }
     
    44754499            Assert(pData->SubResourceIndex < pRc->cAllocations);
    44764500            PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
     4501
     4502            VBOXVDBG_DUMP_UNLOCK_ST(pData);
    44774503
    44784504            --pLockAlloc->LockInfo.cLocks;
     
    49935019                            Assert(!!(pResource->Flags.SharedResource) == !!(hSharedHandle));
    49945020                            pAllocation->hSharedHandle = hSharedHandle;
     5021#ifdef DEBUG_misha
     5022                            if (pResource->Flags.SharedResource)
     5023                            {
     5024                                vboxVDbgPrint(("\n\n********\nShared Texture pAlloc(0x%p) Handle(0x%x), (0n%d) CREATED, pid (0x%x), (0n%d)\n***********\n\n",
     5025                                        pAllocation, hSharedHandle, hSharedHandle, GetCurrentProcessId(), GetCurrentProcessId()));
     5026                            }
     5027#endif
    49955028                        }
    49965029
     
    53025335        {
    53035336            PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
     5337#ifdef DEBUG_misha
     5338            if (pAlloc->hSharedHandle)
     5339            {
     5340                vboxVDbgPrint(("\n\n********\nShared Texture pAlloc(0x%p) Handle(0x%x), (0n%d) DESTROYED, pid (0x%x), (0n%d)\n***********\n\n",
     5341                        pAlloc, pAlloc->hSharedHandle, pAlloc->hSharedHandle, GetCurrentProcessId(), GetCurrentProcessId()));
     5342            }
     5343#endif
    53045344            if (pAlloc->pD3DIf)
    53055345                pAlloc->pD3DIf->Release();
     
    55855625        vboxWddmDalNotifyChange(pDevice);
    55865626
    5587         VBOXVDBG_DUMP_FLUSH(pDevice->pDevice9If);
     5627        VBOXVDBG_DUMP_FLUSH(pDevice);
    55885628    }
    55895629    vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
     
    59706010                Assert(pSrcSurfIf);
    59716011
    5972                 VBOXVDBG_DUMP_BLT_ENTER(pSrcRc, pSrcSurfIf, &pData->SrcRect, pDstRc, pDstSurfIf, &pData->DstRect);
     6012                VBOXVDBG_BREAK_SHARED(pSrcRc);
     6013                VBOXVDBG_BREAK_SHARED(pDstRc);
     6014                VBOXVDBG_DUMP_BLT_ENTER(pSrcAlloc, pSrcSurfIf, &pData->SrcRect, pDstAlloc, pDstSurfIf, &pData->DstRect);
    59736015
    59746016                /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
     
    59816023                Assert(hr == S_OK);
    59826024
    5983                 VBOXVDBG_DUMP_BLT_LEAVE(pSrcRc, pSrcSurfIf, &pData->SrcRect, pDstRc, pDstSurfIf, &pData->DstRect);
     6025                VBOXVDBG_DUMP_BLT_LEAVE(pSrcAlloc, pSrcSurfIf, &pData->SrcRect, pDstAlloc, pDstSurfIf, &pData->DstRect);
    59846026
    59856027                pSrcSurfIf->Release();
     
    64536495    {
    64546496//    Assert(!pDevice->cScreens);
     6497        /* destroy the device first, since destroying PVBOXWDDMDISP_SWAPCHAIN would result in a device window termination */
     6498        if (pDevice->pDevice9If)
     6499        {
     6500            pDevice->pDevice9If->Release();
     6501        }
    64556502        vboxWddmSwapchainDestroyAll(pDevice);
    6456         if (pDevice->pDevice9If)
    6457         {
    6458             pDevice->pDevice9If->Release();
    6459         }
    64606503    }
    64616504
     
    68146857
    68156858#ifdef DEBUG_misha
    6816                     vboxVDbgPrint(("\n\n********\nShared Resource (0x%x), (0n%d) openned\n\n\n", hSharedHandle, hSharedHandle));
     6859                    vboxVDbgPrint(("\n\n********\nShared Texture pAlloc(0x%p) Handle(0x%x), (0n%d) OPENED, pid (0x%x), (0n%d)\n***********\n\n",
     6860                            pAllocation, hSharedHandle, hSharedHandle, GetCurrentProcessId(), GetCurrentProcessId()));
     6861
    68176862#endif
    68186863
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h

    r37840 r38112  
    207207    D3DDDI_LOCKFLAGS fFlags;
    208208    D3DLOCKED_RECT LockedRect;
     209#ifdef VBOXWDDMDISP_DEBUG
     210    PVOID pvData;
     211#endif
    209212} VBOXWDDMDISP_LOCKINFO;
    210213
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h

    r36867 r38112  
    3838#include "common/wddm/VBoxMPIf.h"
    3939#include "VBoxDispCm.h"
     40#include "VBoxDispMpInternal.h"
    4041#include "VBoxDispKmt.h"
    4142#ifdef VBOX_WITH_CRHGSMI
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp

    r36867 r38112  
    269269    if (!GetClassInfo(hInstance, VBOXDISPWND_NAME, &wc))
    270270    {
    271         wc.style = CS_OWNDC;
     271        wc.style = 0;//CS_OWNDC;
    272272        wc.lpfnWndProc = WindowProc;
    273273        wc.cbClsExtra = 0;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp

    r37870 r38112  
    5050
    5151#ifdef VBOXWDDMDISP_DEBUG
    52 DWORD g_VBoxVDbgFDumpSetTexture = 0;
    53 DWORD g_VBoxVDbgFDumpDrawPrim = 0;
    54 DWORD g_VBoxVDbgFDumpTexBlt = 0;
    55 DWORD g_VBoxVDbgFDumpBlt = 0;
    56 DWORD g_VBoxVDbgFDumpRtSynch = 0;
    57 DWORD g_VBoxVDbgFDumpFlush = 0;
    58 DWORD g_VBoxVDbgFDumpShared = 0;
     52#define VBOXWDDMDISP_DEBUG_DUMP_DEFAULT 1
     53DWORD g_VBoxVDbgFDumpSetTexture = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     54DWORD g_VBoxVDbgFDumpDrawPrim = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     55DWORD g_VBoxVDbgFDumpTexBlt = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     56DWORD g_VBoxVDbgFDumpBlt = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     57DWORD g_VBoxVDbgFDumpRtSynch = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     58DWORD g_VBoxVDbgFDumpFlush = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     59DWORD g_VBoxVDbgFDumpShared = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     60DWORD g_VBoxVDbgFDumpLock = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     61DWORD g_VBoxVDbgFDumpUnlock = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
     62
     63DWORD g_VBoxVDbgFBreakShared = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
    5964
    6065DWORD g_VBoxVDbgPid = 0;
     
    175180{
    176181    vboxVDbgDoDumpSurfRectByRc(pPrefix, pAlloc->pRc, pAlloc->iAlloc, pRect, pSuffix);
     182}
     183
     184VOID vboxVDbgDoPrintDumpCmd(const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
     185{
     186    vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
     187            pvData, width, height, bpp, pitch,
     188            pvData, width, height, bpp, pitch));
    177189}
    178190
     
    207219    {
    208220        UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
    209         vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
    210                 LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch,
    211                 LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch));
     221        vboxVDbgDoPrintDumpCmd(LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch);
    212222        if (pRect)
    213223        {
     
    215225            Assert(pRect->bottom > pRect->top);
    216226            vboxVDbgDoPrintRect("rect: ", pRect, "\n");
    217             vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
    218                     ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
    219                     pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch,
    220                     ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
    221                     pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch));
     227            vboxVDbgDoPrintDumpCmd(((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
     228                    pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch);
    222229        }
    223230        Assert(0);
     
    270277        {
    271278            UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
    272             vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
    273                     Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch,
    274                     Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
     279            vboxVDbgDoPrintDumpCmd(Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch);
    275280            if (pRect)
    276281            {
     
    278283                Assert(pRect->bottom > pRect->top);
    279284                vboxVDbgDoPrintRect("rect: ", pRect, "\n");
    280                 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
    281                         ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
    282                         pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch,
    283                         ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
    284                         pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
     285                vboxVDbgDoPrintDumpCmd(((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
     286                        pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch);
    285287            }
    286288
     
    386388            IDirect3DSurface9 *pSurf = (IDirect3DSurface9 *)pRc;
    387389            vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
     390            break;
    388391        }
    389392        default:
     
    398401}
    399402
     403VOID vboxVDbgDoDumpRcRectByAlloc(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DResource9 *pD3DIf, const RECT *pRect, const char* pSuffix)
     404{
     405    if (pPrefix)
     406        vboxVDbgPrint(("%s", pPrefix));
     407
     408    if (!pD3DIf)
     409    {
     410        pD3DIf = (IDirect3DResource9*)pAlloc->pD3DIf;
     411    }
     412
     413    vboxVDbgPrint(("Rc(0x%p), pAlloc(0x%x), pD3DIf(0x%p), SharedHandle(0x%p)\n", pAlloc->pRc, pAlloc, pD3DIf, pAlloc->pRc->aAllocations[0].hSharedHandle));
     414
     415    vboxVDbgDoDumpRcRect("", pD3DIf, pRect, pSuffix);
     416}
     417
    400418VOID vboxVDbgDoDumpRcRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, const RECT *pRect, const char* pSuffix)
    401419{
    402     vboxVDbgDoDumpRcRect(pPrefix, (IDirect3DResource9*)pRc->aAllocations[0].pD3DIf, pRect, pSuffix);
     420    vboxVDbgDoDumpRcRectByAlloc(pPrefix, &pRc->aAllocations[0], NULL, pRect, pSuffix);
    403421}
    404422
     
    408426}
    409427
    410 VOID vboxVDbgDoDumpRt(const char * pPrefix, IDirect3DDevice9 *pDevice, const char * pSuffix)
    411 {
    412     IDirect3DSurface9 *pRt;
    413     HRESULT hr = pDevice->GetRenderTarget(0, &pRt);
    414     Assert(hr == S_OK);
    415     if (hr == S_OK)
    416     {
    417         vboxVDbgDoDumpSurf(pPrefix, pRt, pSuffix);
     428VOID vboxVDbgDoDumpRt(const char * pPrefix, PVBOXWDDMDISP_DEVICE pDevice, const char * pSuffix)
     429{
     430    for (UINT i = 0; i < pDevice->cRTs; ++i)
     431    {
     432        IDirect3DSurface9 *pRt;
     433        PVBOXWDDMDISP_ALLOCATION pAlloc = pDevice->apRTs[i];
     434        IDirect3DDevice9 *pDeviceIf = pDevice->pDevice9If;
     435        HRESULT hr = pDeviceIf->GetRenderTarget(i, &pRt);
     436        Assert(hr == S_OK);
     437        if (hr == S_OK)
     438        {
     439//            Assert(pAlloc->pD3DIf == pRt);
     440            vboxVDbgDoDumpRcRectByAlloc(pPrefix, pAlloc, NULL, NULL, "\n");
     441            pRt->Release();
     442        }
     443        else
     444        {
     445            vboxVDbgPrint((__FUNCTION__": ERROR getting rt: 0x%x", hr));
     446        }
     447    }
     448}
     449
     450VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, const char * pSuffix, bool fBreak)
     451{
     452    if (pPrefix)
     453    {
     454        vboxVDbgPrint(("%s", pPrefix));
     455    }
     456
     457    Assert(!pAlloc->hSharedHandle);
     458
     459    UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
     460    uint32_t width, height, pitch;
     461    RECT Rect, *pRect;
     462    void *pvData;
     463    Assert(!pAlloc->LockInfo.fFlags.RangeValid);
     464    Assert(!pAlloc->LockInfo.fFlags.BoxValid);
     465    if (pAlloc->LockInfo.fFlags.AreaValid)
     466    {
     467        pRect = &pAlloc->LockInfo.Area;
     468        width = pAlloc->LockInfo.Area.left - pAlloc->LockInfo.Area.right;
     469        height = pAlloc->LockInfo.Area.bottom - pAlloc->LockInfo.Area.top;
    418470    }
    419471    else
    420472    {
    421         vboxVDbgPrint((__FUNCTION__": ERROR getting rt: 0x%x", hr));
    422     }
     473        width = pAlloc->SurfDesc.width;
     474        height = pAlloc->SurfDesc.height;
     475        Rect.top = 0;
     476        Rect.bottom = height;
     477        Rect.left = 0;
     478        Rect.right = width;
     479        pRect = &Rect;
     480    }
     481
     482    if (pAlloc->LockInfo.fFlags.NotifyOnly)
     483    {
     484        pitch = pAlloc->SurfDesc.pitch;
     485        pvData = ((uint8_t*)pAlloc->pvMem) + pitch*pRect->top + ((bpp*pRect->left) >> 3);
     486    }
     487    else
     488    {
     489        pvData = pAlloc->LockInfo.pvData;
     490    }
     491
     492    vboxVDbgPrint(("pRc(0x%p) iAlloc(%d), type(%d), cLocks(%d)\n", pAlloc->pRc, pAlloc->iAlloc, pAlloc->enmD3DIfType, pAlloc->LockInfo.cLocks));
     493
     494    vboxVDbgDoPrintDumpCmd(pvData, width, height, bpp, pitch);
     495
     496    if (fBreak)
     497    {
     498        Assert(0);
     499    }
     500
     501    if (pSuffix)
     502    {
     503        vboxVDbgPrint(("%s", pSuffix));
     504    }
     505
     506}
     507
     508VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, bool fBreak)
     509{
     510    const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource;
     511    const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
     512    pAlloc->LockInfo.pvData = pData->pSurfData;
     513    vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fBreak);
     514}
     515
     516VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, bool fBreak)
     517{
     518    const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource;
     519    const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
     520    vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fBreak);
    423521}
    424522
     
    426524{
    427525    Assert(pRc->cAllocations > iAlloc);
    428     PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
     526    const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
    429527    BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
    430528    BOOL bFrontBuf = FALSE;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h

    r37870 r38112  
    111111extern DWORD g_VBoxVDbgFDumpFlush;
    112112extern DWORD g_VBoxVDbgFDumpShared;
     113extern DWORD g_VBoxVDbgFDumpLock;
     114extern DWORD g_VBoxVDbgFDumpUnlock;
     115
     116extern DWORD g_VBoxVDbgFBreakShared;
    113117
    114118void vboxDispLogDrvF(char * szString, ...);
     
    126130VOID vboxVDbgDoDumpRcRect(const char * pPrefix, IDirect3DResource9 *pRc, const RECT *pRect, const char * pSuffix);
    127131VOID vboxVDbgDoDumpRcRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, const RECT *pRect, const char* pSuffix);
     132VOID vboxVDbgDoDumpRcRectByAlloc(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DResource9 *pD3DIf, const RECT *pRect, const char* pSuffix);
    128133VOID vboxVDbgDoDumpTex(const char * pPrefix, IDirect3DBaseTexture9 *pTexBase, const char * pSuffix);
    129 VOID vboxVDbgDoDumpRt(const char * pPrefix, IDirect3DDevice9 *pDevice, const char * pSuffix);
     134VOID vboxVDbgDoDumpRt(const char * pPrefix, struct VBOXWDDMDISP_DEVICE *pDevice, const char * pSuffix);
    130135
    131136void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix);
    132137void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix);
    133 VOID vboxVDbgDoDumpRtData(char * pPrefix, IDirect3DDevice9 *pDevice, char * pSuffix);
     138
     139VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, bool fBreak);
     140VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, bool fBreak);
     141
    134142
    135143extern DWORD g_VBoxVDbgPid;
     
    144152        )
    145153
     154#define VBOXVDBG_IS_BREAK_ALLOWED(_type) ( \
     155        g_VBoxVDbgFBreak##_type \
     156        && (g_VBoxVDbgFBreak##_type == 1 \
     157                || VBOXVDBG_IS_DUMP_ALLOWED_PID(g_VBoxVDbgFBreak##_type) \
     158           ) \
     159        )
     160
    146161#define VBOXVDBG_IS_DUMP_SHARED_ALLOWED(_pRc) (\
    147162        (_pRc)->RcDesc.fFlags.SharedResource \
     
    149164        )
    150165
     166#define VBOXVDBG_IS_BREAK_SHARED_ALLOWED(_pRc) (\
     167        (_pRc)->RcDesc.fFlags.SharedResource \
     168        && VBOXVDBG_IS_BREAK_ALLOWED(Shared) \
     169        )
     170
     171#define VBOXVDBG_BREAK_SHARED(_pRc) do { \
     172        if (VBOXVDBG_IS_BREAK_SHARED_ALLOWED(_pRc)) { \
     173            vboxVDbgPrint(("Break on shared access: Rc(0x%p), SharedHandle(0x%p)\n", (_pRc), (_pRc)->aAllocations[0].hSharedHandle)); \
     174            AssertFailed(); \
     175        } \
     176    } while (0)
     177
    151178#define VBOXVDBG_DUMP_DRAWPRIM_ENTER(_pDevice) do { \
    152179        if (VBOXVDBG_IS_DUMP_ALLOWED(DrawPrim)) \
     
    168195                ) \
    169196        { \
    170             vboxVDbgPrint(("== "__FUNCTION__": Texture Dump, SharedHandle(0x%p)\n", (_pRc)->aAllocations[0].hSharedHandle)); \
    171             vboxVDbgDoDumpRcRectByRc("", _pRc, NULL, "\n"); \
     197            vboxVDbgDoDumpRcRectByRc("== "__FUNCTION__": ", _pRc, NULL, "\n"); \
    172198        } \
    173199    } while (0)
     
    181207            RECT _DstRect; \
    182208            vboxWddmRectMoved(&_DstRect, (_pSrcRect), (_pDstPoint)->x, (_pDstPoint)->y); \
    183             vboxVDbgDoDumpRcRectByRc("==>"__FUNCTION__" Src:\n", (_pSrcRc), (_pSrcRect), "\n"); \
    184             vboxVDbgDoDumpRcRectByRc("==>"__FUNCTION__" Dst:\n", (_pDstRc), &_DstRect, "\n"); \
     209            vboxVDbgDoDumpRcRectByRc("==>"__FUNCTION__" Src: ", (_pSrcRc), (_pSrcRect), "\n"); \
     210            vboxVDbgDoDumpRcRectByRc("==>"__FUNCTION__" Dst: ", (_pDstRc), &_DstRect, "\n"); \
    185211        } \
    186212    } while (0)
     
    194220            RECT _DstRect; \
    195221            vboxWddmRectMoved(&_DstRect, (_pSrcRect), (_pDstPoint)->x, (_pDstPoint)->y); \
    196             vboxVDbgDoDumpRcRectByRc("<=="__FUNCTION__" Src:\n", (_pSrcRc), (_pSrcRect), "\n"); \
    197             vboxVDbgDoDumpRcRectByRc("<=="__FUNCTION__" Dst:\n", (_pDstRc), &_DstRect, "\n"); \
    198         } \
    199     } while (0)
    200 
    201 #define VBOXVDBG_DUMP_BLT_ENTER(_pSrcRc, _pSrcSurf, _pSrcRect, _pDstRc, _pDstSurf, _pDstRect) do { \
     222            vboxVDbgDoDumpRcRectByRc("<=="__FUNCTION__" Src: ", (_pSrcRc), (_pSrcRect), "\n"); \
     223            vboxVDbgDoDumpRcRectByRc("<=="__FUNCTION__" Dst: ", (_pDstRc), &_DstRect, "\n"); \
     224        } \
     225    } while (0)
     226
     227#define VBOXVDBG_DUMP_BLT_ENTER(_pSrcAlloc, _pSrcSurf, _pSrcRect, _pDstAlloc, _pDstSurf, _pDstRect) do { \
    202228        if (VBOXVDBG_IS_DUMP_ALLOWED(Blt) \
    203                 || VBOXVDBG_IS_DUMP_SHARED_ALLOWED(_pSrcRc) \
    204                 || VBOXVDBG_IS_DUMP_SHARED_ALLOWED(_pDstRc) \
    205                 ) \
    206         { \
    207             vboxVDbgPrint(("==>"__FUNCTION__" Src: SharedHandle(0x%p)\n", (_pSrcRc)->aAllocations[0].hSharedHandle)); \
    208             vboxVDbgDoDumpSurfRect("", (_pSrcSurf), (_pSrcRect), "\n", true); \
    209             vboxVDbgPrint(("==>"__FUNCTION__" Dst: SharedHandle(0x%p)\n", (_pDstRc)->aAllocations[0].hSharedHandle)); \
    210             vboxVDbgDoDumpSurfRect("", (_pDstSurf), (_pDstRect), "\n", true); \
    211         } \
    212     } while (0)
    213 
    214 #define VBOXVDBG_DUMP_BLT_LEAVE(_pSrcRc, _pSrcSurf, _pSrcRect, _pDstRc, _pDstSurf, _pDstRect) do { \
     229                || VBOXVDBG_IS_DUMP_SHARED_ALLOWED((_pSrcAlloc)->pRc) \
     230                || VBOXVDBG_IS_DUMP_SHARED_ALLOWED((_pDstAlloc)->pRc) \
     231                ) \
     232        { \
     233            vboxVDbgDoDumpRcRectByAlloc("==>"__FUNCTION__" Src: ", (_pSrcAlloc), (_pSrcSurf), (_pSrcRect), "\n"); \
     234            vboxVDbgDoDumpRcRectByAlloc("==>"__FUNCTION__" Dst: ", (_pDstAlloc), (_pDstSurf), (_pDstRect), "\n"); \
     235        } \
     236    } while (0)
     237
     238#define VBOXVDBG_DUMP_BLT_LEAVE(_pSrcAlloc, _pSrcSurf, _pSrcRect, _pDstAlloc, _pDstSurf, _pDstRect) do { \
    215239        if (VBOXVDBG_IS_DUMP_ALLOWED(Blt) \
    216                 || VBOXVDBG_IS_DUMP_SHARED_ALLOWED(_pSrcRc) \
    217                 || VBOXVDBG_IS_DUMP_SHARED_ALLOWED(_pDstRc) \
    218                 ) \
    219         { \
    220             vboxVDbgPrint(("<=="__FUNCTION__" Src: SharedHandle(0x%p)\n", (_pSrcRc)->aAllocations[0].hSharedHandle)); \
    221             vboxVDbgDoDumpSurfRect("", (_pSrcSurf), (_pSrcRect), "\n", true); \
    222             vboxVDbgPrint(("<=="__FUNCTION__" Dst: SharedHandle(0x%p)\n", (_pDstRc)->aAllocations[0].hSharedHandle)); \
    223             vboxVDbgDoDumpSurfRect("", (_pDstSurf), (_pDstRect), "\n", true); \
     240                || VBOXVDBG_IS_DUMP_SHARED_ALLOWED((_pSrcAlloc)->pRc) \
     241                || VBOXVDBG_IS_DUMP_SHARED_ALLOWED((_pDstAlloc)->pRc) \
     242                ) \
     243        { \
     244            vboxVDbgDoDumpRcRectByAlloc("<=="__FUNCTION__" Src: ", (_pSrcAlloc), (_pSrcSurf), (_pSrcRect), "\n"); \
     245            vboxVDbgDoDumpRcRectByAlloc("<=="__FUNCTION__" Dst: ", (_pDstAlloc), (_pDstSurf), (_pDstRect), "\n"); \
    224246        } \
    225247    } while (0)
     
    238260        }\
    239261    } while (0)
     262
     263#define VBOXVDBG_DUMP_LOCK_ST(_pData) do { \
     264        if (VBOXVDBG_IS_DUMP_ALLOWED(Lock) \
     265                || VBOXVDBG_IS_DUMP_ALLOWED(Unlock) \
     266                ) \
     267        { \
     268            vboxVDbgDoDumpLockSurfTex("== "__FUNCTION__": ", (_pData), "\n", VBOXVDBG_IS_DUMP_ALLOWED(Lock)); \
     269        } \
     270    } while (0)
     271
     272#define VBOXVDBG_DUMP_UNLOCK_ST(_pData) do { \
     273        if (VBOXVDBG_IS_DUMP_ALLOWED(Unlock) \
     274                ) \
     275        { \
     276            vboxVDbgDoDumpUnlockSurfTex("== "__FUNCTION__": ", (_pData), "\n", true); \
     277        } \
     278    } while (0)
     279
    240280#else
    241281#define VBOXVDBG_DUMP_DRAWPRIM_ENTER(_pDevice) do { } while (0)
     
    248288#define VBOXVDBG_DUMP_SYNC_RT(_pBbSurf) do { } while (0)
    249289#define VBOXVDBG_DUMP_FLUSH(_pDevice) do { } while (0)
     290#define VBOXVDBG_DUMP_LOCK_ST(_pData) do { } while (0)
     291#define VBOXVDBG_DUMP_UNLOCK_ST(_pData) do { } while (0)
    250292#endif
    251293
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp

    r36867 r38112  
    3030typedef struct VBOXDISPMP
    3131{
     32    CRITICAL_SECTION CritSect;
    3233    PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd;
    3334    uint32_t cbEscapeCmd;
     
    5455}
    5556
     57DECLINLINE(VOID) vboxVideoCmIterCopyToBack(PVBOXVIDEOCM_ITERATOR pIter, PVBOXVIDEOCM_CMD_HDR pCur)
     58{
     59    memcpy((((uint8_t*)pIter->pCur) + pIter->cbRemain), pCur, pCur->cbCmd);
     60    pIter->cbRemain += pCur->cbCmd;
     61}
     62
    5663DECLINLINE(bool) vboxVideoCmIterHasNext(PVBOXVIDEOCM_ITERATOR pIter)
    5764{
     
    6370DECLCALLBACK(HRESULT) vboxDispMpEnableEvents()
    6471{
     72    EnterCriticalSection(&g_VBoxDispMp.CritSect);
    6573    g_VBoxDispMp.pEscapeCmd = NULL;
    6674    g_VBoxDispMp.cbEscapeCmd = 0;
     
    6977    vboxUhgsmiGlobalSetCurrent();
    7078#endif
     79    LeaveCriticalSection(&g_VBoxDispMp.CritSect);
    7180    return S_OK;
    7281}
     
    7584DECLCALLBACK(HRESULT) vboxDispMpDisableEvents()
    7685{
     86    EnterCriticalSection(&g_VBoxDispMp.CritSect);
    7787    if (g_VBoxDispMp.pEscapeCmd)
     88    {
    7889        RTMemFree(g_VBoxDispMp.pEscapeCmd);
     90        g_VBoxDispMp.pEscapeCmd = NULL;
     91    }
    7992#ifdef VBOX_WITH_CRHGSMI
    8093    vboxUhgsmiGlobalClearCurrent();
    8194#endif
     95    LeaveCriticalSection(&g_VBoxDispMp.CritSect);
    8296    return S_OK;
    8397}
     
    90104{
    91105    HRESULT hr = S_OK;
     106    EnterCriticalSection(&g_VBoxDispMp.CritSect);
    92107    PVBOXVIDEOCM_CMD_HDR pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
    93108    if (!pHdr)
     
    100115                g_VBoxDispMp.cbEscapeCmd = VBOXDISPMP_BUF_INITSIZE;
    101116            else
     117            {
     118                LeaveCriticalSection(&g_VBoxDispMp.CritSect);
    102119                return E_OUTOFMEMORY;
     120            }
    103121        }
    104122
     
    150168        PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
    151169        PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
    152         /* todo: synchronization */
     170        /* the miniport driver should ensure all swapchain-involved commands are completed before swapchain termination,
     171         * so we should have it always valid here */
    153172        Assert(pSwapchain);
     173        Assert(pSwapchain->hWnd);
    154174        pRegions->hWnd = pSwapchain->hWnd;
    155175        pRegions->pRegions = &pCmdInternal->Cmd;
    156176    }
     177    LeaveCriticalSection(&g_VBoxDispMp.CritSect);
    157178    return hr;
    158179}
     
    175196    return S_OK;
    176197}
     198
     199HRESULT vboxDispMpInternalInit()
     200{
     201    memset(&g_VBoxDispMp, 0, sizeof (g_VBoxDispMp));
     202    InitializeCriticalSection(&g_VBoxDispMp.CritSect);
     203    return S_OK;
     204}
     205
     206HRESULT vboxDispMpInternalTerm()
     207{
     208    vboxDispMpDisableEvents();
     209    DeleteCriticalSection(&g_VBoxDispMp.CritSect);
     210    return S_OK;
     211}
     212
     213HRESULT vboxDispMpInternalCancel(VBOXWDDMDISP_CONTEXT *pContext, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
     214{
     215    HRESULT hr = S_OK;
     216    EnterCriticalSection(&g_VBoxDispMp.CritSect);
     217    do
     218    {
     219        /* the pEscapeCmd is used as an indicator to whether the events capturing is active */
     220        if (!g_VBoxDispMp.pEscapeCmd)
     221            break;
     222
     223        /* copy the iterator data to restore it back later */
     224        VBOXVIDEOCM_ITERATOR IterCopy = g_VBoxDispMp.Iterator;
     225
     226        /* first check if we have matching elements */
     227        PVBOXVIDEOCM_CMD_HDR pHdr;
     228        bool fHasMatch = false;
     229        while (pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator))
     230        {
     231            VBOXWDDMDISP_CONTEXT *pCurContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
     232            if (pCurContext != pContext)
     233                continue;
     234
     235            if (!pSwapchain)
     236            {
     237                fHasMatch = true;
     238                break;
     239            }
     240
     241            PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
     242            PVBOXWDDMDISP_SWAPCHAIN pCurSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
     243            if (pCurSwapchain != pSwapchain)
     244                continue;
     245
     246            fHasMatch = true;
     247            break;
     248        }
     249
     250        /* restore the iterator */
     251        g_VBoxDispMp.Iterator = IterCopy;
     252
     253        if (!fHasMatch)
     254            break;
     255
     256        /* there are elements to remove */
     257        PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(g_VBoxDispMp.cbEscapeCmd);
     258        if (!pEscapeCmd)
     259        {
     260            WARN(("no memory"));
     261            hr = E_OUTOFMEMORY;
     262            break;
     263        }
     264        /* copy the header data */
     265        *pEscapeCmd = *g_VBoxDispMp.pEscapeCmd;
     266        /* now copy the command data filtering out the canceled commands */
     267        pHdr = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)pEscapeCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
     268        vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, pHdr, 0);
     269        while (pHdr = vboxVideoCmIterNext(&IterCopy))
     270        {
     271            VBOXWDDMDISP_CONTEXT *pCurContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
     272            if (pCurContext != pContext)
     273            {
     274                vboxVideoCmIterCopyToBack(&g_VBoxDispMp.Iterator, pHdr);
     275                continue;
     276            }
     277
     278            if (!pSwapchain)
     279            {
     280                /* match, just continue */
     281                continue;
     282            }
     283
     284            PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
     285            PVBOXWDDMDISP_SWAPCHAIN pCurSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
     286            if (pCurSwapchain != pSwapchain)
     287            {
     288                vboxVideoCmIterCopyToBack(&g_VBoxDispMp.Iterator, pHdr);
     289                continue;
     290            }
     291            /* match, just continue */
     292        }
     293
     294        Assert(g_VBoxDispMp.pEscapeCmd);
     295        RTMemFree(g_VBoxDispMp.pEscapeCmd);
     296        Assert(pEscapeCmd);
     297        g_VBoxDispMp.pEscapeCmd = pEscapeCmd;
     298    } while (0);
     299
     300    LeaveCriticalSection(&g_VBoxDispMp.CritSect);
     301    return hr;
     302}
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp

    r36867 r38112  
    282282    if (!GetClassInfo(hInstance, VBOXSCREENMONWND_NAME, &wc))
    283283    {
    284         wc.style = CS_OWNDC;
     284        wc.style = 0;//CS_OWNDC;
    285285        wc.lpfnWndProc = vboxScreenMonWndProc;
    286286        wc.cbClsExtra = 0;
Note: See TracChangeset for help on using the changeset viewer.

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