Changeset 57149 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Aug 1, 2015 8:18:07 PM (9 years ago)
- 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 3248 3248 3249 3249 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... */ 3250 3251 { 3251 3252 SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)(pHdr + 1); -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp
r57148 r57149 1 1 /* $Id$ */ 2 2 /** @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. 9 4 */ 10 5 … … 21 16 */ 22 17 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 25 41 26 42 /** … … 329 345 330 346 347 348 349 void 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 331 365 /** 332 * Reinitializes an active context.366 * Worker for vmsvgaR3Info that display details of a host window. 333 367 * 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. 337 370 */ 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++) 371 void 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) 347 377 { 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()); 358 452 } 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 */ 467 const 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) 364 476 { 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); 696 480 } 697 481 #endif 698 482 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 (;;) 701 489 { 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; 708 508 } 709 710 LogFlow(("vmsvga3dLoadExec: return success\n")); 711 return VINF_SUCCESS; 509 return NULL; 712 510 } 713 511 714 512 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 */ 524 char *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) 724 530 { 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; 789 536 } 790 537 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; 792 543 } 793 544 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 */ 560 char *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) 807 564 { 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); 1171 569 } 1172 570 else 1173 571 { 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); 1190 576 } 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 */ 587 DECLCALLBACK(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 */ 600 DECLCALLBACK(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 610 void 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 */ 910 static 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 */ 1023 char *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 */ 1089 static 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 */ 1131 char *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; 1193 1252 } 1194 1253 … … 1805 1864 } 1806 1865 1807 1808 #endif /* !___DevVGA_SVGA3d_shared_h___ */1809 -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h
r57148 r57149 1 1 /* $Id$ */ 2 2 /** @file 3 * DevVMWare - VMWare SVGA device 3 * DevVMWare - VMWare SVGA device - 3D part, internal header. 4 4 */ 5 5 … … 16 16 */ 17 17 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 *********************************************************************************************************************************/ 50 39 #include "DevVGA-SVGA3d.h" 51 #include "vmsvga/svga_reg.h"52 #include "vmsvga/svga3d_reg.h"53 #include "vmsvga/svga3d_shaderdefs.h"54 40 55 41 #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 58 50 59 51 #elif defined(RT_OS_DARWIN) … … 78 70 # define GL_LUMINANCE8_ALPHA8_EXT 0x8045 79 71 # define GL_INT_2_10_10_10_REV 0x8D9F 72 80 73 #else 81 74 # include <X11/Xlib.h> … … 86 79 # define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103 87 80 #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 *********************************************************************************************************************************/ 103 92 /** Experimental: Create a dedicated context for handling surfaces in, thus 104 93 * avoiding orphaned surfaces after context destruction. … … 114 103 * if we really need to, but as this is an experiment, I'm playing it safe. 115 104 */ 116 #define VMSVGA3D_OGL_WITH_SHARED_CTX 105 #ifdef VMSVGA3D_OPENGL 106 # define VMSVGA3D_OGL_WITH_SHARED_CTX 107 #endif 117 108 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX 118 109 /** 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 121 114 122 115 /** @def VBOX_VMSVGA3D_GL_HACK_LEVEL … … 127 120 * The value is ((x)<<16 | (y)) where x and y are taken from the GL_VERSION_x_y. 128 121 */ 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) \ 182 130 do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0) 183 131 … … 187 135 * @parm pContext The new context. 188 136 */ 189 # ifdef RT_OS_WINDOWS190 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \137 # ifdef RT_OS_WINDOWS 138 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \ 191 139 do { \ 192 140 if ((pState)->idActiveContext != (pContext)->id) \ … … 199 147 } while (0) 200 148 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) \ 203 151 do { \ 204 152 if ((pState)->idActiveContext != (pContext)->id) \ … … 209 157 } \ 210 158 } while (0) 211 # else212 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \159 # else 160 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \ 213 161 do { \ 214 162 if ((pState)->idActiveContext != (pContext)->id) \ … … 222 170 } \ 223 171 } while (0) 224 # endif172 # endif 225 173 226 174 /** @def VMSVGA3D_CLEAR_GL_ERRORS … … 239 187 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS 240 188 */ 241 # define VMSVGA3D_CLEAR_GL_ERRORS() \189 # define VMSVGA3D_CLEAR_GL_ERRORS() \ 242 190 do { \ 243 191 if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \ … … 258 206 * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 259 207 */ 260 # define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())208 # define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError()) 261 209 262 210 /** @def VMSVGA3D_GL_SUCCESS … … 271 219 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN 272 220 */ 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)) 274 222 275 223 /** @def VMSVGA3D_GL_COMPLAIN … … 289 237 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS 290 238 */ 291 # ifdef VBOX_STRICT292 # 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) \ 293 241 do { \ 294 242 AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \ … … 300 248 AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \ 301 249 } while (0) 302 # else303 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \250 # else 251 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \ 304 252 do { \ 305 253 LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id)); \ … … 309 257 LogRelMax(32, a_LogRelDetails); \ 310 258 } while (0) 311 # endif259 # endif 312 260 313 261 /** @def VMSVGA3D_GL_GET_AND_COMPLAIN … … 322 270 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 323 271 */ 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) \ 325 273 do { \ 326 274 VMSVGA3D_GET_GL_ERROR(a_pContext); \ … … 341 289 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 342 290 */ 343 # define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \291 # define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \ 344 292 if (VMSVGA3D_GL_IS_SUCCESS(a_pContext)) \ 345 293 { /* likely */ } \ … … 367 315 * VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 368 316 */ 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) \ 370 318 do { \ 371 319 (a_GlCall); \ … … 389 337 * VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 390 338 */ 391 # define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \339 # define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \ 392 340 VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, ("%s\n", #a_GlCall)) 393 341 … … 406 354 * release builds. 407 355 */ 408 # ifdef VBOX_STRICT409 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { \356 # ifdef VBOX_STRICT 357 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { \ 410 358 Assert((pState)->idActiveContext == (pContext)->id); \ 411 359 (pContext)->lastError = glGetError(); \ … … 414 362 VERR_INTERNAL_ERROR); \ 415 363 } while (0) 416 # else417 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { } while (0)418 # endif364 # else 365 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { } while (0) 366 # endif 419 367 420 368 /** @def VMSVGA3D_CHECK_LAST_ERROR_WARN … … 426 374 * @parm pContext The new context. 427 375 */ 428 # ifdef VBOX_STRICT429 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { \376 # ifdef VBOX_STRICT 377 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { \ 430 378 Assert((pState)->idActiveContext == (pContext)->id); \ 431 379 (pContext)->lastError = glGetError(); \ 432 380 AssertMsg((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError)); \ 433 381 } 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 */ 400 typedef struct VMSVGA3DMIPMAPLEVEL 401 { 402 /** The mipmap size. */ 487 403 SVGA3dSize size; 404 /** The size (in bytes) of the mimap data when using the format the surface was 405 * defined with. */ 488 406 uint32_t cbSurface; 407 /** The scanline/pitch size in bytes. */ 489 408 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. */ 490 411 void *pSurfaceData; 412 /** Set if pvSurfaceData contains data not realized in hardware or pushed to the 413 * hardware surface yet. */ 491 414 bool fDirty; 492 } VMSVGA3DMIPMAPLEVEL, *PVMSVGA3DMIPMAPLEVEL; 493 415 } VMSVGA3DMIPMAPLEVEL; 416 /** Pointer to a mipmap level. */ 417 typedef VMSVGA3DMIPMAPLEVEL *PVMSVGA3DMIPMAPLEVEL; 418 419 420 #ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS 494 421 /** 495 422 * SSM descriptor table for the VMSVGA3DMIPMAPLEVEL structure. … … 504 431 SSMFIELD_ENTRY_TERM() 505 432 }; 506 433 #endif 434 435 typedef struct VMSVGATRANSFORMSTATE 436 { 437 bool fValid; 438 float matrix[16]; 439 } VMSVGATRANSFORMSTATE; 440 typedef VMSVGATRANSFORMSTATE *PVMSVGATRANSFORMSTATE; 441 442 typedef struct VMSVGAMATERIALSTATE 443 { 444 bool fValid; 445 SVGA3dMaterial material; 446 } VMSVGAMATERIALSTATE; 447 typedef VMSVGAMATERIALSTATE *PVMSVGAMATERIALSTATE; 448 449 typedef struct VMSVGACLIPPLANESTATE 450 { 451 bool fValid; 452 float plane[4]; 453 } VMSVGACLIPPLANESTATE; 454 typedef VMSVGACLIPPLANESTATE *PVMSVGACLIPPLANESTATE; 455 456 typedef struct VMSVGALIGHTSTATE 457 { 458 bool fEnabled; 459 bool fValidData; 460 SVGA3dLightData data; 461 } VMSVGALIGHTSTATE; 462 typedef VMSVGALIGHTSTATE *PVMSVGALIGHTSTATE; 463 464 typedef struct VMSVGASHADERCONST 465 { 466 bool fValid; 467 SVGA3dShaderConstType ctype; 468 uint32_t value[4]; 469 } VMSVGASHADERCONST; 470 typedef VMSVGASHADERCONST *PVMSVGASHADERCONST; 471 472 #ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS 473 /** 474 * SSM descriptor table for the VMSVGASHADERCONST structure. 475 */ 476 static 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 */ 507 489 typedef 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; 500 typedef VMSVGA3DSHAREDSURFACE *PVMSVGA3DSHAREDSURFACE; 501 #endif /* VMSVGA3D_DIRECT3D */ 502 503 /** 504 * VMSVGA3d surface. 505 */ 506 typedef struct VMSVGA3DSURFACE 508 507 { 509 508 uint32_t id; … … 515 514 uint32_t flags; 516 515 SVGA3dSurfaceFormat format; 516 #ifdef VMSVGA3D_OPENGL 517 517 GLint internalFormatGL; 518 518 GLint formatGL; … … 524 524 GLuint renderbuffer; 525 525 } oglId; 526 #endif 526 527 SVGA3dSurfaceFace faces[SVGA3D_MAX_SURFACE_FACES]; 527 528 uint32_t cFaces; … … 529 530 uint32_t multiSampleCount; 530 531 SVGA3dTextureFilter autogenFilter; 532 #ifdef VMSVGA3D_DIRECT3D 533 D3DFORMAT formatD3D; 534 DWORD fUsageD3D; 535 D3DMULTISAMPLE_TYPE multiSampleTypeD3D; 536 #endif 537 531 538 uint32_t cbBlock; /* block/pixel size in bytes */ 532 539 /* Dirty state; surface was manually updated. */ 533 540 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. */ 565 typedef VMSVGA3DSURFACE *PVMSVGA3DSURFACE; 566 567 #ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS 536 568 /** 537 569 * SSM descriptor table for the VMSVGA3DSURFACE structure. … … 542 574 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX 543 575 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idWeakContextAssociation), 544 # else576 # else 545 577 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idAssociatedContext), 546 # endif578 # endif 547 579 SSMFIELD_ENTRY( VMSVGA3DSURFACE, flags), 548 580 SSMFIELD_ENTRY( VMSVGA3DSURFACE, format), 581 # ifdef VMSVGA3D_OPENGL 549 582 SSMFIELD_ENTRY( VMSVGA3DSURFACE, internalFormatGL), 550 583 SSMFIELD_ENTRY( VMSVGA3DSURFACE, formatGL), 551 584 SSMFIELD_ENTRY( VMSVGA3DSURFACE, typeGL), 552 585 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, id), 586 # endif 553 587 SSMFIELD_ENTRY( VMSVGA3DSURFACE, faces), 554 588 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cFaces), … … 556 590 SSMFIELD_ENTRY( VMSVGA3DSURFACE, multiSampleCount), 557 591 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 558 598 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cbBlock), 559 599 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 560 608 SSMFIELD_ENTRY_TERM() 561 609 }; 562 563 typedef struct 610 #endif 611 612 613 typedef struct VMSVGA3DSHADER 564 614 { 565 615 uint32_t id; … … 570 620 union 571 621 { 622 #ifdef VMSVGA3D_DIRECT3D 623 IDirect3DVertexShader9 *pVertexShader; 624 IDirect3DPixelShader9 *pPixelShader; 625 #else 572 626 void *pVertexShader; 573 627 void *pPixelShader; 628 #endif 629 void *pv; 574 630 } u; 575 } VMSVGA3DSHADER, *PVMSVGA3DSHADER; 576 631 } VMSVGA3DSHADER; 632 typedef VMSVGA3DSHADER *PVMSVGA3DSHADER; 633 634 #ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS 577 635 /** 578 636 * SSM descriptor table for the VMSVGA3DSHADER structure. … … 585 643 SSMFIELD_ENTRY( VMSVGA3DSHADER, cbData), 586 644 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, pShaderProgram), 587 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, u.p VertexShader),645 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, u.pv), 588 646 SSMFIELD_ENTRY_TERM() 589 647 }; 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 */ 642 664 typedef struct VMSVGA3DCONTEXT 643 665 { 644 666 uint32_t id; 645 667 #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 646 675 /* Device context of the context window. */ 647 676 HDC hdc; 648 677 /* OpenGL rendering context handle. */ 649 678 HGLRC hglrc; 679 # endif 650 680 /* Device context window handle. */ 651 681 HWND hwnd; … … 663 693 bool fMapped; 664 694 #endif 695 696 #ifdef VMSVGA3D_OPENGL 665 697 /* Framebuffer object associated with this context. */ 666 698 GLuint idFramebuffer; … … 670 702 /* Last GL error recorded. */ 671 703 GLenum lastError; 704 void *pShaderContext; 705 #endif 672 706 673 707 /* Current active render target (if any) */ … … 680 714 uint32_t cVertexShaders; 681 715 PVMSVGA3DSHADER paVertexShader; 682 void *pShaderContext;683 716 /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */ 684 717 struct 685 718 { 719 /** VMSVGA3D_UPDATE_XXX */ 686 720 uint32_t u32UpdateFlags; 687 721 … … 705 739 PVMSVGASHADERCONST paVertexShaderConst; 706 740 } state; 707 } VMSVGA3DCONTEXT, *PVMSVGA3DCONTEXT; 708 741 } VMSVGA3DCONTEXT; 742 /** Pointer to a VMSVGA3d context. */ 743 typedef VMSVGA3DCONTEXT *PVMSVGA3DCONTEXT; 744 745 #ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS 709 746 /** 710 747 * SSM descriptor table for the VMSVGA3DCONTEXT structure. … … 713 750 { 714 751 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 716 757 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc), 717 758 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hglrc), 759 # endif 718 760 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 721 772 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idFramebuffer), 722 773 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idReadFramebuffer), 723 774 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idDrawFramebuffer), 724 775 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, lastError), 776 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pShaderContext), 777 #endif 725 778 726 779 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, sidRenderTarget), … … 730 783 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cVertexShaders), 731 784 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paVertexShader), 732 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pShaderContext),733 785 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.u32UpdateFlags), 734 786 … … 752 804 SSMFIELD_ENTRY_TERM() 753 805 }; 806 #endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */ 807 754 808 755 809 /** … … 760 814 typedef struct VMSVGA3DSTATE 761 815 { 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 762 825 #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 763 836 /** Window Thread. */ 764 837 R3PTRTYPE(RTTHREAD) pWindowThread; … … 767 840 /** Window request semaphore. */ 768 841 RTSEMEVENT WndRequestSem; 769 #elif defined(RT_OS_LINUX) 842 #elif defined(RT_OS_DARWIN) 843 #else 770 844 /* The X display */ 771 Display 772 R3PTRTYPE(RTTHREAD) pWindowThread;845 Display *display; 846 R3PTRTYPE(RTTHREAD) pWindowThread; 773 847 bool bTerminate; 774 848 #endif 775 849 850 #ifdef VMSVGA3D_OPENGL 776 851 float fGLVersion; 777 852 /* Current active context. */ … … 849 924 } caps; 850 925 851 uint32_t cContexts;852 PVMSVGA3DCONTEXT *papContexts;853 uint32_t cSurfaces;854 PVMSVGA3DSURFACE *papSurfaces;855 #ifdef DEBUG_GFX_WINDOW_TEST_CONTEXT856 uint32_t idTestContext;857 #endif858 926 /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile. 859 927 * Free with RTStrFree. */ … … 873 941 VBOXVMSVGASHADERIF ShaderIf; 874 942 875 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX943 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX 876 944 /** The shared context. */ 877 945 VMSVGA3DCONTEXT SharedCtx; 878 #endif 946 # endif 947 #endif /* VMSVGA3D_OPENGL */ 879 948 } VMSVGA3DSTATE; 880 949 950 #ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS 881 951 /** 882 952 * SSM descriptor table for the VMSVGA3DSTATE structure. 953 * 954 * @remarks This isn't a complete structure markup, only fields with state. 883 955 */ 884 956 static SSMFIELD const g_aVMSVGA3DSTATEFields[] = 885 957 { 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 902 961 SSMFIELD_ENTRY( VMSVGA3DSTATE, cContexts), 903 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSTATE, papContexts),904 962 SSMFIELD_ENTRY( VMSVGA3DSTATE, cSurfaces), 905 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSTATE, papSurfaces),906 963 SSMFIELD_ENTRY_TERM() 907 964 }; 908 909 965 #endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */ 966 967 968 #ifdef VMSVGA3D_OPENGL 910 969 /** Save and setup everything. */ 911 # define VMSVGA3D_PARANOID_TEXTURE_PACKING970 # define VMSVGA3D_PARANOID_TEXTURE_PACKING 912 971 913 972 /** … … 932 991 typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS; 933 992 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 = ▭ 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 993 void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface, PVMSVGAPACKPARAMS pSave); 994 void 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 /** @} */ 1008 int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags); 1009 #endif /* VMSVGA3D_OPENGL */ 1010 1011 1012 /* DevVGA-SVGA3d-shared.cpp: */ 1013 uint32_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 38 38 #include <iprt/uuid.h> 39 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> 40 41 #include <VBox/VBoxVideo.h> /* required by DevVGA.h */ 45 42 46 43 /* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */ … … 49 46 #include "DevVGA-SVGA.h" 50 47 #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 88 50 #ifdef DUMP_SHADER_DISASSEMBLY 89 51 # include <d3dx9shader.h> 90 52 #endif 91 #include "vmsvga_glext/glext.h"92 93 #include "shaderlib/shaderlib.h"94 53 95 54 #include <stdlib.h> 96 55 #include <math.h> 97 #include <float.h> 56 #include <float.h> /* FLT_MIN */ 98 57 99 58 … … 101 60 * Defined Constants And Macros * 102 61 *******************************************************************************/ 103 /** Experimental: Create a dedicated context for handling surfaces in, thus104 * avoiding orphaned surfaces after context destruction.105 *106 * This cures, for instance, an assertion on fedora 21 that happens in107 * vmsvga3dSurfaceStretchBlt if the login screen and the desktop has different108 * sizes. The context of the login screen seems to have just been destroyed109 * earlier and I believe the driver/X/whoever is attemting to strech the old110 * screen content onto the new sized screen.111 *112 * @remarks This probably comes at a slight preformance expense, as we currently113 * switches context when setting up the surface the first time. Not sure114 * if we really need to, but as this is an experiment, I'm playing it safe.115 */116 #define VMSVGA3D_OGL_WITH_SHARED_CTX117 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX118 /** Fake surface ID for the shared context. */119 # define VMSVGA3D_SHARED_CTX_ID UINT32_C(0xffffeeee)120 #endif121 122 /** @def VBOX_VMSVGA3D_GL_HACK_LEVEL123 * Turns out that on Linux gl.h may often define the first 2-4 OpenGL versions124 * worth of extensions, but missing out on a function pointer of fifteen. This125 * causes headache for us when we use the function pointers below. This hack126 * 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_LEVEL130 # define VBOX_VMSVGA3D_GL_HACK_LEVEL 0131 #endif132 133 62 #ifndef VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE 134 63 # define VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE 1.0 … … 159 88 #define D3D_TO_OGL_Y_COORD_MIPLEVEL(ptrMipLevel, y_coordinate) (ptrMipLevel->size.height - (y_coordinate)) 160 89 161 #define OPENGL_INVALID_ID 0162 163 90 //#define MANUAL_FLIP_SURFACE_DATA 164 91 /* Enable to render the result of DrawPrimitive in a seperate window. */ 165 92 //#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 only172 * 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_CONTEXT185 * 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_WINDOWS190 # 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 #else212 # 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 #endif225 226 /** @def VMSVGA3D_CLEAR_GL_ERRORS227 * Clears all pending OpenGL errors.228 *229 * If I understood this correctly, OpenGL maintains a bitmask internally and230 * glGetError gets the next bit (clearing it) from the bitmap and translates it231 * into a GL_XXX constant value which it then returns. A single OpenGL call can232 * set more than one bit, and they stick around across calls, from what I233 * understand.234 *235 * So in order to be able to use glGetError to check whether a function236 * 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_SUCCESS240 */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_ERROR252 * Gets the last OpenGL error, stores it in a_pContext->lastError and returns253 * 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_COMPLAIN259 */260 #define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())261 262 /** @def VMSVGA3D_GL_SUCCESS263 * 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_COMPLAIN272 */273 #define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))274 275 /** @def VMSVGA3D_GL_COMPLAIN276 * 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 the279 * first few occurences in the release log.280 *281 * All GL errors will be cleared after invocation. Assumes lastError282 * 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 describes287 * the operation in greater detail.288 *289 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS290 */291 #ifdef VBOX_STRICT292 # 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 #else303 # 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 #endif312 313 /** @def VMSVGA3D_GL_GET_AND_COMPLAIN314 * Combination of VMSVGA3D_GET_GL_ERROR and VMSVGA3D_GL_COMPLAIN, assuming that315 * 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 describes320 * the operation in greater detail.321 *322 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN323 */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_SUCCESS331 * 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 release334 * 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 describes339 * the operation in greater detail.340 *341 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN342 */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_EX351 * Executes the specified OpenGL API call and asserts that it succeeded, variant352 * with extra logging flexibility.353 *354 * ASSUMES no GL errors pending prior to invocation - caller should use355 * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.356 *357 * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release358 * 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 describes364 * 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_COMPLAIN368 */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_CALL376 * Executes the specified OpenGL API call and asserts that it succeeded.377 *378 * ASSUMES no GL errors pending prior to invocation - caller should use379 * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.380 *381 * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release382 * 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_COMPLAIN390 */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_ERROR396 * Checks that the last OpenGL error code indicates success.397 *398 * Will assert and return VERR_INTERNAL_ERROR in strict builds, in other399 * 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 return405 * VERR_INTERNAL_ERROR in strict builds and just barge on ahead in406 * release builds.407 */408 #ifdef VBOX_STRICT409 # 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 #else417 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { } while (0)418 #endif419 420 /** @def VMSVGA3D_CHECK_LAST_ERROR_WARN421 * 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_STRICT429 # 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 #else435 # define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { } while (0)436 #endif437 93 438 94 … … 481 137 482 138 /******************************************************************************* 483 * Structures, Typedefs and Globals. *484 *******************************************************************************/485 typedef struct486 {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 struct508 {509 uint32_t id;510 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX511 uint32_t idWeakContextAssociation;512 #else513 uint32_t idAssociatedContext;514 #endif515 uint32_t flags;516 SVGA3dSurfaceFormat format;517 GLint internalFormatGL;518 GLint formatGL;519 GLint typeGL;520 union521 {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_CTX543 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idWeakContextAssociation),544 #else545 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idAssociatedContext),546 #endif547 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 struct564 {565 uint32_t id;566 uint32_t cid;567 SVGA3dShaderType type;568 uint32_t cbData;569 void *pShaderProgram;570 union571 {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 struct592 {593 bool fValid;594 float matrix[16];595 } VMSVGATRANSFORMSTATE, *PVMSVGATRANSFORMSTATE;596 597 typedef struct598 {599 bool fValid;600 SVGA3dMaterial material;601 } VMSVGAMATERIALSTATE, *PVMSVGAMATERIALSTATE;602 603 typedef struct604 {605 bool fValid;606 float plane[4];607 } VMSVGACLIPPLANESTATE, *PVMSVGACLIPPLANESTATE;608 609 typedef struct610 {611 bool fEnabled;612 bool fValidData;613 SVGA3dLightData data;614 } VMSVGALIGHTSTATE, *PVMSVGALIGHTSTATE;615 616 typedef struct617 {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 VMSVGA3DCONTEXT643 {644 uint32_t id;645 #ifdef RT_OS_WINDOWS646 /* 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 #else658 /** 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 #endif665 /* 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 struct685 {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_WINDOWS716 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc),717 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hglrc),718 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hwnd),719 #endif720 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 VMSVGA3DSTATE761 {762 #ifdef RT_OS_WINDOWS763 /** 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 #endif775 776 float fGLVersion;777 /* Current active context. */778 uint32_t idActiveContext;779 780 struct781 {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 < 0x102804 PFNGLBLENDCOLORPROC glBlendColor;805 PFNGLBLENDEQUATIONPROC glBlendEquation;806 #endif807 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 < 0x103825 PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;826 #endif827 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;828 PFNGLPROVOKINGVERTEXPROC glProvokingVertex;829 bool fEXT_stencil_two_side;830 } ext;831 832 struct833 {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_CONTEXT856 uint32_t idTestContext;857 #endif858 /** 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 implementations866 * (darwin) hides extensions that have made it into core and probably a867 * 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_CTX876 /** The shared context. */877 VMSVGA3DCONTEXT SharedCtx;878 #endif879 } VMSVGA3DSTATE;880 881 /**882 * SSM descriptor table for the VMSVGA3DSTATE structure.883 */884 static SSMFIELD const g_aVMSVGA3DSTATEFields[] =885 {886 #ifdef RT_OS_WINDOWS887 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 #endif896 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_PACKING912 913 /**914 * Saved texture packing parameters (shared by both pack and unpack).915 */916 typedef struct VMSVGAPACKPARAMS917 {918 GLint iAlignment;919 GLint cxRow;920 #ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING921 GLint cyImage;922 GLboolean fSwapBytes;923 GLboolean fLsbFirst;924 GLint cSkipRows;925 GLint cSkipPixels;926 GLint cSkipImages;927 #endif928 } 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 /*******************************************************************************936 139 * Global Variables * 937 140 *******************************************************************************/ … … 959 162 *******************************************************************************/ 960 163 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 164 static int vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid); 963 165 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 166 969 167 /* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */ … … 1886 1084 } 1887 1085 1888 /* Shared functions that depend on private structure definitions. */1889 #define VMSVGA3D_OPENGL1890 #include "DevVGA-SVGA3d-shared.h"1891 1086 1892 1087 /** … … 3286 2481 * @param pSave Where to save stuff. 3287 2482 */ 3288 static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface, 3289 PVMSVGAPACKPARAMS pSave) 2483 void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface, PVMSVGAPACKPARAMS pSave) 3290 2484 { 3291 2485 /* … … 3361 2555 * @param pSave Where stuff was saved. 3362 2556 */ 3363 staticvoid vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,3364 2557 void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface, 2558 PCVMSVGAPACKPARAMS pSave) 3365 2559 { 3366 2560 NOREF(pSurface); … … 4287 3481 * @param fFlags VMSVGA3D_DEF_CTX_F_XXX. 4288 3482 */ 4289 staticint vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags)3483 int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags) 4290 3484 { 4291 3485 int rc; -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp
r57148 r57149 1 1 /* $Id$ */ 2 2 /** @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. 9 4 */ 10 5 … … 21 16 */ 22 17 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 329 41 330 42 … … 1147 859 } 1148 860 1149 staticuint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)861 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 862 { 1151 863 /* Choose a sane upper limit. */ … … 1193 905 } 1194 906 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_WINDOWS1254 pHlp->pfnPrintf(pHlp, "hwnd: %p\n", pContext->hwnd);1255 if (fVerbose)1256 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);1257 # ifdef VMSVGA3D_DIRECT3D1258 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice);1259 # else1260 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc);1261 pHlp->pfnPrintf(pHlp, "hglrc: %p\n", pContext->hglrc);1262 # endif1263 #else1264 /** @todo Other hosts... */1265 #endif1266 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 else1410 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 else1466 {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_DIRECT3D1516 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 #else1648 # error "Build config error."1649 #endif1650 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 #else1661 pHlp->pfnPrintf(pHlp, "idAssociatedContext: %#x\n", pSurface->idAssociatedContext);1662 #endif1663 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_DIRECT3D1701 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 #else1723 # error "Build config error."1724 #endif1725 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 else1737 {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 else1785 {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 33 33 #include <iprt/avl.h> 34 34 35 #include <VBox/VMMDev.h> 36 #include <VBox/VBoxVideo.h> 37 #include <VBox/bioslogo.h> 35 #include <VBox/VBoxVideo.h> /* required by DevVGA.h */ 38 36 39 37 /* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */ … … 42 40 #include "DevVGA-SVGA.h" 43 41 #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" 47 44 48 45 … … 51 48 * Structures and Typedefs * 52 49 *******************************************************************************/ 53 # define VMSVGA3D_WNDCLASSNAME"VMSVGA3DWNDCLS"50 # define VMSVGA3D_WNDCLASSNAME "VMSVGA3DWNDCLS" 54 51 55 52 static LONG WINAPI vmsvga3dWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); … … 118 115 119 116 117 120 118 #ifdef RT_OS_WINDOWS 121 119 … … 304 302 305 303 #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_WINDOWS333 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 else410 pHlp->pfnPrintf(pHlp, " GetWindowInfo: last error %d\n", GetLastError());411 }412 #else413 pHlp->pfnPrintf(pHlp, " Windows info: Not implemented on this platform\n");414 #endif415 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_STRICT431 /*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 #endif441 442 /*443 * Binary search444 */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 else455 break;456 }457 else if (iValue > paValues[i].iValue)458 {459 i++;460 if (i < iEnd)461 iStart = i;462 else463 break;464 }465 else466 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 else493 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 else500 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 if514 * none. This helps reduce the memory footprint515 * 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 else527 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);528 }529 else530 {531 if (pszName)532 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);533 else534 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 on605 * mapping a block of converted pixels to an ASCII character of similar606 * weigth. We do that by summing up all the 8-bit gray scale pixels in607 * that block, applying a conversion factor and getting an index into an608 * 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 work616 */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 the632 * different formats. We generally ignore alpha, unless it's633 * 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) * 8664 + ((u16Tmp >> 5) & 0x3f) * 4665 + ( 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) * 8671 + ((u16Tmp >> 5) & 0x1f) * 8672 + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );673 break;674 case SVGA3D_A4R4G4B4:675 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],676 ( ( u16Tmp & 0xf) * 16677 + ((u16Tmp >> 4) & 0xf) * 16678 + ((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 else815 AssertFailed();816 break;817 818 }819 820 /*821 * Print we've reached the end of a block in y direction or if we're at822 * 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 else847 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' = SVGA3dbool858 * - 'd' = uint32_t859 * - 'r' = float860 * - 'b' = SVGA3dBlendOp861 * - 'c' = SVGA3dColor, SVGA3dColorMask862 * - 'e' = SVGA3dBlendEquation863 * - 'm' = SVGA3dColorMask864 * - 'p' = SVGA3dCmpFunc865 * - 's' = SVGA3dStencilOp866 * - 'v' = SVGA3dVertexMaterial867 * - 'w' = SVGA3dWrapFlags868 */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 union993 {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 else1008 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, SVGA3dColorMask1018 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': //SVGA3dWrapFlags1022 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': //SVGA3dBlendOp1028 case 'e': //SVGA3dBlendEquation1029 case 'p': //SVGA3dCmpFunc1030 case 's': //SVGA3dStencilOp1031 case 'v': //SVGA3dVertexMaterial1032 case '*':1033 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);1034 break;1035 }1036 }1037 else1038 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);1039 }1040 else1041 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 else1103 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 union1117 {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': //SVGA3dTextureArgData1136 {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, SVGA3dColorMask1147 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': //SVGA3dTextureAddress1152 {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': //SVGA3dTextureFilter1163 {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': //SVGA3dTextureCoordGen1174 {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': //SVGA3dTextureCombiner1185 {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 else1206 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);1207 }1208 else1209 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");1210 return pszRet;1211 }1212 1213 1214 304 1215 305 -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
r57082 r57149 33 33 #include <iprt/avl.h> 34 34 35 #include <VBox/VMMDev.h> 36 #include <VBox/VBoxVideo.h> 37 #include <VBox/bioslogo.h> 35 #include <VBox/VBoxVideo.h> /* required by DevVGA.h */ 38 36 39 37 /* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */ … … 42 40 #include "DevVGA-SVGA.h" 43 41 #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" 49 43 50 44 /* Enable to disassemble defined shaders. */ … … 57 51 #endif 58 52 53 54 /******************************************************************************* 55 * Defined Constants And Macros * 56 *******************************************************************************/ 59 57 /* Enable to render the result of DrawPrimitive in a seperate window. */ 60 58 //#define DEBUG_GFX_WINDOW 61 59 62 /* Enable to use Wine to convert D3D to opengl */63 //#define VBOX_VMSVGA3D_WITH_OPENGL64 65 60 #define FOURCC_INTZ (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z') 66 61 #define FOURCC_NULL (D3DFORMAT)MAKEFOURCC('N', 'U', 'L', 'L') 62 67 63 68 64 /******************************************************************************* 69 65 * Structures and Typedefs * 70 66 *******************************************************************************/ 71 72 typedef struct73 {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 struct95 {96 /* Key is context id. */97 AVLU32NODECORE Core;98 union99 {100 IDirect3DSurface9 *pSurface;101 IDirect3DTexture9 *pTexture;102 IDirect3DCubeTexture9 *pCubeTexture;103 } u;104 } VMSVGA3DSHAREDSURFACE, *PVMSVGA3DSHAREDSURFACE;105 106 typedef struct107 {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 union128 {129 IDirect3DSurface9 *pSurface;130 IDirect3DCubeTexture9 *pCubeTexture;131 IDirect3DIndexBuffer9 *pIndexBuffer;132 IDirect3DTexture9 *pTexture;133 IDirect3DVertexBuffer9 *pVertexBuffer;134 } u;135 union136 {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 struct173 {174 uint32_t id;175 uint32_t cid;176 SVGA3dShaderType type;177 uint32_t cbData;178 void *pShaderProgram;179 union180 {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 struct201 {202 bool fValid;203 float matrix[16];204 } VMSVGATRANSFORMSTATE, *PVMSVGATRANSFORMSTATE;205 206 typedef struct207 {208 bool fValid;209 SVGA3dMaterial material;210 } VMSVGAMATERIALSTATE, *PVMSVGAMATERIALSTATE;211 212 typedef struct213 {214 bool fValid;215 float plane[4];216 } VMSVGACLIPPLANESTATE, *PVMSVGACLIPPLANESTATE;217 218 typedef struct219 {220 bool fEnabled;221 bool fValidData;222 SVGA3dLightData data;223 } VMSVGALIGHTSTATE, *PVMSVGALIGHTSTATE;224 225 typedef struct226 {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 VMSVGA3DCONTEXT252 {253 uint32_t id;254 #ifdef VBOX_VMSVGA3D_WITH_OPENGL255 IDirect3DDevice9 *pDevice;256 #else257 IDirect3DDevice9Ex *pDevice;258 #endif259 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 struct271 {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 VMSVGA3DSTATE332 {333 #ifdef VBOX_VMSVGA3D_WITH_OPENGL334 IDirect3D9 *pD3D9;335 #else336 IDirect3D9Ex *pD3D9;337 #endif338 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 };379 67 380 68 typedef struct … … 385 73 } VMSVGA3DFORMATSUPPORT; 386 74 387 VMSVGA3DFORMATSUPPORT aFormatSupport[] = 75 76 /******************************************************************************* 77 * Global Variables * 78 *******************************************************************************/ 79 static VMSVGA3DFORMATSUPPORT const g_aFormatSupport[] = 388 80 { 389 81 { … … 444 136 }; 445 137 446 VMSVGA3DFORMATSUPPORTaFeatureReject[] =138 static VMSVGA3DFORMATSUPPORT const g_aFeatureReject[] = 447 139 { 448 140 { … … 463 155 }; 464 156 157 158 /******************************************************************************* 159 * Internal Functions * 160 *******************************************************************************/ 465 161 static 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 162 static int vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface); 163 164 470 165 471 166 int vmsvga3dInit(PVGASTATE pThis) … … 505 200 return VINF_SUCCESS; /* already initialized (load state) */ 506 201 507 #ifdef VBOX_VMSVGA3D_WITH_ OPENGL202 #ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL 508 203 pState->pD3D9 = Direct3DCreate9(D3D_SDK_VERSION); 509 204 AssertReturn(pState->pD3D9, VERR_INTERNAL_ERROR); … … 630 325 } 631 326 632 /* Shared functions that depend on private structure definitions. */633 #define VMSVGA3D_DIRECT3D634 #include "DevVGA-SVGA3d-shared.h"635 636 327 637 328 static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_t idx3dCaps, D3DFORMAT format) … … 649 340 format); 650 341 651 for (unsigned i = 0; i < RT_ELEMENTS( aFormatSupport); i++)342 for (unsigned i = 0; i < RT_ELEMENTS(g_aFormatSupport); i++) 652 343 { 653 344 hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 654 345 D3DDEVTYPE_HAL, 655 346 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, 658 349 format); 659 350 if (hr == D3D_OK) 660 result |= aFormatSupport[i].FormatOp;351 result |= g_aFormatSupport[i].FormatOp; 661 352 } 662 353 … … 664 355 if (result) 665 356 { 666 for (unsigned i = 0; i < RT_ELEMENTS( aFeatureReject); i++)357 for (unsigned i = 0; i < RT_ELEMENTS(g_aFeatureReject); i++) 667 358 { 668 359 hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 669 360 D3DDEVTYPE_HAL, 670 361 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, 673 364 format); 674 365 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: 680 371 * 681 372 * SVGA3DFORMAT_OP_PIXELSIZE … … 1748 1439 } 1749 1440 1750 #ifdef VBOX_VMSVGA3D_WITH_ OPENGL1441 #ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL 1751 1442 #define vmsvga3dSurfaceTrackUsage(a, b, c) 1752 1443 #define vmsvga3dSurfaceFlush(a, b) 1753 #else 1444 #else /* !VBOX_VMSVGA3D_WITH_WINE_OPENGL */ 1754 1445 /* Inject a query event into the D3D pipeline so we can check when usage of this surface has finished. 1755 1446 * (D3D does not synchronize shared surface usage) … … 1814 1505 return VINF_SUCCESS; 1815 1506 } 1816 #endif /* VBOX_VMSVGA3D_WITH_OPENGL */1507 #endif /* !VBOX_VMSVGA3D_WITH_WINE_OPENGL */ 1817 1508 1818 1509 int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, uint32_t cCopyBoxes, SVGA3dCopyBox *pBox) … … 1885 1576 vmsvga3dSurfaceFlush(pThis, pSurfaceDest); 1886 1577 1887 #ifndef VBOX_VMSVGA3D_WITH_ OPENGL1578 #ifndef VBOX_VMSVGA3D_WITH_WINE_OPENGL 1888 1579 if ( fSrcTexture 1889 1580 && pSurfaceSrc->idAssociatedContext != cid) … … 3010 2701 PresParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 3011 2702 3012 #ifdef VBOX_VMSVGA3D_WITH_ OPENGL2703 #ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL 3013 2704 hr = pState->pD3D9->CreateDevice(D3DADAPTER_DEFAULT, 3014 2705 D3DDEVTYPE_HAL, … … 3163 2854 } 3164 2855 3165 #ifdef VBOX_VMSVGA3D_WITH_ OPENGL2856 #ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL 3166 2857 #define vmsvga3dContextTrackUsage(pThis, pContext) 3167 2858 #else … … 3347 3038 PresParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;; 3348 3039 3349 #ifdef VBOX_VMSVGA3D_WITH_ OPENGL3040 #ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL 3350 3041 hr = pContext->pDevice->Reset(&PresParam); 3351 3042 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dChangeMode: Reset failed with %x\n", hr), VERR_INTERNAL_ERROR); … … 4487 4178 } 4488 4179 4489 #ifndef VBOX_VMSVGA3D_WITH_ OPENGL4180 #ifndef VBOX_VMSVGA3D_WITH_WINE_OPENGL 4490 4181 if (pRenderTarget->idAssociatedContext != cid) 4491 4182 { … … 4850 4541 } 4851 4542 4852 #ifndef VBOX_VMSVGA3D_WITH_ OPENGL4543 #ifndef VBOX_VMSVGA3D_WITH_WINE_OPENGL 4853 4544 if (pSurface->idAssociatedContext != cid) 4854 4545 { -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
r57082 r57149 1 /* $Id$ */ 1 2 /** @file 2 3 * DevVMWare - VMWare SVGA device - 3D part. … … 43 44 /* DevVGA-SVGA.cpp: */ 44 45 void 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);46 int 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); 47 48 void vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(PVGASTATE pThis, uint32_t sid); 48 49 -
trunk/src/VBox/Devices/Makefile.kmk
r56967 r57149 256 256 ifdef VBOX_WITH_VMSVGA3D 257 257 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 259 262 if "$(KBUILD_TARGET)" == "win" && !defined(VBOX_WITH_VMSVGA3D_USE_OPENGL) 263 VBoxDD_DEFS += VMSVGA3D_DIRECT3D 260 264 VBoxDD_SOURCES += Graphics/DevVGA-SVGA3d-win.cpp 261 265 VBoxDD_LIBS.win += d3d9.lib $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib 262 266 VBoxDD_LDFLAGS.win += /DELAYLOAD:d3d9.dll 263 267 else 268 VBoxDD_DEFS += VMSVGA3D_OPENGL 264 269 VBoxDD_SOURCES += \ 265 270 Graphics/DevVGA-SVGA3d-ogl.cpp \
Note:
See TracChangeset
for help on using the changeset viewer.