Changeset 86838 in vbox for trunk/src/VBox/Devices/Graphics
- Timestamp:
- Nov 9, 2020 11:16:50 PM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
r86479 r86838 37 37 #endif 38 38 39 #ifdef DUMP_BITMAPS 40 # include <iprt/formats/bmp.h> 41 # include <stdio.h> 42 #endif 39 43 40 44 #if defined(LOG_ENABLED) || defined(VBOX_STRICT) … … 272 276 273 277 278 #if !defined(VMSVGA3D_DX) 279 /* 280 * Stubs for old backends. 281 */ 282 int vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid) 283 { 284 RT_NOREF(pThisCC, pScreen, sid); 285 return VERR_NOT_IMPLEMENTED; 286 } 287 288 int vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect) 289 { 290 RT_NOREF(pThisCC, pScreen, pRect); 291 return VERR_NOT_IMPLEMENTED; 292 } 293 294 int vmsvga3dSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox, VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap) 295 { 296 RT_NOREF(pThisCC, pImage, pBox, enmMapType, pMap); 297 return VERR_NOT_IMPLEMENTED; 298 } 299 300 int vmsvga3dSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten) 301 { 302 RT_NOREF(pThisCC, pImage, pMap, fWritten); 303 return VERR_NOT_IMPLEMENTED; 304 } 305 #endif 306 307 308 /* 309 * 310 * Guest-Backed Objects (GBO). 311 * 312 */ 313 314 static int vmsvgaR3GboCreate(PVMSVGAR3STATE pSvgaR3State, SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, bool fGCPhys64, PVMSVGAGBO pGbo) 315 { 316 ASSERT_GUEST_RETURN(sizeInBytes <= _128M, VERR_INVALID_PARAMETER); /** @todo Less than SVGA_REG_MOB_MAX_SIZE */ 317 318 /* 319 * The 'baseAddress' is a page number and points to the 'root page' of the GBO. 320 * Content of the root page depends on the ptDepth value: 321 * SVGA3D_MOBFMT_PTDEPTH[64]_0 - the only data page; 322 * SVGA3D_MOBFMT_PTDEPTH[64]_1 - array of page numbers for data pages; 323 * SVGA3D_MOBFMT_PTDEPTH[64]_2 - array of page numbers for SVGA3D_MOBFMT_PTDEPTH[64]_1 pages. 324 * The code below extracts the page addresses of the GBO. 325 */ 326 327 /* Verify and normalize the ptDepth value. */ 328 if (RT_LIKELY(ptDepth >= SVGA3D_MOBFMT_PTDEPTH64_0 && ptDepth <= SVGA3D_MOBFMT_PTDEPTH64_2)) 329 ASSERT_GUEST_RETURN(fGCPhys64, VERR_INVALID_PARAMETER); 330 else if (ptDepth >= SVGA3D_MOBFMT_PTDEPTH_0 && ptDepth <= SVGA3D_MOBFMT_PTDEPTH_2) 331 { 332 ASSERT_GUEST_RETURN(!fGCPhys64, VERR_INVALID_PARAMETER); 333 /* Shift ptDepth to the SVGA3D_MOBFMT_PTDEPTH64_x range. */ 334 ptDepth = (SVGAMobFormat)(ptDepth + SVGA3D_MOBFMT_PTDEPTH64_0 - SVGA3D_MOBFMT_PTDEPTH_0); 335 } 336 else if (ptDepth == SVGA3D_MOBFMT_RANGE) 337 { } 338 else 339 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER); 340 341 uint32_t const cPPNsPerPage = X86_PAGE_SIZE / (fGCPhys64 ? sizeof(PPN64) : sizeof(PPN)); 342 343 pGbo->cbTotal = sizeInBytes; 344 pGbo->cTotalPages = (sizeInBytes + X86_PAGE_SIZE - 1) >> X86_PAGE_SHIFT; 345 346 /* Allocate the maximum amount possible (everything non-continuous) */ 347 PVMSVGAGBODESCRIPTOR paDescriptors = (PVMSVGAGBODESCRIPTOR)RTMemAlloc(pGbo->cTotalPages * sizeof(VMSVGAGBODESCRIPTOR)); 348 AssertReturn(paDescriptors, VERR_NO_MEMORY); 349 350 int rc = VINF_SUCCESS; 351 if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_0) 352 { 353 ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages == 1, 354 RTMemFree(paDescriptors), 355 VERR_INVALID_PARAMETER); 356 357 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT; 358 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 359 paDescriptors[0].GCPhys = GCPhys; 360 paDescriptors[0].cPages = 1; 361 } 362 else if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_1) 363 { 364 ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages <= cPPNsPerPage, 365 RTMemFree(paDescriptors), 366 VERR_INVALID_PARAMETER); 367 368 /* Read the root page. */ 369 uint8_t au8RootPage[X86_PAGE_SIZE]; 370 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT; 371 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, &au8RootPage, sizeof(au8RootPage)); 372 if (RT_SUCCESS(rc)) 373 { 374 PPN64 *paPPN64 = (PPN64 *)&au8RootPage[0]; 375 PPN *paPPN32 = (PPN *)&au8RootPage[0]; 376 for (uint32_t iPPN = 0; iPPN < pGbo->cTotalPages; ++iPPN) 377 { 378 GCPhys = (RTGCPHYS)(fGCPhys64 ? paPPN64[iPPN] : paPPN32[iPPN]) << X86_PAGE_SHIFT; 379 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 380 paDescriptors[iPPN].GCPhys = GCPhys; 381 paDescriptors[iPPN].cPages = 1; 382 } 383 } 384 } 385 else if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_2) 386 { 387 ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages <= cPPNsPerPage * cPPNsPerPage, 388 RTMemFree(paDescriptors), 389 VERR_INVALID_PARAMETER); 390 391 /* Read the Level2 root page. */ 392 uint8_t au8RootPageLevel2[X86_PAGE_SIZE]; 393 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT; 394 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, &au8RootPageLevel2, sizeof(au8RootPageLevel2)); 395 if (RT_SUCCESS(rc)) 396 { 397 uint32_t cPagesLeft = pGbo->cTotalPages; 398 399 PPN64 *paPPN64Level2 = (PPN64 *)&au8RootPageLevel2[0]; 400 PPN *paPPN32Level2 = (PPN *)&au8RootPageLevel2[0]; 401 402 uint32_t const cPPNsLevel2 = (pGbo->cTotalPages + cPPNsPerPage - 1) / cPPNsPerPage; 403 for (uint32_t iPPNLevel2 = 0; iPPNLevel2 < cPPNsLevel2; ++iPPNLevel2) 404 { 405 /* Read the Level1 root page. */ 406 uint8_t au8RootPage[X86_PAGE_SIZE]; 407 RTGCPHYS GCPhysLevel1 = (RTGCPHYS)(fGCPhys64 ? paPPN64Level2[iPPNLevel2] : paPPN32Level2[iPPNLevel2]) << X86_PAGE_SHIFT; 408 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 409 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhysLevel1, &au8RootPage, sizeof(au8RootPage)); 410 if (RT_SUCCESS(rc)) 411 { 412 PPN64 *paPPN64 = (PPN64 *)&au8RootPage[0]; 413 PPN *paPPN32 = (PPN *)&au8RootPage[0]; 414 415 uint32_t const cPPNs = RT_MIN(cPagesLeft, cPPNsPerPage); 416 for (uint32_t iPPN = 0; iPPN < cPPNs; ++iPPN) 417 { 418 GCPhys = (RTGCPHYS)(fGCPhys64 ? paPPN64[iPPN] : paPPN32[iPPN]) << X86_PAGE_SHIFT; 419 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 420 paDescriptors[iPPN + iPPNLevel2 * cPPNsPerPage].GCPhys = GCPhys; 421 paDescriptors[iPPN + iPPNLevel2 * cPPNsPerPage].cPages = 1; 422 } 423 cPagesLeft -= cPPNs; 424 } 425 } 426 } 427 } 428 else if (ptDepth == SVGA3D_MOBFMT_RANGE) 429 { 430 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT; 431 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 432 paDescriptors[0].GCPhys = GCPhys; 433 paDescriptors[0].cPages = pGbo->cTotalPages; 434 } 435 else 436 { 437 AssertFailed(); 438 return VERR_INTERNAL_ERROR; /* ptDepth should be already verified. */ 439 } 440 441 /* Compress the descriptors. */ 442 if (ptDepth != SVGA3D_MOBFMT_RANGE) 443 { 444 uint32_t iDescriptor = 0; 445 for (uint32_t i = 1; i < pGbo->cTotalPages; ++i) 446 { 447 /* Continuous physical memory? */ 448 if (paDescriptors[i].GCPhys == paDescriptors[iDescriptor].GCPhys + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE) 449 { 450 Assert(paDescriptors[iDescriptor].cPages); 451 paDescriptors[iDescriptor].cPages++; 452 Log5Func(("Page %x GCPhys=%RGp successor\n", i, paDescriptors[i].GCPhys)); 453 } 454 else 455 { 456 iDescriptor++; 457 paDescriptors[iDescriptor].GCPhys = paDescriptors[i].GCPhys; 458 paDescriptors[iDescriptor].cPages = 1; 459 Log5Func(("Page %x GCPhys=%RGp\n", i, paDescriptors[iDescriptor].GCPhys)); 460 } 461 } 462 463 pGbo->cDescriptors = iDescriptor + 1; 464 Log5Func(("Nr of descriptors %d\n", pGbo->cDescriptors)); 465 } 466 else 467 pGbo->cDescriptors = 1; 468 469 if (RT_LIKELY(pGbo->cDescriptors < pGbo->cTotalPages)) 470 { 471 pGbo->paDescriptors = (PVMSVGAGBODESCRIPTOR)RTMemRealloc(paDescriptors, pGbo->cDescriptors * sizeof(VMSVGAGBODESCRIPTOR)); 472 AssertReturn(pGbo->paDescriptors, VERR_NO_MEMORY); 473 } 474 else 475 pGbo->paDescriptors = paDescriptors; 476 477 return VINF_SUCCESS; 478 } 479 480 481 static void vmsvgaR3GboDestroy(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo) 482 { 483 RT_NOREF(pSvgaR3State); 484 if (RT_LIKELY(VMSVGA_IS_GBO_CREATED(pGbo))) 485 { 486 RTMemFree(pGbo->paDescriptors); 487 RT_ZERO(pGbo); 488 } 489 } 490 491 492 typedef enum VMSVGAGboTransferDirection 493 { 494 VMSVGAGboTransferDirection_Read, 495 VMSVGAGboTransferDirection_Write, 496 } VMSVGAGboTransferDirection; 497 498 static int vmsvgaR3GboTransfer(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo, 499 uint32_t off, void *pvData, uint32_t cbData, 500 VMSVGAGboTransferDirection enmDirection) 501 { 502 // ASMBreakpoint(); 503 int rc = VINF_SUCCESS; 504 uint8_t *pu8CurrentHost = (uint8_t *)pvData; 505 506 /* Find the right descriptor */ 507 PCVMSVGAGBODESCRIPTOR const paDescriptors = pGbo->paDescriptors; 508 uint32_t iDescriptor = 0; /* Index in the descriptor array. */ 509 uint32_t offDescriptor = 0; /* GMR offset of the current descriptor. */ 510 while (offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE <= off) 511 { 512 offDescriptor += paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE; 513 AssertReturn(offDescriptor < pGbo->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */ 514 ++iDescriptor; 515 AssertReturn(iDescriptor < pGbo->cDescriptors, VERR_INTERNAL_ERROR); 516 } 517 518 while (cbData) 519 { 520 uint32_t cbToCopy; 521 if (off + cbData <= offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE) 522 cbToCopy = cbData; 523 else 524 { 525 cbToCopy = (offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE - off); 526 AssertReturn(cbToCopy <= cbData, VERR_INVALID_PARAMETER); 527 } 528 529 RTGCPHYS const GCPhys = paDescriptors[iDescriptor].GCPhys + off - offDescriptor; 530 Log5Func(("%s phys=%RGp\n", (enmDirection == VMSVGAGboTransferDirection_Read) ? "READ" : "WRITE", GCPhys)); 531 532 if (enmDirection == VMSVGAGboTransferDirection_Read) 533 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, pu8CurrentHost, cbToCopy); 534 else 535 rc = PDMDevHlpPCIPhysWrite(pSvgaR3State->pDevIns, GCPhys, pu8CurrentHost, cbToCopy); 536 AssertRCBreak(rc); 537 538 cbData -= cbToCopy; 539 off += cbToCopy; 540 pu8CurrentHost += cbToCopy; 541 542 /* Go to the next descriptor if there's anything left. */ 543 if (cbData) 544 { 545 offDescriptor += paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE; 546 AssertReturn(offDescriptor < pGbo->cbTotal, VERR_INTERNAL_ERROR); 547 ++iDescriptor; 548 AssertReturn(iDescriptor < pGbo->cDescriptors, VERR_INTERNAL_ERROR); 549 } 550 } 551 return rc; 552 } 553 554 555 static int vmsvgaR3GboWrite(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo, 556 uint32_t off, void const *pvData, uint32_t cbData) 557 { 558 return vmsvgaR3GboTransfer(pSvgaR3State, pGbo, 559 off, (void *)pvData, cbData, 560 VMSVGAGboTransferDirection_Write); 561 } 562 563 564 static int vmsvgaR3GboRead(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo, 565 uint32_t off, void *pvData, uint32_t cbData) 566 { 567 return vmsvgaR3GboTransfer(pSvgaR3State, pGbo, 568 off, pvData, cbData, 569 VMSVGAGboTransferDirection_Read); 570 } 571 572 573 /* 574 * 575 * Object Tables. 576 * 577 */ 578 579 static int vmsvgaR3OTableVerifyIndex(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable, 580 uint32_t idx, uint32_t cbEntry) 581 { 582 RT_NOREF(pSvgaR3State); 583 584 /* The table must exist and the index must be within the table. */ 585 ASSERT_GUEST_RETURN(VMSVGA_IS_GBO_CREATED(pGboOTable), VERR_INVALID_PARAMETER); 586 ASSERT_GUEST_RETURN(idx < pGboOTable->cbTotal / cbEntry, VERR_INVALID_PARAMETER); 587 RT_UNTRUSTED_VALIDATED_FENCE(); 588 return VINF_SUCCESS; 589 } 590 591 592 static int vmsvgaR3OTableRead(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable, 593 uint32_t idx, uint32_t cbEntry, 594 void *pvData, uint32_t cbData) 595 { 596 AssertReturn(cbData <= cbEntry, VERR_INVALID_PARAMETER); 597 598 int rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, pGboOTable, idx, cbEntry); 599 if (RT_SUCCESS(rc)) 600 { 601 uint32_t const off = idx * cbEntry; 602 rc = vmsvgaR3GboRead(pSvgaR3State, pGboOTable, off, pvData, cbData); 603 } 604 return rc; 605 } 606 607 static int vmsvgaR3OTableWrite(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable, 608 uint32_t idx, uint32_t cbEntry, 609 void const *pvData, uint32_t cbData) 610 { 611 AssertReturn(cbData <= cbEntry, VERR_INVALID_PARAMETER); 612 613 int rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, pGboOTable, idx, cbEntry); 614 if (RT_SUCCESS(rc)) 615 { 616 uint32_t const off = idx * cbEntry; 617 rc = vmsvgaR3GboWrite(pSvgaR3State, pGboOTable, off, pvData, cbData); 618 } 619 return rc; 620 } 621 622 623 /* 624 * 625 * The guest's Memory OBjects (MOB). 626 * 627 */ 628 629 static int vmsvgaR3MobCreate(PVMSVGAR3STATE pSvgaR3State, 630 SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, SVGAMobId mobid, 631 bool fGCPhys64, PVMSVGAMOB pMob) 632 { 633 RT_ZERO(*pMob); 634 635 /* Update the entry in the pSvgaR3State->pGboOTableMob. */ 636 SVGAOTableMobEntry entry; 637 entry.ptDepth = ptDepth; 638 entry.sizeInBytes = sizeInBytes; 639 entry.base = baseAddress; 640 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableMob, 641 mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry)); 642 if (RT_SUCCESS(rc)) 643 { 644 /* Create the corresponding GBO. */ 645 rc = vmsvgaR3GboCreate(pSvgaR3State, ptDepth, baseAddress, sizeInBytes, fGCPhys64, &pMob->Gbo); 646 if (RT_SUCCESS(rc)) 647 { 648 /* Add to the tree of known GBOs and the LRU list. */ 649 pMob->Core.Key = mobid; 650 if (RTAvlU32Insert(&pSvgaR3State->MOBTree, &pMob->Core)) 651 { 652 RTListPrepend(&pSvgaR3State->MOBLRUList, &pMob->nodeLRU); 653 return VINF_SUCCESS; 654 } 655 656 vmsvgaR3GboDestroy(pSvgaR3State, &pMob->Gbo); 657 } 658 } 659 660 return rc; 661 } 662 663 664 static int vmsvgaR3MobDestroy(PVMSVGAR3STATE pSvgaR3State, SVGAMobId mobid) 665 { 666 /* Update the entry in the pSvgaR3State->pGboOTableMob. */ 667 SVGAOTableMobEntry entry; 668 RT_ZERO(entry); 669 vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableMob, 670 mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry)); 671 672 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Remove(&pSvgaR3State->MOBTree, mobid); 673 if (pMob) 674 { 675 RTListNodeRemove(&pMob->nodeLRU); 676 vmsvgaR3GboDestroy(pSvgaR3State, &pMob->Gbo); 677 RTMemFree(pMob); 678 return VINF_SUCCESS; 679 } 680 681 return VERR_INVALID_PARAMETER; 682 } 683 684 685 static PVMSVGAMOB vmsvgaR3MobGet(PVMSVGAR3STATE pSvgaR3State, SVGAMobId mobid) 686 { 687 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Get(&pSvgaR3State->MOBTree, mobid); 688 if (pMob) 689 { 690 /* Move to the head of the LRU list. */ 691 RTListNodeRemove(&pMob->nodeLRU); 692 RTListPrepend(&pSvgaR3State->MOBLRUList, &pMob->nodeLRU); 693 } 694 695 return pMob; 696 } 697 698 /* 699 * Screen objects. 700 */ 274 701 VMSVGASCREENOBJECT *vmsvgaR3GetScreenObject(PVGASTATECC pThisCC, uint32_t idScreen) 275 702 { … … 435 862 436 863 #ifdef VBOX_WITH_VMSVGA3D 864 865 /* 866 * SVGA_3D_CMD_* handlers. 867 */ 868 869 870 /** SVGA_3D_CMD_SURFACE_DEFINE 1040, SVGA_3D_CMD_SURFACE_DEFINE_V2 1070 871 * 872 * @param pThisCC The VGA/VMSVGA state for the current context. 873 * @param pCmd The VMSVGA command. 874 * @param cMipLevelSizes Number of elements in the paMipLevelSizes array. 875 * @param paMipLevelSizes Arrays of surface sizes for each face and miplevel. 876 */ 877 static void vmsvga3dCmdDefineSurface(PVGASTATECC pThisCC, SVGA3dCmdDefineSurface_v2 const *pCmd, 878 uint32_t cMipLevelSizes, SVGA3dSize *paMipLevelSizes) 879 { 880 ASSERT_GUEST_RETURN_VOID(pCmd->sid < SVGA3D_MAX_SURFACE_IDS); 881 ASSERT_GUEST_RETURN_VOID(cMipLevelSizes >= 1); 882 RT_UNTRUSTED_VALIDATED_FENCE(); 883 884 /* Number of faces (cFaces) is specified as the number of the first non-zero elements in the 'face' array. 885 * Since only plain surfaces (cFaces == 1) and cubemaps (cFaces == 6) are supported 886 * (see also SVGA3dCmdDefineSurface definition in svga3d_reg.h), we ignore anything else. 887 */ 888 uint32_t cRemainingMipLevels = cMipLevelSizes; 889 uint32_t cFaces = 0; 890 for (uint32_t i = 0; i < SVGA3D_MAX_SURFACE_FACES; ++i) 891 { 892 if (pCmd->face[i].numMipLevels == 0) 893 break; 894 895 /* All SVGA3dSurfaceFace structures must have the same value of numMipLevels field */ 896 ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels == pCmd->face[0].numMipLevels); 897 898 /* numMipLevels value can't be greater than the number of remaining elements in the paMipLevelSizes array. */ 899 ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels <= cRemainingMipLevels); 900 cRemainingMipLevels -= pCmd->face[i].numMipLevels; 901 902 ++cFaces; 903 } 904 for (uint32_t i = cFaces; i < SVGA3D_MAX_SURFACE_FACES; ++i) 905 ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels == 0); 906 907 /* cFaces must be 6 for a cubemap and 1 otherwise. */ 908 ASSERT_GUEST_RETURN_VOID(cFaces == (uint32_t)((pCmd->surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1)); 909 910 /* Sum of face[i].numMipLevels must be equal to cMipLevels. */ 911 ASSERT_GUEST_RETURN_VOID(cRemainingMipLevels == 0); 912 RT_UNTRUSTED_VALIDATED_FENCE(); 913 914 /* Verify paMipLevelSizes */ 915 uint32_t cWidth = paMipLevelSizes[0].width; 916 uint32_t cHeight = paMipLevelSizes[0].height; 917 uint32_t cDepth = paMipLevelSizes[0].depth; 918 for (uint32_t i = 1; i < pCmd->face[0].numMipLevels; ++i) 919 { 920 cWidth >>= 1; 921 if (cWidth == 0) cWidth = 1; 922 cHeight >>= 1; 923 if (cHeight == 0) cHeight = 1; 924 cDepth >>= 1; 925 if (cDepth == 0) cDepth = 1; 926 for (uint32_t iFace = 0; iFace < cFaces; ++iFace) 927 { 928 uint32_t const iMipLevelSize = iFace * pCmd->face[0].numMipLevels + i; 929 ASSERT_GUEST_RETURN_VOID( cWidth == paMipLevelSizes[iMipLevelSize].width 930 && cHeight == paMipLevelSizes[iMipLevelSize].height 931 && cDepth == paMipLevelSizes[iMipLevelSize].depth); 932 } 933 } 934 RT_UNTRUSTED_VALIDATED_FENCE(); 935 936 /* Create the surface. */ 937 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, 938 pCmd->multisampleCount, pCmd->autogenFilter, 939 pCmd->face[0].numMipLevels, &paMipLevelSizes[0]); 940 } 941 942 943 /* SVGA_3D_CMD_DEFINE_GB_MOB 1093 */ 944 static void vmsvga3dCmdDefineGBMob(PVGASTATECC pThisCC, SVGA3dCmdDefineGBMob const *pCmd) 945 { 946 ASMBreakpoint(); 947 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 948 949 ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */ 950 951 /* Maybe just update the OTable and create Gbo when the MOB is actually accessed? */ 952 /* Allocate a structure for the MOB. */ 953 PVMSVGAMOB pMob = (PVMSVGAMOB)RTMemAllocZ(sizeof(*pMob)); 954 AssertPtrReturnVoid(pMob); 955 956 int rc = vmsvgaR3MobCreate(pSvgaR3State, pCmd->ptDepth, pCmd->base, pCmd->sizeInBytes, pCmd->mobid, /*fGCPhys64=*/ false, pMob); 957 if (RT_SUCCESS(rc)) 958 { 959 return; 960 } 961 962 AssertFailed(); 963 964 RTMemFree(pMob); 965 } 966 967 968 /* SVGA_3D_CMD_DESTROY_GB_MOB 1094 */ 969 static void vmsvga3dCmdDestroyGBMob(PVGASTATECC pThisCC, SVGA3dCmdDestroyGBMob const *pCmd) 970 { 971 // ASMBreakpoint(); 972 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 973 974 ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */ 975 976 int rc = vmsvgaR3MobDestroy(pSvgaR3State, pCmd->mobid); 977 if (RT_SUCCESS(rc)) 978 { 979 return; 980 } 981 982 AssertFailed(); 983 } 984 985 986 /* SVGA_3D_CMD_DEFINE_GB_SURFACE 1097 */ 987 static void vmsvga3dCmdDefineGBSurface(PVGASTATECC pThisCC, SVGA3dCmdDefineGBSurface const *pCmd) 988 { 989 // ASMBreakpoint(); 990 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 991 992 /* Update the entry in the pSvgaR3State->pGboOTableSurface. */ 993 SVGAOTableSurfaceEntry entry; 994 RT_ZERO(entry); 995 entry.format = pCmd->format; 996 entry.surfaceFlags = pCmd->surfaceFlags; 997 entry.numMipLevels = pCmd->numMipLevels; 998 entry.multisampleCount = pCmd->multisampleCount; 999 entry.autogenFilter = pCmd->autogenFilter; 1000 entry.size = pCmd->size; 1001 entry.mobid = SVGA_ID_INVALID; 1002 // entry.arraySize = 0; 1003 // entry.mobPitch = 0; 1004 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1005 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry)); 1006 if (RT_SUCCESS(rc)) 1007 { 1008 /* Create the host surface. */ 1009 /** @todo fGBO = true flag. */ 1010 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, 1011 pCmd->multisampleCount, pCmd->autogenFilter, 1012 pCmd->numMipLevels, &pCmd->size); 1013 } 1014 } 1015 1016 1017 /* SVGA_3D_CMD_DESTROY_GB_SURFACE 1098 */ 1018 static void vmsvga3dCmdDestroyGBSurface(PVGASTATECC pThisCC, SVGA3dCmdDestroyGBSurface const *pCmd) 1019 { 1020 // ASMBreakpoint(); 1021 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1022 1023 /* Update the entry in the pSvgaR3State->pGboOTableSurface. */ 1024 SVGAOTableSurfaceEntry entry; 1025 RT_ZERO(entry); 1026 entry.mobid = SVGA_ID_INVALID; 1027 vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1028 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry)); 1029 1030 vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid); 1031 } 1032 1033 1034 /* SVGA_3D_CMD_BIND_GB_SURFACE 1099 */ 1035 static void vmsvga3dCmdBindGBSurface(PVGASTATECC pThisCC, SVGA3dCmdBindGBSurface const *pCmd) 1036 { 1037 // ASMBreakpoint(); 1038 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1039 RT_NOREF(pCmd, pSvgaR3State); 1040 1041 /* Assign the mobid to the surface. */ 1042 int rc = VINF_SUCCESS; 1043 if (pCmd->mobid != SVGA_ID_INVALID) 1044 rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->GboOTableMob, 1045 pCmd->mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE); 1046 if (RT_SUCCESS(rc)) 1047 { 1048 SVGAOTableSurfaceEntry entry; 1049 rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1050 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry)); 1051 if (RT_SUCCESS(rc)) 1052 { 1053 entry.mobid = pCmd->mobid; 1054 rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1055 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry)); 1056 if (RT_SUCCESS(rc)) 1057 { 1058 /* */ 1059 } 1060 } 1061 } 1062 } 1063 1064 1065 #ifdef DUMP_BITMAPS 1066 static int vmsvga3dBmpWrite(const char *pszFilename, VMSVGA3D_MAPPED_SURFACE const *pMap) 1067 { 1068 if (pMap->cbPixel != 4) 1069 return VERR_NOT_SUPPORTED; 1070 1071 int const w = pMap->box.w; 1072 int const h = pMap->box.h; 1073 1074 const int cbBitmap = w * h * 4; 1075 1076 FILE *f = fopen(pszFilename, "wb"); 1077 if (!f) 1078 return VERR_FILE_NOT_FOUND; 1079 1080 { 1081 BMPFILEHDR fileHdr; 1082 RT_ZERO(fileHdr); 1083 fileHdr.uType = BMP_HDR_MAGIC; 1084 fileHdr.cbFileSize = sizeof(BMPFILEHDR) + sizeof(BMPWIN3XINFOHDR) + cbBitmap; 1085 fileHdr.offBits = sizeof(BMPFILEHDR) + sizeof(BMPWIN3XINFOHDR); 1086 1087 BMPWIN3XINFOHDR coreHdr; 1088 RT_ZERO(coreHdr); 1089 coreHdr.cbSize = sizeof(coreHdr); 1090 coreHdr.uWidth = w; 1091 coreHdr.uHeight = -h; 1092 coreHdr.cPlanes = 1; 1093 coreHdr.cBits = 32; 1094 coreHdr.cbSizeImage = cbBitmap; 1095 1096 fwrite(&fileHdr, 1, sizeof(fileHdr), f); 1097 fwrite(&coreHdr, 1, sizeof(coreHdr), f); 1098 } 1099 1100 if (pMap->cbPixel == 4) 1101 { 1102 const uint8_t *s = (uint8_t *)pMap->pvData; 1103 for (int32_t y = 0; y < h; ++y) 1104 { 1105 fwrite(s, 1, w * pMap->cbPixel, f); 1106 1107 s += pMap->cbRowPitch; 1108 } 1109 } 1110 1111 fclose(f); 1112 1113 return VINF_SUCCESS; 1114 } 1115 1116 1117 void vmsvga3dMapWriteBmpFile(VMSVGA3D_MAPPED_SURFACE const *pMap, char const *pszPrefix) 1118 { 1119 static int idxBitmap = 0; 1120 char *pszFilename = RTStrAPrintf2("bmp\\%s%d.bmp", pszPrefix, idxBitmap++); 1121 vmsvga3dBmpWrite(pszFilename, pMap); 1122 RTStrFree(pszFilename); 1123 } 1124 #endif /* DUMP_BITMAPS */ 1125 1126 1127 /* SVGA_3D_CMD_UPDATE_GB_IMAGE 1101 */ 1128 static void vmsvga3dCmdUpdateGBImage(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBImage const *pCmd) 1129 { 1130 // ASMBreakpoint(); 1131 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1132 1133 LogFlowFunc(("sid=%u @%u,%u,%u %ux%ux%u\n", 1134 pCmd->image.sid, pCmd->box.x, pCmd->box.y, pCmd->box.z, pCmd->box.w, pCmd->box.h, pCmd->box.d)); 1135 1136 /* "update a surface from its backing MOB." */ 1137 SVGAOTableSurfaceEntry entrySurface; 1138 int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1139 pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface)); 1140 if (RT_SUCCESS(rc)) 1141 { 1142 PVMSVGAMOB pMob = vmsvgaR3MobGet(pSvgaR3State, entrySurface.mobid); 1143 if (pMob) 1144 { 1145 VMSVGA3D_MAPPED_SURFACE map; 1146 rc = vmsvga3dSurfaceMap(pThisCC, &pCmd->image, &pCmd->box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map); 1147 if (RT_SUCCESS(rc)) 1148 { 1149 /* Copy MOB -> mapped surface. */ 1150 uint32_t offSrc = pCmd->box.x * map.cbPixel 1151 + pCmd->box.y * entrySurface.size.width * map.cbPixel 1152 + pCmd->box.z * entrySurface.size.height * entrySurface.size.width * map.cbPixel; 1153 uint8_t *pu8Dst = (uint8_t *)map.pvData; 1154 for (uint32_t z = 0; z < pCmd->box.d; ++z) 1155 { 1156 for (uint32_t y = 0; y < pCmd->box.h; ++y) 1157 { 1158 rc = vmsvgaR3GboRead(pSvgaR3State, &pMob->Gbo, offSrc, pu8Dst, pCmd->box.w * map.cbPixel); 1159 if (RT_FAILURE(rc)) 1160 break; 1161 1162 pu8Dst += map.cbRowPitch; 1163 offSrc += entrySurface.size.width * map.cbPixel; 1164 } 1165 1166 pu8Dst += map.cbDepthPitch; 1167 offSrc += entrySurface.size.height * entrySurface.size.width * map.cbPixel; 1168 } 1169 1170 // vmsvga3dMapWriteBmpFile(&map, "Dynamic"); 1171 1172 vmsvga3dSurfaceUnmap(pThisCC, &pCmd->image, &map, /* fWritten = */true); 1173 } 1174 } 1175 } 1176 } 1177 1178 1179 /* SVGA_3D_CMD_INVALIDATE_GB_SURFACE 1106 */ 1180 static void vmsvga3dCmdInvalidateGBSurface(PVGASTATECC pThisCC, SVGA3dCmdInvalidateGBSurface const *pCmd) 1181 { 1182 // ASMBreakpoint(); 1183 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1184 RT_NOREF(pSvgaR3State, pCmd); 1185 /** @todo Implement. */ 1186 } 1187 1188 1189 /* SVGA_3D_CMD_SET_OTABLE_BASE64 1115 */ 1190 static void vmsvga3dCmdSetOTableBase64(PVGASTATECC pThisCC, SVGA3dCmdSetOTableBase64 const *pCmd) 1191 { 1192 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1193 1194 /* 1195 * Create a GBO for the table. 1196 */ 1197 PVMSVGAGBO pGbo; 1198 switch (pCmd->type) 1199 { 1200 case SVGA_OTABLE_MOB: 1201 { 1202 pGbo = &pSvgaR3State->GboOTableMob; 1203 break; 1204 } 1205 case SVGA_OTABLE_SURFACE: 1206 { 1207 pGbo = &pSvgaR3State->GboOTableSurface; 1208 break; 1209 } 1210 case SVGA_OTABLE_CONTEXT: 1211 { 1212 pGbo = &pSvgaR3State->GboOTableContext; 1213 break; 1214 } 1215 case SVGA_OTABLE_SHADER: 1216 { 1217 pGbo = &pSvgaR3State->GboOTableShader; 1218 break; 1219 } 1220 case SVGA_OTABLE_SCREENTARGET: 1221 { 1222 pGbo = &pSvgaR3State->GboOTableScreenTarget; 1223 break; 1224 } 1225 default: 1226 pGbo = NULL; 1227 ASSERT_GUEST_FAILED(); 1228 break; 1229 } 1230 1231 if (pGbo) 1232 { 1233 /* Recreate. */ 1234 vmsvgaR3GboDestroy(pSvgaR3State, pGbo); 1235 int rc = vmsvgaR3GboCreate(pSvgaR3State, pCmd->ptDepth, pCmd->baseAddress, pCmd->sizeInBytes, /*fGCPhys64=*/ true, pGbo); 1236 AssertRC(rc); 1237 } 1238 } 1239 1240 1241 /* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET 1124 */ 1242 static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC, SVGA3dCmdDefineGBScreenTarget const *pCmd) 1243 { 1244 // ASMBreakpoint(); 1245 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1246 1247 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens)); 1248 ASSERT_GUEST_RETURN_VOID(pCmd->width > 0 && pCmd->width <= pThis->svga.u32MaxWidth); /* SVGA_REG_SCREENTARGET_MAX_WIDTH */ 1249 ASSERT_GUEST_RETURN_VOID(pCmd->height > 0 && pCmd->height <= pThis->svga.u32MaxHeight); /* SVGA_REG_SCREENTARGET_MAX_HEIGHT */ 1250 RT_UNTRUSTED_VALIDATED_FENCE(); 1251 1252 /* Update the entry in the pSvgaR3State->pGboOTableScreenTarget. */ 1253 SVGAOTableScreenTargetEntry entry; 1254 RT_ZERO(entry); 1255 entry.image.sid = SVGA_ID_INVALID; 1256 // entry.image.face = 0; 1257 // entry.image.mipmap = 0; 1258 entry.width = pCmd->width; 1259 entry.height = pCmd->height; 1260 entry.xRoot = pCmd->xRoot; 1261 entry.yRoot = pCmd->yRoot; 1262 entry.flags = pCmd->flags; 1263 entry.dpi = pCmd->dpi; 1264 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget, 1265 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry)); 1266 if (RT_SUCCESS(rc)) 1267 { 1268 /* Screen objects and screen targets are similar, therefore we will use the same for both. */ 1269 /** @todo Generic screen object/target interface. */ 1270 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid]; 1271 pScreen->fDefined = true; 1272 pScreen->fModified = true; 1273 pScreen->fuScreen = SVGA_SCREEN_MUST_BE_SET 1274 | (RT_BOOL(pCmd->flags & SVGA_STFLAG_PRIMARY) ? SVGA_SCREEN_IS_PRIMARY : 0); 1275 pScreen->idScreen = pCmd->stid; 1276 1277 pScreen->xOrigin = pCmd->xRoot; 1278 pScreen->yOrigin = pCmd->yRoot; 1279 pScreen->cWidth = pCmd->width; 1280 pScreen->cHeight = pCmd->height; 1281 pScreen->offVRAM = 0; /* Always for screen targets, they use either a separate memory buffer or a host window. */ 1282 pScreen->cbPitch = pCmd->width * 4; 1283 pScreen->cBpp = 32; 1284 1285 if (RT_LIKELY(pThis->svga.f3DEnabled)) 1286 vmsvga3dDefineScreen(pThis, pThisCC, pScreen); 1287 1288 if (!pScreen->pHwScreen) 1289 { 1290 /* System memory buffer. */ 1291 pScreen->pvScreenBitmap = RTMemAllocZ(pScreen->cHeight * pScreen->cbPitch); 1292 } 1293 1294 pThis->svga.fGFBRegisters = false; 1295 vmsvgaR3ChangeMode(pThis, pThisCC); 1296 } 1297 } 1298 1299 1300 /* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET 1125 */ 1301 static void vmsvga3dCmdDestroyGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC, SVGA3dCmdDestroyGBScreenTarget const *pCmd) 1302 { 1303 // ASMBreakpoint(); 1304 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1305 1306 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens)); 1307 RT_UNTRUSTED_VALIDATED_FENCE(); 1308 1309 /* Update the entry in the pSvgaR3State->pGboOTableScreenTarget. */ 1310 SVGAOTableScreenTargetEntry entry; 1311 RT_ZERO(entry); 1312 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget, 1313 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry)); 1314 if (RT_SUCCESS(rc)) 1315 { 1316 /* Screen objects and screen targets are similar, therefore we will use the same for both. */ 1317 /** @todo Generic screen object/target interface. */ 1318 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid]; 1319 pScreen->fModified = true; 1320 pScreen->fDefined = false; 1321 pScreen->idScreen = pCmd->stid; 1322 1323 if (RT_LIKELY(pThis->svga.f3DEnabled)) 1324 vmsvga3dDestroyScreen(pThisCC, pScreen); 1325 1326 vmsvgaR3ChangeMode(pThis, pThisCC); 1327 1328 RTMemFree(pScreen->pvScreenBitmap); 1329 pScreen->pvScreenBitmap = NULL; 1330 } 1331 } 1332 1333 1334 /* SVGA_3D_CMD_BIND_GB_SCREENTARGET 1126 */ 1335 static void vmsvga3dCmdBindGBScreenTarget(PVGASTATECC pThisCC, SVGA3dCmdBindGBScreenTarget const *pCmd) 1336 { 1337 // ASMBreakpoint(); 1338 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1339 1340 /* "Binding a surface to a Screen Target the same as flipping" */ 1341 1342 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens)); 1343 ASSERT_GUEST_RETURN_VOID(pCmd->image.face == 0 && pCmd->image.mipmap == 0); 1344 RT_UNTRUSTED_VALIDATED_FENCE(); 1345 1346 /* Assign the surface to the screen target. */ 1347 int rc = VINF_SUCCESS; 1348 if (pCmd->image.sid != SVGA_ID_INVALID) 1349 rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1350 pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE); 1351 if (RT_SUCCESS(rc)) 1352 { 1353 SVGAOTableScreenTargetEntry entry; 1354 rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget, 1355 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry)); 1356 if (RT_SUCCESS(rc)) 1357 { 1358 entry.image = pCmd->image; 1359 rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget, 1360 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry)); 1361 if (RT_SUCCESS(rc)) 1362 { 1363 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid]; 1364 rc = vmsvga3dScreenTargetBind(pThisCC, pScreen, pCmd->image.sid); 1365 AssertRC(rc); 1366 } 1367 } 1368 } 1369 } 1370 1371 1372 /* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET 1127 */ 1373 static void vmsvga3dCmdUpdateGBScreenTarget(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBScreenTarget const *pCmd) 1374 { 1375 // ASMBreakpoint(); 1376 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1377 1378 /* Update the screen target from its backing surface. */ 1379 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens)); 1380 RT_UNTRUSTED_VALIDATED_FENCE(); 1381 1382 /* Get the screen target info. */ 1383 SVGAOTableScreenTargetEntry entryScreenTarget; 1384 int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget, 1385 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entryScreenTarget, sizeof(entryScreenTarget)); 1386 if (RT_SUCCESS(rc)) 1387 { 1388 ASSERT_GUEST_RETURN_VOID(entryScreenTarget.image.face == 0 && entryScreenTarget.image.mipmap == 0); 1389 RT_UNTRUSTED_VALIDATED_FENCE(); 1390 1391 if (entryScreenTarget.image.sid != SVGA_ID_INVALID) 1392 { 1393 SVGAOTableSurfaceEntry entrySurface; 1394 rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface, 1395 entryScreenTarget.image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface)); 1396 if (RT_SUCCESS(rc)) 1397 { 1398 /* Copy entrySurface.mobid content to the screen target. */ 1399 if (entrySurface.mobid != SVGA_ID_INVALID) 1400 { 1401 RT_UNTRUSTED_VALIDATED_FENCE(); 1402 SVGA3dRect targetRect = pCmd->rect; 1403 1404 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid]; 1405 if (pScreen->pHwScreen) 1406 { 1407 /* Copy the screen target surface to the backend's screen. */ 1408 vmsvga3dScreenTargetUpdate(pThisCC, pScreen, &targetRect); 1409 } 1410 else if (pScreen->pvScreenBitmap) 1411 { 1412 /* Copy the screen target surface to the memory buffer. */ 1413 VMSVGA3D_MAPPED_SURFACE map; 1414 rc = vmsvga3dSurfaceMap(pThisCC, &entryScreenTarget.image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map); 1415 if (RT_SUCCESS(rc)) 1416 { 1417 uint8_t const *pu8Src = (uint8_t *)map.pvData 1418 + targetRect.x * map.cbPixel 1419 + targetRect.y * map.cbRowPitch; 1420 uint8_t *pu8Dst = (uint8_t *)pScreen->pvScreenBitmap 1421 + targetRect.x * map.cbPixel 1422 + targetRect.y * map.box.w * map.cbPixel; 1423 for (uint32_t y = 0; y < targetRect.h; ++y) 1424 { 1425 memcpy(pu8Dst, pu8Src, targetRect.w * map.cbPixel); 1426 1427 pu8Src += map.cbRowPitch; 1428 pu8Dst += map.box.w * map.cbPixel; 1429 } 1430 1431 vmsvga3dSurfaceUnmap(pThisCC, &entryScreenTarget.image, &map, /* fWritten = */ false); 1432 1433 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->rect.x, pCmd->rect.y, pCmd->rect.w, pCmd->rect.h); 1434 } 1435 else 1436 AssertFailed(); 1437 } 1438 } 1439 } 1440 } 1441 } 1442 } 1443 1444 1445 /* SVGA_3D_CMD_DEFINE_GB_MOB64 1135 */ 1446 static void vmsvga3dCmdDefineGBMob64(PVGASTATECC pThisCC, SVGA3dCmdDefineGBMob64 const *pCmd) 1447 { 1448 // ASMBreakpoint(); 1449 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 1450 1451 ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */ 1452 1453 /* Maybe just update the OTable and create Gbo when the MOB is actually accessed? */ 1454 /* Allocate a structure for the MOB. */ 1455 PVMSVGAMOB pMob = (PVMSVGAMOB)RTMemAllocZ(sizeof(*pMob)); 1456 AssertPtrReturnVoid(pMob); 1457 1458 int rc = vmsvgaR3MobCreate(pSvgaR3State, pCmd->ptDepth, pCmd->base, pCmd->sizeInBytes, pCmd->mobid, /*fGCPhys64=*/ true, pMob); 1459 if (RT_SUCCESS(rc)) 1460 { 1461 return; 1462 } 1463 1464 RTMemFree(pMob); 1465 } 1466 1467 437 1468 /** @def VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK 438 1469 * Check that the 3D command has at least a_cbMin of payload bytes after the … … 473 1504 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefine); 474 1505 475 uint32_t const cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 476 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0, 477 SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1)); 1506 SVGA3dCmdDefineSurface_v2 cmd; 1507 cmd.sid = pCmd->sid; 1508 cmd.surfaceFlags = pCmd->surfaceFlags; 1509 cmd.format = pCmd->format; 1510 memcpy(cmd.face, pCmd->face, sizeof(cmd.face)); 1511 cmd.multisampleCount = 0; 1512 cmd.autogenFilter = SVGA3D_TEX_FILTER_NONE; 1513 1514 uint32_t const cMipLevelSizes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 1515 vmsvga3dCmdDefineSurface(pThisCC, &cmd, cMipLevelSizes, (SVGA3dSize *)(pCmd + 1)); 478 1516 # ifdef DEBUG_GMR_ACCESS 479 1517 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis); … … 488 1526 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefineV2); 489 1527 490 uint32_t const cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 491 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face, 492 pCmd->multisampleCount, pCmd->autogenFilter, 493 cMipLevels, (SVGA3dSize *)(pCmd + 1)); 1528 uint32_t const cMipLevelSizes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 1529 vmsvga3dCmdDefineSurface(pThisCC, pCmd, cMipLevelSizes, (SVGA3dSize *)(pCmd + 1)); 1530 # ifdef DEBUG_GMR_ACCESS 1531 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis); 1532 # endif 494 1533 break; 495 1534 } … … 971 2010 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd; 972 2011 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 973 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2012 vmsvga3dCmdDestroyGBMob(pThisCC, pCmd); 974 2013 break; 975 2014 } … … 993 2032 SVGA3dCmdDefineGBSurface *pCmd = (SVGA3dCmdDefineGBSurface *)pvCmd; 994 2033 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 995 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2034 vmsvga3dCmdDefineGBSurface(pThisCC, pCmd); 996 2035 break; 997 2036 } … … 1001 2040 SVGA3dCmdDestroyGBSurface *pCmd = (SVGA3dCmdDestroyGBSurface *)pvCmd; 1002 2041 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1003 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2042 vmsvga3dCmdDestroyGBSurface(pThisCC, pCmd); 1004 2043 break; 1005 2044 } … … 1009 2048 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd; 1010 2049 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1011 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2050 vmsvga3dCmdBindGBSurface(pThisCC, pCmd); 1012 2051 break; 1013 2052 } … … 1025 2064 SVGA3dCmdUpdateGBImage *pCmd = (SVGA3dCmdUpdateGBImage *)pvCmd; 1026 2065 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1027 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2066 vmsvga3dCmdUpdateGBImage(pThisCC, pCmd); 1028 2067 break; 1029 2068 } … … 1065 2104 SVGA3dCmdInvalidateGBSurface *pCmd = (SVGA3dCmdInvalidateGBSurface *)pvCmd; 1066 2105 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1067 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2106 vmsvga3dCmdInvalidateGBSurface(pThisCC, pCmd); 1068 2107 break; 1069 2108 } … … 1137 2176 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd; 1138 2177 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1139 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2178 vmsvga3dCmdSetOTableBase64(pThisCC, pCmd); 1140 2179 break; 1141 2180 } … … 1206 2245 SVGA3dCmdDefineGBScreenTarget *pCmd = (SVGA3dCmdDefineGBScreenTarget *)pvCmd; 1207 2246 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1208 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2247 vmsvga3dCmdDefineGBScreenTarget(pThis, pThisCC, pCmd); 1209 2248 break; 1210 2249 } … … 1214 2253 SVGA3dCmdDestroyGBScreenTarget *pCmd = (SVGA3dCmdDestroyGBScreenTarget *)pvCmd; 1215 2254 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1216 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2255 vmsvga3dCmdDestroyGBScreenTarget(pThis, pThisCC, pCmd); 1217 2256 break; 1218 2257 } … … 1222 2261 SVGA3dCmdBindGBScreenTarget *pCmd = (SVGA3dCmdBindGBScreenTarget *)pvCmd; 1223 2262 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1224 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2263 vmsvga3dCmdBindGBScreenTarget(pThisCC, pCmd); 1225 2264 break; 1226 2265 } … … 1230 2269 SVGA3dCmdUpdateGBScreenTarget *pCmd = (SVGA3dCmdUpdateGBScreenTarget *)pvCmd; 1231 2270 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1232 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2271 vmsvga3dCmdUpdateGBScreenTarget(pThisCC, pCmd); 1233 2272 break; 1234 2273 } … … 1295 2334 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd; 1296 2335 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 1297 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);2336 vmsvga3dCmdDefineGBMob64(pThisCC, pCmd); 1298 2337 break; 1299 2338 } … … 2713 3752 } 2714 3753 3754 3755 /** 3756 * Clip. 3757 * 3758 * @param pBound Bounding rectangle. 3759 * @param pRect Rectangle to be clipped. 3760 */ 3761 void vmsvgaR3Clip3dRect(SVGA3dRect const *pBound, SVGA3dRect RT_UNTRUSTED_GUEST *pRect) 3762 { 3763 uint32_t const leftBound = pBound->x; 3764 uint32_t const rightBound = pBound->x + pBound->w; 3765 uint32_t const topBound = pBound->y; 3766 uint32_t const bottomBound = pBound->y + pBound->h; 3767 3768 uint32_t x = pRect->x; 3769 uint32_t y = pRect->y; 3770 uint32_t w = pRect->w; 3771 uint32_t h = pRect->h; 3772 3773 /* Make sure that right and bottom coordinates can be safely computed. */ 3774 if (x > rightBound) 3775 x = rightBound; 3776 if (w > rightBound - x) 3777 w = rightBound - x; 3778 if (y > bottomBound) 3779 y = bottomBound; 3780 if (h > bottomBound - y) 3781 h = bottomBound - y; 3782 3783 /* Switch from x, y, w, h to left, top, right, bottom. */ 3784 uint32_t left = x; 3785 uint32_t right = x + w; 3786 uint32_t top = y; 3787 uint32_t bottom = y + h; 3788 3789 /* A standard left, right, bottom, top clipping. */ 3790 if (left < leftBound) 3791 left = leftBound; 3792 if (right < leftBound) 3793 right = leftBound; 3794 3795 if (left > rightBound) 3796 left = rightBound; 3797 if (right > rightBound) 3798 right = rightBound; 3799 3800 if (top < topBound) 3801 top = topBound; 3802 if (bottom < topBound) 3803 bottom = topBound; 3804 3805 if (top > bottomBound) 3806 top = bottomBound; 3807 if (bottom > bottomBound) 3808 bottom = bottomBound; 3809 3810 /* Back to x, y, w, h representation. */ 3811 pRect->x = left; 3812 pRect->y = top; 3813 pRect->w = right - left; 3814 pRect->h = bottom - top; 3815 } 3816 -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-internal.h
r86265 r86838 29 29 #endif 30 30 31 #include <iprt/avl.h> 32 #include <iprt/list.h> 33 31 34 32 35 /********************************************************************************************************************************* … … 47 50 typedef struct 48 51 { 49 uint32_t 50 uint32_t 51 uint32_t 52 PVMSVGAGMRDESCRIPTOR 52 uint32_t cMaxPages; 53 uint32_t cbTotal; 54 uint32_t numDescriptors; 55 PVMSVGAGMRDESCRIPTOR paDesc; 53 56 } GMR, *PGMR; 57 58 /* 59 * GBO (Guest Backed Object). 60 * A GBO is a list of the guest pages. GBOs are used for VMSVGA MOBs (Memory OBjects) 61 * and Object Tables which the guest shares with the host. 62 * 63 * A GBO is similar to a GMR. Nevertheless I'll create a new code for GBOs in order 64 * to avoid tweaking and possibly breaking existing code. Moreover it will be probably possible to 65 * map the guest pages into the host R3 memory and access them directly. 66 */ 67 68 /* GBO descriptor. */ 69 typedef struct VMSVGAGBODESCRIPTOR 70 { 71 RTGCPHYS GCPhys; 72 uint64_t cPages; 73 } VMSVGAGBODESCRIPTOR, *PVMSVGAGBODESCRIPTOR; 74 typedef VMSVGAGBODESCRIPTOR const *PCVMSVGAGBODESCRIPTOR; 75 76 /* GBO. 77 */ 78 typedef struct VMSVGAGBO 79 { 80 uint32_t u32Reserved; 81 uint32_t cTotalPages; 82 uint32_t cbTotal; 83 uint32_t cDescriptors; 84 PVMSVGAGBODESCRIPTOR paDescriptors; 85 } VMSVGAGBO, *PVMSVGAGBO; 86 typedef VMSVGAGBO const *PCVMSVGAGBO; 87 88 #define VMSVGA_IS_GBO_CREATED(a_Gbo) ((a_Gbo)->paDescriptors != NULL) 89 90 /* MOB is also a GBO. 91 */ 92 typedef struct VMSVGAMOB 93 { 94 AVLU32NODECORE Core; /* Key is the mobid. */ 95 RTLISTNODE nodeLRU; 96 VMSVGAGBO Gbo; 97 } VMSVGAMOB, *PVMSVGAMOB; 98 typedef VMSVGAMOB const *PCVMSVGAMOB; 99 54 100 55 101 typedef struct VMSVGACMDBUF *PVMSVGACMDBUF; … … 84 130 typedef struct VMSVGAR3STATE 85 131 { 132 PPDMDEVINS pDevIns; /* Stored here to use with PDMDevHlp* */ 86 133 GMR *paGMR; // [VMSVGAState::cGMR] 87 134 struct … … 127 174 /** Critical section for accessing the command buffer data. */ 128 175 RTCRITSECT CritSectCmdBuf; 176 177 /** */ 178 VMSVGAGBO GboOTableMob; 179 VMSVGAGBO GboOTableSurface; 180 VMSVGAGBO GboOTableContext; 181 VMSVGAGBO GboOTableShader; 182 VMSVGAGBO GboOTableScreenTarget; 183 184 /** Tree of guest's Memory OBjects. Key is mobid. */ 185 AVLU32TREE MOBTree; 186 /** Least Recently Used list of MOBs. 187 * To unmap older MOBs when the guest exceeds SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB (SVGA_REG_GBOBJECT_MEM_SIZE_KB) value. */ 188 RTLISTANCHOR MOBLRUList; 129 189 130 190 /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */ -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
r86479 r86838 248 248 SSMFIELD_ENTRY( VMSVGASCREENOBJECT, fDefined), 249 249 SSMFIELD_ENTRY( VMSVGASCREENOBJECT, fModified), 250 SSMFIELD_ENTRY_VER( VMSVGASCREENOBJECT, cDpi, VGA_SAVEDSTATE_VERSION_VMSVGA_MIPLEVELS), 250 251 SSMFIELD_ENTRY_TERM() 251 252 }; … … 626 627 } 627 628 628 rc = pThisCC->pDrv->pfnVBVAResize(pThisCC->pDrv, &view, &screen, pThisCC->pbVRam, /*fResetInputMapping=*/ true); 629 void *pvVRAM = pScreen->pvScreenBitmap ? pScreen->pvScreenBitmap : pThisCC->pbVRam; 630 rc = pThisCC->pDrv->pfnVBVAResize(pThisCC->pDrv, &view, &screen, pvVRAM, /*fResetInputMapping=*/ true); 629 631 AssertRC(rc); 630 632 } … … 2473 2475 2474 2476 /** 2475 * HC access handler for the FIFO.2477 * HC access handler for GMRs. 2476 2478 * 2477 2479 * @returns VINF_SUCCESS if the handler have carried out the operation. … … 2631 2633 * @param pDevIns The device instance. 2632 2634 * @param pThis The shared VGA/VMSVGA state. 2633 * @param fIRQSVGA_IRQFLAG_* bits.2635 * @param u32IrqStatus SVGA_IRQFLAG_* bits. 2634 2636 * @thread FIFO or EMT. 2635 2637 */ 2636 static void vmsvgaR3CmdBufRaiseIRQ(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t fIRQ)2638 static void vmsvgaR3CmdBufRaiseIRQ(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t u32IrqStatus) 2637 2639 { 2638 2640 int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VERR_IGNORED); 2639 2641 AssertRC(rc); 2640 2642 2641 if (pThis->svga.u32IrqMask & fIRQ)2642 { 2643 LogFunc(("Trigger interrupt with status %#x\n", fIRQ));2644 ASMAtomicOrU32(&pThis->svga.u32IrqStatus, fIRQ);2643 if (pThis->svga.u32IrqMask & u32IrqStatus) 2644 { 2645 LogFunc(("Trigger interrupt with status %#x\n", u32IrqStatus)); 2646 ASMAtomicOrU32(&pThis->svga.u32IrqStatus, u32IrqStatus); 2645 2647 PDMDevHlpPCISetIrq(pDevIns, 0, 1); 2646 2648 } … … 3086 3088 * @param cbCommands Size of the command buffer. 3087 3089 * @param poffNextCmd Where to store the offset of the first unprocessed command. 3090 * @param pu32IrqStatus Where to store SVGA_IRQFLAG_ if the IRQ is generated by the last command in the buffer. 3088 3091 * @return SVGACBStatus code. 3089 3092 * @thread FIFO 3090 3093 */ 3091 static SVGACBStatus vmsvgaR3CmdBufProcessCommands(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, void const *pvCommands, uint32_t cbCommands, uint32_t *poffNextCmd )3094 static SVGACBStatus vmsvgaR3CmdBufProcessCommands(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, void const *pvCommands, uint32_t cbCommands, uint32_t *poffNextCmd, uint32_t *pu32IrqStatus) 3092 3095 { 3093 3096 SVGACBStatus CBstatus = SVGA_CB_STATUS_COMPLETED; … … 3144 3147 pFIFO[SVGA_FIFO_FENCE] = pCmd->fence; 3145 3148 3146 uint32_t u32IrqStatus = 0;3147 3149 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE) 3148 3150 { 3149 3151 Log(("any fence irq\n")); 3150 u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;3152 *pu32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE; 3151 3153 } 3152 3154 else if ( VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin) … … 3155 3157 { 3156 3158 Log(("fence goal reached irq (fence=%#x)\n", pCmd->fence)); 3157 u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;3159 *pu32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL; 3158 3160 } 3159 3160 if (u32IrqStatus)3161 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, u32IrqStatus);3162 3161 } 3163 3162 else … … 3321 3320 break; 3322 3321 } 3323 # endif / / VBOX_WITH_VMSVGA3D3322 # endif /* VBOX_WITH_VMSVGA3D */ 3324 3323 case SVGA_CMD_DEFINE_SCREEN: 3325 3324 { … … 3432 3431 pu8Cmd += cbCmd; 3433 3432 cbRemain -= cbCmd; 3433 3434 /* If this is not the last command in the buffer, then generate IRQ, if required. 3435 * This avoids a double call to vmsvgaR3CmdBufRaiseIRQ if FENCE is the last command 3436 * in the buffer (usually the case). 3437 */ 3438 if (RT_LIKELY(!(cbRemain && *pu32IrqStatus))) 3439 { /* likely */ } 3440 else 3441 { 3442 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, *pu32IrqStatus); 3443 *pu32IrqStatus = 0; 3444 } 3434 3445 } 3435 3446 … … 3492 3503 SVGACBStatus CBstatus = SVGA_CB_STATUS_NONE; 3493 3504 uint32_t offNextCmd = 0; 3505 uint32_t u32IrqStatus = 0; 3494 3506 3495 3507 /* Process one buffer. */ 3496 CBstatus = vmsvgaR3CmdBufProcessCommands(pDevIns, pThis, pThisCC, pCmdBuf->pvCommands, pCmdBuf->hdr.length, &offNextCmd); 3497 3498 uint32_t fIRQ = 0; 3508 CBstatus = vmsvgaR3CmdBufProcessCommands(pDevIns, pThis, pThisCC, pCmdBuf->pvCommands, pCmdBuf->hdr.length, &offNextCmd, &u32IrqStatus); 3509 3499 3510 if (!RT_BOOL(pCmdBuf->hdr.flags & SVGA_CB_FLAG_NO_IRQ)) 3500 fIRQ|= SVGA_IRQFLAG_COMMAND_BUFFER;3511 u32IrqStatus |= SVGA_IRQFLAG_COMMAND_BUFFER; 3501 3512 if (CBstatus == SVGA_CB_STATUS_COMMAND_ERROR) 3502 fIRQ|= SVGA_IRQFLAG_ERROR;3513 u32IrqStatus |= SVGA_IRQFLAG_ERROR; 3503 3514 3504 3515 vmsvgaR3CmdBufWriteStatus(pDevIns, pCmdBuf->GCPhysCB, CBstatus, offNextCmd); 3505 if ( fIRQ)3506 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, fIRQ);3516 if (u32IrqStatus) 3517 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, u32IrqStatus); 3507 3518 3508 3519 vmsvgaR3CmdBufFree(pCmdBuf); … … 5380 5391 * 5381 5392 * @returns VBox status code. 5393 * @param pDevIns The PDM device instance. 5382 5394 * @param pThis The shared VGA/VMSVGA instance data. 5383 5395 * @param pSVGAState Pointer to the structure. It is already allocated. 5384 5396 */ 5385 static int vmsvgaR3StateInit(P VGASTATE pThis, PVMSVGAR3STATE pSVGAState)5397 static int vmsvgaR3StateInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVMSVGAR3STATE pSVGAState) 5386 5398 { 5387 5399 int rc = VINF_SUCCESS; 5388 5400 RT_ZERO(*pSVGAState); 5401 pSVGAState->pDevIns = pDevIns; 5389 5402 5390 5403 pSVGAState->paGMR = (PGMR)RTMemAllocZ(pThis->svga.cGMR * sizeof(GMR)); … … 5401 5414 5402 5415 vmsvgaR3CmdBufCtxInit(&pSVGAState->CmdBufCtxDC); 5416 5417 RTListInit(&pSVGAState->MOBLRUList); 5403 5418 return rc; 5404 5419 } … … 5808 5823 5809 5824 vmsvgaR3StateTerm(pThis, pThisCC->svga.pSvgaR3State); 5810 vmsvgaR3StateInit(p This, pThisCC->svga.pSvgaR3State);5825 vmsvgaR3StateInit(pDevIns, pThis, pThisCC->svga.pSvgaR3State); 5811 5826 5812 5827 RT_BZERO(pThisCC->svga.pbVgaFrameBufferR3, VMSVGA_VGA_FB_BACKUP_SIZE); … … 5925 5940 AssertReturn(pThisCC->svga.pSvgaR3State, VERR_NO_MEMORY); 5926 5941 5927 rc = vmsvgaR3StateInit(p This, pThisCC->svga.pSvgaR3State);5942 rc = vmsvgaR3StateInit(pDevIns, pThis, pThisCC->svga.pSvgaR3State); 5928 5943 AssertMsgRCReturn(rc, ("Failed to create pSvgaR3State.\n"), rc); 5929 5944 -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
r86266 r86838 254 254 /** Bits per pixel. */ 255 255 uint32_t cBpp; 256 /** The physical DPI that the guest expects for this screen. Zero, if the guest is not DPI aware. */ 257 uint32_t cDpi; 256 258 bool fDefined; 257 259 bool fModified; 260 void *pvScreenBitmap; 258 261 #ifdef VBOX_WITH_VMSVGA3D 259 262 /** Pointer to the HW accelerated (3D) screen data. */ … … 361 364 uint32_t uPadding1; 362 365 #endif 363 /** Number of GMRs . */366 /** Number of GMRs (VMSVGA_MAX_GMR_IDS, count of elements in VMSVGAR3STATE::paGMR array). */ 364 367 uint32_t cGMR; 365 368 uint32_t uScreenOffset; /* Used only for loading older saved states. */ … … 566 569 void vmsvgaR3ClipBox(const SVGA3dSize *pSize, SVGA3dBox *pBox); 567 570 void vmsvgaR3ClipRect(SVGASignedRect const *pBound, SVGASignedRect *pRect); 571 void vmsvgaR3Clip3dRect(SVGA3dRect const *pBound, SVGA3dRect RT_UNTRUSTED_GUEST *pRect); 568 572 569 573 #endif /* !VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA_h */ -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp
r86024 r86838 291 291 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++) 292 292 { 293 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels); 294 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iFace * pSurface->faces[0].numMipLevels]; 295 for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++) 293 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iFace * pSurface->cLevels]; 294 for (uint32_t i = 0; i < pSurface->cLevels; i++, pMipmapLevel++) 296 295 { 297 296 if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface)) … … 498 497 AssertMsgFailed(("%#x\n", fSwitchFlags)); 499 498 } 499 #elif defined(VMSVGA3D_DX) 500 /** @todo */ 501 RT_NOREF(pState); 500 502 #else 501 503 # error "misconfigured" … … 1522 1524 # ifdef VMSVGA3D_DIRECT3D 1523 1525 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice); 1526 # elif defined(VMSVGA3D_DX) 1527 /** @todo */ 1524 1528 # else 1525 1529 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc); … … 1919 1923 const uint32_t u32Seq = ASMAtomicIncU32(&sSeq); 1920 1924 1921 for (uint32_t i = 0; i < pSurface-> faces[0].numMipLevels; ++i)1925 for (uint32_t i = 0; i < pSurface->cLevels; ++i) 1922 1926 { 1923 1927 if (!pSurface->paMipmapLevels[i].pSurfaceData) … … 1978 1982 vmsvga3dInfoU32Flags(pHlp, pSurface->surfaceFlags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags)); 1979 1983 pHlp->pfnPrintf(pHlp, "\n"); 1980 if (pSurface->cFaces == 0)1984 if (pSurface->cFaces != 0) 1981 1985 pHlp->pfnPrintf(pHlp, "Faces: %u\n", pSurface->cFaces); 1986 if (pSurface->cLevels != 0) 1987 pHlp->pfnPrintf(pHlp, "Mipmap levels: %u\n", pSurface->cLevels); 1982 1988 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++) 1983 1989 { 1984 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels); 1985 if (pSurface->faces[iFace].numMipLevels == 0) 1986 pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels: %u\n", iFace, pSurface->faces[iFace].numMipLevels); 1987 1988 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels; 1989 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++) 1990 uint32_t iMipmap = iFace * pSurface->cLevels; 1991 for (uint32_t iLevel = 0; iLevel < pSurface->cLevels; iLevel++, iMipmap++) 1990 1992 { 1991 1993 pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x", … … 2030 2032 pHlp->pfnPrintf(pHlp, "fStencilAsTexture: %RTbool\n", pSurface->fStencilAsTexture); 2031 2033 2034 #elif defined(VMSVGA3D_DX) 2035 /** @todo */ 2032 2036 #elif defined(VMSVGA3D_OPENGL) 2033 2037 /** @todo */ … … 2039 2043 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++) 2040 2044 { 2041 uint32_t iMipmap = iFace * pSurface-> faces[0].numMipLevels;2042 for (uint32_t iLevel = 0; iLevel < pSurface-> faces[iFace].numMipLevels; iLevel++, iMipmap++)2045 uint32_t iMipmap = iFace * pSurface->cLevels; 2046 for (uint32_t iLevel = 0; iLevel < pSurface->cLevels; iLevel++, iMipmap++) 2043 2047 if (pSurface->paMipmapLevels[iMipmap].pSurfaceData) 2044 2048 { -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h
r86809 r86838 29 29 #endif 30 30 #ifdef VMSVGA3D_OPENGL 31 # if def VMSVGA3D_DIRECT3D31 # if defined(VMSVGA3D_DIRECT3D) || defined(VMSVGA3D_DX) 32 32 # error "Both VMSVGA3D_DIRECT3D and VMSVGA3D_OPENGL cannot be defined at the same time." 33 33 # endif 34 #elif !defined(VMSVGA3D_DIRECT3D) 34 #elif !defined(VMSVGA3D_DIRECT3D) && !defined(VMSVGA3D_DX) 35 35 # error "Either VMSVGA3D_OPENGL or VMSVGA3D_DIRECT3D must be defined." 36 36 #endif … … 51 51 # include <d3d9.h> 52 52 # include <iprt/avl.h> 53 # elif defined(VMSVGA3D_DX) 54 # include <d3d11.h> 53 55 # else 54 56 # include <GL/gl.h> … … 536 538 #endif 537 539 540 /* The 3D backend surface. The actual structure is 3D API specific. */ 541 typedef struct VMSVGA3DBACKENDSURFACE *PVMSVGA3DBACKENDSURFACE; 542 538 543 /** 539 544 * VMSVGA3d surface. … … 541 546 typedef struct VMSVGA3DSURFACE 542 547 { 548 PVMSVGA3DBACKENDSURFACE pBackendSurface; 549 543 550 uint32_t id; 544 551 #ifdef VMSVGA3D_OPENGL … … 566 573 GLuint idEmulated; /* GL name of the intermediate texture. */ 567 574 #endif 568 SVGA3dSurfaceFace faces[SVGA3D_MAX_SURFACE_FACES]; 569 uint32_t cFaces; 570 uint32_t cMipmapLevels; 571 PVMSVGA3DMIPMAPLEVEL paMipmapLevels; 575 uint32_t cFaces; /* Number of faces: 6 for cubemaps, 1 for everything else. */ 576 uint32_t cLevels; /* Number of mipmap levels per face. */ 577 PVMSVGA3DMIPMAPLEVEL paMipmapLevels; /* cFaces * cLevels elements. */ 572 578 uint32_t multiSampleCount; 573 579 SVGA3dTextureFilter autogenFilter; … … 646 652 SSMFIELD_ENTRY( VMSVGA3DSURFACE, formatGL), 647 653 SSMFIELD_ENTRY( VMSVGA3DSURFACE, typeGL), 648 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, id),649 654 # endif 650 SSMFIELD_ENTRY( VMSVGA3DSURFACE, faces),651 655 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cFaces), 652 SSMFIELD_ENTRY _IGN_HCPTR( VMSVGA3DSURFACE, paMipmapLevels),656 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cLevels), 653 657 SSMFIELD_ENTRY( VMSVGA3DSURFACE, multiSampleCount), 654 658 SSMFIELD_ENTRY( VMSVGA3DSURFACE, autogenFilter), 655 # ifdef VMSVGA3D_DIRECT3D656 SSMFIELD_ENTRY( VMSVGA3DSURFACE, format), /** @todo format duplicated. */657 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, formatD3D),658 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fUsageD3D),659 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, multiSampleTypeD3D),660 # endif661 659 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cbBlock), 662 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fDirty),663 # ifdef VMSVGA3D_DIRECT3D664 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, hSharedObject),665 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, pQuery),666 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, u.pSurface),667 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, bounce.pTexture),668 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, pSharedObjectTree),669 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fStencilAsTexture),670 # endif671 660 SSMFIELD_ENTRY_TERM() 672 661 }; … … 687 676 #ifdef VMSVGA3D_DIRECT3D 688 677 # define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->u.pSurface != NULL) 678 #elif defined(VMSVGA3D_DX) 679 # define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->pBackendSurface != NULL) 689 680 #else 690 681 # define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->oglId.texture != OPENGL_INVALID_ID) … … 701 692 ( (a_pSurface)->enmD3DResType == VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER \ 702 693 || (a_pSurface)->enmD3DResType == VMSVGA3D_D3DRESTYPE_INDEX_BUFFER) 694 #elif defined(VMSVGA3D_DX) 695 /** @todo */ 696 # define VMSVGA3DSURFACE_NEEDS_DATA(a_pSurface) (false) 703 697 #else 704 698 # define VMSVGA3DSURFACE_NEEDS_DATA(a_pSurface) \ … … 719 713 IDirect3DVertexShader9 *pVertexShader; 720 714 IDirect3DPixelShader9 *pPixelShader; 715 #elif defined(VMSVGA3D_DX) 716 /** todo */ 721 717 #else 722 718 void *pVertexShader; … … 770 766 #ifdef VMSVGA3D_DIRECT3D 771 767 IDirect3DQuery9 *pQuery; 768 #elif defined(VMSVGA3D_DX) 769 /** @todo */ 772 770 #else /* VMSVGA3D_OPENGL */ 773 771 GLuint idQuery; … … 785 783 #ifdef VMSVGA3D_DIRECT3D 786 784 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DQUERY, pQuery), 785 #elif defined(VMSVGA3D_DX) 786 /** @todo */ 787 787 #else /* VMSVGA3D_OPENGL */ 788 788 SSMFIELD_ENTRY_IGNORE( VMSVGA3DQUERY, idQuery), … … 796 796 #ifdef VMSVGA3D_DIRECT3D 797 797 #define VMSVGA3DQUERY_EXISTS(p) ((p)->pQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL) 798 #elif defined(VMSVGA3D_DX) 799 /** @todo */ 800 #define VMSVGA3DQUERY_EXISTS(p) (false) 798 801 #else 799 802 #define VMSVGA3DQUERY_EXISTS(p) ((p)->idQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL) … … 813 816 IDirect3DDevice9Ex *pDevice; 814 817 # endif 818 # elif defined(VMSVGA3D_DX) 819 /** @todo */ 815 820 # else 816 821 /* Device context of the context window. */ … … 911 916 # ifdef VMSVGA3D_DIRECT3D 912 917 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pDevice), 918 # elif defined(VMSVGA3D_DX) 919 /** @todo */ 913 920 # else 914 921 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc), … … 967 974 #endif 968 975 976 /* The 3D backend. The actual structure is 3D API specific. */ 977 typedef struct VMSVGA3DBACKEND *PVMSVGA3DBACKEND; 978 969 979 /** 970 980 * VMSVGA3d state data. … … 996 1006 bool fSupportedFormatYUY2 : 1; 997 1007 bool fSupportedFormatA8B8G8R8 : 1; 1008 # elif defined(VMSVGA3D_DX) 1009 PVMSVGA3DBACKEND pBackend; 998 1010 # endif 999 1011 /** Window Thread. */ … … 1297 1309 PVMSVGA3DMIPMAPLEVEL *ppMipmapLevel) 1298 1310 { 1299 /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */1300 const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;1301 1302 1311 AssertMsgReturn(face < pSurface->cFaces, 1303 1312 ("cFaces %d, face %d\n", pSurface->cFaces, face), 1304 1313 VERR_INVALID_PARAMETER); 1305 AssertMsgReturn(mipmap < numMipLevels,1306 ("numMipLevels %d, mipmap %d", numMipLevels, mipmap),1314 AssertMsgReturn(mipmap < pSurface->cLevels, 1315 ("numMipLevels %d, mipmap %d", pSurface->cLevels, mipmap), 1307 1316 VERR_INVALID_PARAMETER); 1308 1317 1309 *ppMipmapLevel = &pSurface->paMipmapLevels[face * numMipLevels + mipmap];1318 *ppMipmapLevel = &pSurface->paMipmapLevels[face * pSurface->cLevels + mipmap]; 1310 1319 return VINF_SUCCESS; 1311 1320 } … … 1327 1336 return Face; 1328 1337 } 1338 #elif defined(VMSVGA3D_DX) 1339 DECLINLINE(D3D11_TEXTURECUBE_FACE) vmsvga3dCubemapFaceFromIndex(uint32_t iFace) 1340 { 1341 D3D11_TEXTURECUBE_FACE Face; 1342 switch (iFace) 1343 { 1344 case 0: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_X; break; 1345 case 1: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_X; break; 1346 case 2: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Y; break; 1347 case 3: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Y; break; 1348 case 4: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Z; break; 1349 default: 1350 case 5: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Z; break; 1351 } 1352 return Face; 1353 } 1329 1354 #else /* VMSVGA3D_OPENGL */ 1330 1355 DECLINLINE(GLenum) vmsvga3dCubemapFaceFromIndex(uint32_t iFace) … … 1354 1379 const char *pszPath, const char *pszNamePrefix, const char *pszNameSuffix); 1355 1380 1356 #if def VMSVGA3D_DIRECT3D1381 #if defined(VMSVGA3D_DIRECT3D) || defined(VMSVGA3D_DX) 1357 1382 #define D3D_RELEASE(ptr) do { \ 1358 1383 if (ptr) \ … … 1362 1387 } \ 1363 1388 } while (0) 1364 1389 #endif 1390 1391 #if defined(VMSVGA3D_DIRECT3D) 1365 1392 HRESULT D3D9UpdateTexture(PVMSVGA3DCONTEXT pContext, 1366 1393 PVMSVGA3DSURFACE pSurface); -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
r86809 r86838 2366 2366 LogFunc(("sid=%u\n", pSurface->id)); 2367 2367 2368 uint32_t const numMipLevels = pSurface-> faces[0].numMipLevels;2368 uint32_t const numMipLevels = pSurface->cLevels; 2369 2369 2370 2370 /* Fugure out what kind of texture we are creating. */ … … 2425 2425 glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); 2426 2426 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 2427 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, pSurface-> faces[0].numMipLevels - 1);2427 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, pSurface->cLevels - 1); 2428 2428 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 2429 2429 … … 5722 5722 { 5723 5723 Log(("CreateTexture (%d,%d) levels=%d\n", 5724 pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface-> faces[0].numMipLevels));5724 pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface->cLevels)); 5725 5725 rc = vmsvga3dBackCreateTexture(pState, pContext, cid, pSurface); 5726 5726 AssertRCReturn(rc, rc); -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp
r82968 r86838 147 147 } 148 148 149 static int vmsvga3dLoadVMSVGA3DSURFACEPreMipLevels(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, VMSVGA3DSURFACE *pSurface) 150 { 151 typedef struct VMSVGA3DSURFACEPreMipLevels 152 { 153 uint32_t id; 154 #ifdef VMSVGA3D_OPENGL 155 uint32_t idWeakContextAssociation; 156 #else 157 uint32_t idAssociatedContext; 158 #endif 159 uint32_t surfaceFlags; 160 SVGA3dSurfaceFormat format; 161 #ifdef VMSVGA3D_OPENGL 162 GLint internalFormatGL; 163 GLint formatGL; 164 GLint typeGL; 165 #endif 166 SVGA3dSurfaceFace faces[SVGA3D_MAX_SURFACE_FACES]; 167 uint32_t cFaces; 168 uint32_t multiSampleCount; 169 SVGA3dTextureFilter autogenFilter; 170 uint32_t cbBlock; 171 } VMSVGA3DSURFACEPreMipLevels; 172 173 static SSMFIELD const s_aVMSVGA3DSURFACEFieldsPreMipLevels[] = 174 { 175 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, id), 176 #ifdef VMSVGA3D_OPENGL 177 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, idWeakContextAssociation), 178 #else 179 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, idAssociatedContext), 180 #endif 181 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, surfaceFlags), 182 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, format), 183 #ifdef VMSVGA3D_OPENGL 184 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, internalFormatGL), 185 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, formatGL), 186 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, typeGL), 187 #endif 188 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, faces), 189 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, cFaces), 190 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, multiSampleCount), 191 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, autogenFilter), 192 #ifdef VMSVGA3D_DIRECT3D 193 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, format), /* Yes, the 'format' field is duplicated. */ 194 #endif 195 SSMFIELD_ENTRY(VMSVGA3DSURFACEPreMipLevels, cbBlock), 196 SSMFIELD_ENTRY_TERM() 197 }; 198 199 VMSVGA3DSURFACEPreMipLevels surfacePreMipLevels; 200 int rc = pDevIns->pHlpR3->pfnSSMGetStructEx(pSSM, &surfacePreMipLevels, sizeof(surfacePreMipLevels), 0, s_aVMSVGA3DSURFACEFieldsPreMipLevels, NULL); 201 if (RT_SUCCESS(rc)) 202 { 203 pSurface->id = surfacePreMipLevels.id; 204 #ifdef VMSVGA3D_OPENGL 205 pSurface->idWeakContextAssociation = surfacePreMipLevels.idWeakContextAssociation; 206 #else 207 pSurface->idAssociatedContext = surfacePreMipLevels.idAssociatedContext; 208 #endif 209 pSurface->surfaceFlags = surfacePreMipLevels.surfaceFlags; 210 pSurface->format = surfacePreMipLevels.format; 211 #ifdef VMSVGA3D_OPENGL 212 pSurface->internalFormatGL = surfacePreMipLevels.internalFormatGL; 213 pSurface->formatGL = surfacePreMipLevels.formatGL; 214 pSurface->typeGL = surfacePreMipLevels.typeGL; 215 #endif 216 pSurface->cLevels = surfacePreMipLevels.faces[0].numMipLevels; 217 pSurface->cFaces = surfacePreMipLevels.cFaces; 218 pSurface->multiSampleCount = surfacePreMipLevels.multiSampleCount; 219 pSurface->autogenFilter = surfacePreMipLevels.autogenFilter; 220 pSurface->cbBlock = surfacePreMipLevels.cbBlock; 221 } 222 return rc; 223 } 224 149 225 int vmsvga3dLoadExec(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 150 226 { … … 408 484 409 485 /* Fetch the surface structure first. */ 410 rc = pHlp->pfnSSMGetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL); 486 if (RT_LIKELY(uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_MIPLEVELS)) 487 rc = pHlp->pfnSSMGetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL); 488 else 489 rc = vmsvga3dLoadVMSVGA3DSURFACEPreMipLevels(pDevIns, pSSM, &surface); 411 490 AssertRCReturn(rc, rc); 412 491 413 492 { 414 uint32_t cMipLevels = surface. faces[0].numMipLevels * surface.cFaces;493 uint32_t cMipLevels = surface.cLevels * surface.cFaces; 415 494 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL)); 416 495 AssertReturn(pMipmapLevel, VERR_NO_MEMORY); … … 421 500 for (uint32_t face=0; face < surface.cFaces; face++) 422 501 { 423 for (uint32_t j = 0; j < surface. faces[0].numMipLevels; j++)502 for (uint32_t j = 0; j < surface.cLevels; j++) 424 503 { 425 uint32_t idx = j + face * surface. faces[0].numMipLevels;504 uint32_t idx = j + face * surface.cLevels; 426 505 /* Load the mip map level struct. */ 427 506 rc = pHlp->pfnSSMGetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, … … 433 512 } 434 513 435 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surface.surfaceFlags, surface.format, surface. faces,436 surface. multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);514 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surface.surfaceFlags, surface.format, surface.multiSampleCount, 515 surface.autogenFilter, surface.cLevels, &pMipmapLevelSize[0]); 437 516 AssertRCReturn(rc, rc); 438 517 … … 447 526 448 527 /* Load the mip map level data. */ 449 for (uint32_t j = 0; j < pSurface-> faces[0].numMipLevels * pSurface->cFaces; j++)528 for (uint32_t j = 0; j < pSurface->cLevels * pSurface->cFaces; j++) 450 529 { 451 530 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[j]; … … 684 763 for (uint32_t face=0; face < pSurface->cFaces; face++) 685 764 { 686 for (uint32_t i = 0; i < pSurface-> faces[0].numMipLevels; i++)765 for (uint32_t i = 0; i < pSurface->cLevels; i++) 687 766 { 688 uint32_t idx = i + face * pSurface-> faces[0].numMipLevels;767 uint32_t idx = i + face * pSurface->cLevels; 689 768 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[idx]; 690 769 … … 698 777 for (uint32_t face=0; face < pSurface->cFaces; face++) 699 778 { 700 for (uint32_t i = 0; i < pSurface-> faces[0].numMipLevels; i++)779 for (uint32_t i = 0; i < pSurface->cLevels; i++) 701 780 { 702 uint32_t idx = i + face * pSurface-> faces[0].numMipLevels;781 uint32_t idx = i + face * pSurface->cLevels; 703 782 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[idx]; 704 783 … … 877 956 878 957 RTMemFree(pData); 958 #elif defined(VMSVGA3D_DX) 959 /** @todo */ 879 960 #elif defined(VMSVGA3D_OPENGL) 880 961 void *pData = NULL; -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
r86576 r86838 1196 1196 const uint32_t cHeight = pSurface->paMipmapLevels[0].mipmapSize.height; 1197 1197 const uint32_t cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth; 1198 const uint32_t numMipLevels = pSurface-> faces[0].numMipLevels;1198 const uint32_t numMipLevels = pSurface->cLevels; 1199 1199 1200 1200 LogFunc(("Create shared %stexture copy d3d (%d,%d,%d) cMip=%d usage %x format %x.\n", … … 1853 1853 const uint32_t cHeight = pSurface->paMipmapLevels[0].mipmapSize.height; 1854 1854 const uint32_t cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth; 1855 const uint32_t numMipLevels = pSurface-> faces[0].numMipLevels;1855 const uint32_t numMipLevels = pSurface->cLevels; 1856 1856 1857 1857 /* … … 1908 1908 { 1909 1909 Assert(pSurface->cFaces == 1); 1910 Assert(pSurface-> faces[0].numMipLevels == 1);1910 Assert(pSurface->cLevels == 1); 1911 1911 Assert(cDepth == 1); 1912 1912 … … 2223 2223 2224 2224 /* We will now use the bounce texture for all memory accesses, so free our surface memory buffer. */ 2225 for (uint32_t i = 0; i < pSurface-> faces[0].numMipLevels; i++)2225 for (uint32_t i = 0; i < pSurface->cLevels; i++) 2226 2226 { 2227 2227 RTMemFree(pSurface->paMipmapLevels[i].pSurfaceData); … … 2709 2709 SVGA3dTextureFilter const autogenFilter = pSurface->autogenFilter; 2710 2710 uint32_t const cFaces = pSurface->cFaces; 2711 uint32_t const cMipLevels = pSurface-> faces[0].numMipLevels;2711 uint32_t const cMipLevels = pSurface->cLevels; 2712 2712 2713 2713 SVGA3dSize *pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(cMipLevels * cFaces * sizeof(SVGA3dSize)); … … 2723 2723 } 2724 2724 2725 SVGA3dSurfaceFace aFaces[SVGA3D_MAX_SURFACE_FACES];2726 AssertCompile(sizeof(aFaces) == sizeof(pSurface->faces));2727 memcpy(aFaces, pSurface->faces, sizeof(pSurface->faces));2728 2729 2725 /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */ 2730 2726 #ifdef DEBUG_sunlover … … 2736 2732 AssertRC(rc); 2737 2733 2738 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surfaceFlags, format, aFaces,multisampleCount, autogenFilter,2739 cMipLevels * cFaces, pMipLevelSize);2734 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surfaceFlags, format, multisampleCount, autogenFilter, 2735 cMipLevels, &pMipLevelSize[0]); 2740 2736 AssertRC(rc); 2741 2737 … … 4059 4055 { 4060 4056 Log(("vmsvga3dSetRenderTarget: sync dirty depth/stencil buffer\n")); 4061 Assert(pRenderTarget-> faces[0].numMipLevels == 1);4062 4063 for (uint32_t i = 0; i < pRenderTarget-> faces[0].numMipLevels; i++)4057 Assert(pRenderTarget->cLevels == 1); 4058 4059 for (uint32_t i = 0; i < pRenderTarget->cLevels; i++) 4064 4060 { 4065 4061 if (pRenderTarget->paMipmapLevels[i].fDirty) … … 4401 4397 { 4402 4398 Assert(pSurface->idAssociatedContext == SVGA3D_INVALID_ID); 4403 LogFunc(("CreateTexture (%d,%d) level=%d fUsage=%x format=%x\n", pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface-> faces[0].numMipLevels, pSurface->fUsageD3D, pSurface->formatD3D));4399 LogFunc(("CreateTexture (%d,%d) level=%d fUsage=%x format=%x\n", pSurface->paMipmapLevels[0].mipmapSize.width, pSurface->paMipmapLevels[0].mipmapSize.height, pSurface->cLevels, pSurface->fUsageD3D, pSurface->formatD3D)); 4404 4400 rc = vmsvga3dBackCreateTexture(pState, pContext, cid, pSurface); 4405 4401 AssertRCReturn(rc, rc); -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
r86024 r86838 50 50 * @param surfaceFlags . 51 51 * @param format . 52 * @param face .53 52 * @param multisampleCount . 54 53 * @param autogenFilter . 55 * @param cMipLevels.56 * @param p aMipLevelSizes.54 * @param numMipLevels . 55 * @param pMipLevel0Size . 57 56 */ 58 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, uint32_tsurfaceFlags, SVGA3dSurfaceFormat format,59 SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,60 SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *paMipLevelSizes)57 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, SVGA3dSurfaceFlags surfaceFlags, SVGA3dSurfaceFormat format, 58 uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter, 59 uint32_t numMipLevels, SVGA3dSize const *pMipLevel0Size) 61 60 { 62 61 PVMSVGA3DSURFACE pSurface; 63 62 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState; 64 AssertReturn(pState, VERR_ NO_MEMORY);65 66 Log (("vmsvga3dSurfaceDefine: sid=%u surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n",67 sid, surfaceFlags, vmsvgaLookupEnum((int)format, &g_SVGA3dSurfaceFormat2String), format, multisampleCount, autogenFilter,68 cMipLevels, paMipLevelSizes->width, paMipLevelSizes->height, paMipLevelSizes->depth));63 AssertReturn(pState, VERR_INVALID_STATE); 64 65 LogFunc(("sid=%u surfaceFlags=%#x format=%s (%#x) multiSampleCount=%d autogenFilter=%d, numMipLevels=%d size=(%dx%dx%d)\n", 66 sid, surfaceFlags, vmsvgaLookupEnum((int)format, &g_SVGA3dSurfaceFormat2String), format, multisampleCount, autogenFilter, 67 numMipLevels, pMipLevel0Size->width, pMipLevel0Size->height, pMipLevel0Size->depth)); 69 68 70 69 AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER); 71 AssertReturn(cMipLevels >= 1, VERR_INVALID_PARAMETER); 72 73 /* Number of faces (cFaces) is specified as the number of the first non-zero elements in the 'face' array. 74 * Since only plain surfaces (cFaces == 1) and cubemaps (cFaces == 6) are supported 75 * (see also SVGA3dCmdDefineSurface definition in svga3d_reg.h), we ignore anything else. 76 */ 77 uint32_t cRemainingMipLevels = cMipLevels; 78 uint32_t cFaces = 0; 79 for (uint32_t i = 0; i < SVGA3D_MAX_SURFACE_FACES; ++i) 80 { 81 if (face[i].numMipLevels == 0) 82 break; 83 84 /* All SVGA3dSurfaceFace structures must have the same value of numMipLevels field */ 85 AssertReturn(face[i].numMipLevels == face[0].numMipLevels, VERR_INVALID_PARAMETER); 86 87 /* numMipLevels value can't be greater than the number of remaining elements in the paMipLevelSizes array. */ 88 AssertReturn(face[i].numMipLevels <= cRemainingMipLevels, VERR_INVALID_PARAMETER); 89 cRemainingMipLevels -= face[i].numMipLevels; 90 91 ++cFaces; 92 } 93 for (uint32_t i = cFaces; i < SVGA3D_MAX_SURFACE_FACES; ++i) 94 AssertReturn(face[i].numMipLevels == 0, VERR_INVALID_PARAMETER); 95 96 /* cFaces must be 6 for a cubemap and 1 otherwise. */ 97 AssertReturn(cFaces == (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1), VERR_INVALID_PARAMETER); 98 99 /* Sum of face[i].numMipLevels must be equal to cMipLevels. */ 100 AssertReturn(cRemainingMipLevels == 0, VERR_INVALID_PARAMETER); 70 AssertReturn(numMipLevels >= 1, VERR_INVALID_PARAMETER); 101 71 102 72 if (sid >= pState->cSurfaces) … … 126 96 pSurface->idWeakContextAssociation = SVGA3D_INVALID_ID; 127 97 pSurface->oglId.buffer = OPENGL_INVALID_ID; 98 #elif defined(VMSVGA3D_DX) 99 // pSurface->pBackendSurface = NULL; 128 100 #else /* VMSVGA3D_DIRECT3D */ 129 101 pSurface->idAssociatedContext = SVGA3D_INVALID_ID; … … 132 104 #endif 133 105 106 /** @todo This 'switch' and the sufraceFlags tweaks should not be necessary. 107 * The actual surface type will be figured out when the surface is actually used later. 108 * The backends code must be reviewed for unnecessary dependencies on the surfaceFlags value. 109 */ 134 110 /* The surface type is sort of undefined now, even though the hints and format can help to clear that up. 135 111 * In some case we'll have to wait until the surface is used to create the D3D object. … … 145 121 case SVGA3D_Z_DF24: 146 122 case SVGA3D_Z_D24S8_INT: 123 Assert(surfaceFlags & SVGA3D_SURFACE_HINT_DEPTHSTENCIL); 147 124 surfaceFlags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; 148 125 break; … … 171 148 case SVGA3D_A1R5G5B5: 172 149 case SVGA3D_A4R4G4B4: 150 Assert(surfaceFlags & (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_SCREENTARGET)); 173 151 surfaceFlags |= SVGA3D_SURFACE_HINT_TEXTURE; 174 152 break; … … 210 188 pSurface->surfaceFlags = surfaceFlags; 211 189 pSurface->format = format; 212 memcpy(pSurface->faces, face, sizeof(pSurface->faces)); 213 pSurface->cFaces = cFaces; 190 /* cFaces is 6 for a cubemaps and 1 otherwise. */ 191 pSurface->cFaces = (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1); 192 pSurface->cLevels = numMipLevels; 214 193 pSurface->multiSampleCount = multisampleCount; 215 194 pSurface->autogenFilter = autogenFilter; 216 195 Assert(autogenFilter != SVGA3D_TEX_FILTER_FLATCUBIC); 217 196 Assert(autogenFilter != SVGA3D_TEX_FILTER_GAUSSIANCUBIC); 218 pSurface->cMipmapLevels = cMipLevels; 219 pSurface->paMipmapLevels = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL)); 197 pSurface->paMipmapLevels = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(numMipLevels * pSurface->cFaces * sizeof(VMSVGA3DMIPMAPLEVEL)); 220 198 AssertReturn(pSurface->paMipmapLevels, VERR_NO_MEMORY); 221 222 for (uint32_t i=0; i < cMipLevels; i++)223 pSurface->paMipmapLevels[i].mipmapSize = paMipLevelSizes[i];224 199 225 200 pSurface->cbBlock = vmsvga3dSurfaceFormatSize(format, &pSurface->cxBlock, &pSurface->cyBlock); 226 201 AssertReturn(pSurface->cbBlock, VERR_INVALID_PARAMETER); 202 203 /** @todo cbMemRemaining = value of SVGA_REG_MOB_MAX_SIZE */ 204 uint32_t cbMemRemaining = SVGA3D_MAX_SURFACE_MEM_SIZE; /* Do not allow more than this for a surface. */ 205 SVGA3dSize mipmapSize = *pMipLevel0Size; 206 for (uint32_t i = 0; i < numMipLevels; ++i) 207 { 208 for (uint32_t iFace = 0; iFace < pSurface->cFaces; ++iFace) 209 { 210 uint32_t const iMipmap = iFace * numMipLevels + i; 211 LogFunc(("[%d] face %d mip level %d (%d,%d,%d) cbBlock=%#x block %dx%d\n", 212 iMipmap, iFace, i, mipmapSize.width, mipmapSize.height, mipmapSize.depth, 213 pSurface->cbBlock, pSurface->cxBlock, pSurface->cyBlock)); 214 215 uint32_t cBlocksX; 216 uint32_t cBlocksY; 217 if (RT_LIKELY(pSurface->cxBlock == 1 && pSurface->cyBlock == 1)) 218 { 219 cBlocksX = mipmapSize.width; 220 cBlocksY = mipmapSize.height; 221 } 222 else 223 { 224 cBlocksX = mipmapSize.width / pSurface->cxBlock; 225 if (mipmapSize.width % pSurface->cxBlock) 226 ++cBlocksX; 227 cBlocksY = mipmapSize.height / pSurface->cyBlock; 228 if (mipmapSize.height % pSurface->cyBlock) 229 ++cBlocksY; 230 } 231 232 AssertReturn(cBlocksX > 0 && cBlocksY > 0 && mipmapSize.depth > 0, VERR_INVALID_PARAMETER); 233 234 const uint32_t cMaxBlocksX = cbMemRemaining / pSurface->cbBlock; 235 if (cBlocksX > cMaxBlocksX) 236 return VERR_INVALID_PARAMETER; 237 const uint32_t cbSurfacePitch = pSurface->cbBlock * cBlocksX; 238 LogFunc(("cbSurfacePitch=0x%x\n", cbSurfacePitch)); 239 240 const uint32_t cMaxBlocksY = cbMemRemaining / cbSurfacePitch; 241 if (cBlocksY > cMaxBlocksY) 242 return VERR_INVALID_PARAMETER; 243 const uint32_t cbSurfacePlane = cbSurfacePitch * cBlocksY; 244 245 const uint32_t cMaxDepth = cbMemRemaining / cbSurfacePlane; 246 if (mipmapSize.depth > cMaxDepth) 247 return VERR_INVALID_PARAMETER; 248 const uint32_t cbSurface = cbSurfacePlane * mipmapSize.depth; 249 250 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iMipmap]; 251 pMipmapLevel->mipmapSize = mipmapSize; 252 pMipmapLevel->cBlocksX = cBlocksX; 253 pMipmapLevel->cBlocksY = cBlocksY; 254 pMipmapLevel->cBlocks = cBlocksX * cBlocksY * mipmapSize.depth; 255 pMipmapLevel->cbSurfacePitch = cbSurfacePitch; 256 pMipmapLevel->cbSurfacePlane = cbSurfacePlane; 257 pMipmapLevel->cbSurface = cbSurface; 258 pMipmapLevel->pSurfaceData = NULL; 259 260 cbMemRemaining -= cbSurface; 261 } 262 263 mipmapSize.width >>= 1; 264 if (mipmapSize.width == 0) mipmapSize.width = 1; 265 mipmapSize.height >>= 1; 266 if (mipmapSize.height == 0) mipmapSize.height = 1; 267 mipmapSize.depth >>= 1; 268 if (mipmapSize.depth == 0) mipmapSize.depth = 1; 269 } 227 270 228 271 #ifdef VMSVGA3D_DIRECT3D … … 246 289 /* pSurface->bounce.pTexture = NULL; */ 247 290 /* pSurface->emulated.pTexture = NULL; */ 291 #elif defined(VMSVGA3D_DX) 292 /* Nothing, because all backend specific data reside in pSurface->pBackendSurface. */ 248 293 #else 249 294 /* pSurface->fEmulated = false; */ … … 264 309 265 310 /* Allocate buffer to hold the surface data until we can move it into a D3D object */ 266 uint32_t cbMemRemaining = SVGA3D_MAX_SURFACE_MEM_SIZE; /* Do not allow more than this for a surface. */ 267 for (uint32_t i = 0; i < cMipLevels; ++i) 311 for (uint32_t i = 0; i < numMipLevels * pSurface->cFaces; ++i) 268 312 { 269 313 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i]; 270 LogFunc(("[%d] face %d mip level %d (%d,%d,%d) cbBlock=0x%x block %dx%d\n", 271 i, i / pSurface->faces[0].numMipLevels, i % pSurface->faces[0].numMipLevels, 272 pMipmapLevel->mipmapSize.width, pMipmapLevel->mipmapSize.height, pMipmapLevel->mipmapSize.depth, 273 pSurface->cbBlock, pSurface->cxBlock, pSurface->cyBlock)); 274 275 uint32_t cBlocksX; 276 uint32_t cBlocksY; 277 if (RT_LIKELY(pSurface->cxBlock == 1 && pSurface->cyBlock == 1)) 278 { 279 cBlocksX = pMipmapLevel->mipmapSize.width; 280 cBlocksY = pMipmapLevel->mipmapSize.height; 281 } 282 else 283 { 284 cBlocksX = pMipmapLevel->mipmapSize.width / pSurface->cxBlock; 285 if (pMipmapLevel->mipmapSize.width % pSurface->cxBlock) 286 ++cBlocksX; 287 cBlocksY = pMipmapLevel->mipmapSize.height / pSurface->cyBlock; 288 if (pMipmapLevel->mipmapSize.height % pSurface->cyBlock) 289 ++cBlocksY; 290 } 291 292 if ( cBlocksX == 0 293 || cBlocksY == 0 294 || pMipmapLevel->mipmapSize.depth == 0) 295 return VERR_INVALID_PARAMETER; 296 297 const uint32_t cMaxBlocksX = cbMemRemaining / pSurface->cbBlock; 298 if (cBlocksX > cMaxBlocksX) 299 return VERR_INVALID_PARAMETER; 300 const uint32_t cbSurfacePitch = pSurface->cbBlock * cBlocksX; 301 LogFunc(("cbSurfacePitch=0x%x\n", cbSurfacePitch)); 302 303 const uint32_t cMaxBlocksY = cbMemRemaining / cbSurfacePitch; 304 if (cBlocksY > cMaxBlocksY) 305 return VERR_INVALID_PARAMETER; 306 const uint32_t cbSurfacePlane = cbSurfacePitch * cBlocksY; 307 308 const uint32_t cMaxDepth = cbMemRemaining / cbSurfacePlane; 309 if (pMipmapLevel->mipmapSize.depth > cMaxDepth) 310 return VERR_INVALID_PARAMETER; 311 const uint32_t cbSurface = cbSurfacePlane * pMipmapLevel->mipmapSize.depth; 312 313 pMipmapLevel->cBlocksX = cBlocksX; 314 pMipmapLevel->cBlocksY = cBlocksY; 315 pMipmapLevel->cBlocks = cBlocksX * cBlocksY * pMipmapLevel->mipmapSize.depth; 316 pMipmapLevel->cbSurfacePitch = cbSurfacePitch; 317 pMipmapLevel->cbSurfacePlane = cbSurfacePlane; 318 pMipmapLevel->cbSurface = cbSurface; 319 pMipmapLevel->pSurfaceData = RTMemAllocZ(cbSurface); 314 pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface); 320 315 AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY); 321 322 cbMemRemaining -= cbSurface;323 316 } 324 317 return VINF_SUCCESS; … … 363 356 if (pSurface->paMipmapLevels) 364 357 { 365 for (uint32_t i = 0; i < pSurface->c MipmapLevels; ++i)358 for (uint32_t i = 0; i < pSurface->cLevels * pSurface->cFaces; ++i) 366 359 RTMemFreeZ(pSurface->paMipmapLevels[i].pSurfaceData, pSurface->paMipmapLevels[i].cbSurface); 367 360 RTMemFree(pSurface->paMipmapLevels); … … 405 398 AssertRCReturn(rc, rc); 406 399 407 /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */408 400 AssertReturn(pSrcSfcImg->face < pSrcSurface->cFaces, VERR_INVALID_PARAMETER); 409 AssertReturn(pSrcSfcImg->mipmap < pSrcSurface-> faces[0].numMipLevels, VERR_INVALID_PARAMETER);401 AssertReturn(pSrcSfcImg->mipmap < pSrcSurface->cLevels, VERR_INVALID_PARAMETER); 410 402 AssertReturn(pDstSfcImg->face < pDstSurface->cFaces, VERR_INVALID_PARAMETER); 411 AssertReturn(pDstSfcImg->mipmap < pDstSurface-> faces[0].numMipLevels, VERR_INVALID_PARAMETER);403 AssertReturn(pDstSfcImg->mipmap < pDstSurface->cLevels, VERR_INVALID_PARAMETER); 412 404 413 405 PVMSVGA3DCONTEXT pContext; … … 514 506 /* Flush the drawing pipeline for this surface as it could be used in a shared context. */ 515 507 vmsvga3dSurfaceFlush(pSurface); 516 508 #elif defined(VMSVGA3D_DX) 509 /** @todo */ 517 510 #else /* VMSVGA3D_OPENGL */ 518 511 pContext = &pState->SharedCtx; -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
r86024 r86838 49 49 50 50 51 typedef enum VMSVGA3D_SURFACE_MAP 52 { 53 VMSVGA3D_SURFACE_MAP_READ, 54 VMSVGA3D_SURFACE_MAP_WRITE, 55 VMSVGA3D_SURFACE_MAP_READ_WRITE, 56 VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, 57 } VMSVGA3D_SURFACE_MAP; 58 59 typedef struct VMSVGA3D_MAPPED_SURFACE 60 { 61 VMSVGA3D_SURFACE_MAP enmMapType; 62 SVGA3dBox box; 63 uint32_t cbPixel; 64 uint32_t cbRowPitch; 65 uint32_t cbDepthPitch; 66 void *pvData; 67 } VMSVGA3D_MAPPED_SURFACE; 68 69 #ifdef DUMP_BITMAPS 70 void vmsvga3dMapWriteBmpFile(VMSVGA3D_MAPPED_SURFACE const *pMap, char const *pszPrefix); 71 #endif 72 51 73 /* DevVGA-SVGA.cpp: */ 52 74 void vmsvgaR33dSurfaceUpdateHeapBuffersOnFifoThread(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t sid); … … 63 85 int vmsvga3dQueryCaps(PVGASTATECC pThisCC, uint32_t idx3dCaps, uint32_t *pu32Val); 64 86 65 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, uint32_tsurfaceFlags, SVGA3dSurfaceFormat format,66 SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,67 SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *pMipLevelSize);87 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, SVGA3dSurfaceFlags surfaceFlags, SVGA3dSurfaceFormat format, 88 uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter, 89 uint32_t cMipLevels, SVGA3dSize const *pMipLevel0Size); 68 90 int vmsvga3dSurfaceDestroy(PVGASTATECC pThisCC, uint32_t sid); 69 91 int vmsvga3dSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, … … 108 130 int vmsvga3dQueryWait(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t cid, SVGA3dQueryType type, SVGAGuestPtr guestResult); 109 131 132 int vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid); 133 int vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect); 134 135 int vmsvga3dSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox, VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap); 136 int vmsvga3dSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten); 137 110 138 /* DevVGA-SVGA3d-shared.h: */ 111 139 #if defined(RT_OS_WINDOWS) && defined(IN_RING3) -
trunk/src/VBox/Devices/Graphics/DevVGASavedState.h
r83274 r86838 47 47 } while (0) 48 48 49 #define VGA_SAVEDSTATE_VERSION 22 49 #define VGA_SAVEDSTATE_VERSION 23 50 #define VGA_SAVEDSTATE_VERSION_VMSVGA_MIPLEVELS 23 /* Surface struct with number of miplevels. */ 50 51 #define VGA_SAVEDSTATE_VERSION_VMSVGA_CURSOR 22 /* Legacy cursor registers. */ 51 52 #define VGA_SAVEDSTATE_VERSION_VMSVGA_SCREENS 21 /* Screen objects. */
Note:
See TracChangeset
for help on using the changeset viewer.