Changeset 86193 in vbox for trunk/src/VBox
- Timestamp:
- Sep 21, 2020 12:37:31 PM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
r86024 r86193 213 213 214 214 #ifdef IN_RING3 215 typedef struct VMSVGACMDBUF *PVMSVGACMDBUF; 216 typedef struct VMSVGACMDBUFCTX *PVMSVGACMDBUFCTX; 217 218 /* Command buffer. */ 219 typedef struct VMSVGACMDBUF 220 { 221 RTLISTNODE nodeBuffer; 222 /* Context of the buffer. */ 223 PVMSVGACMDBUFCTX pCmdBufCtx; 224 /* PA of the buffer. */ 225 RTGCPHYS GCPhysCB; 226 /* A copy of the buffer header. */ 227 SVGACBHeader hdr; 228 /* A copy of the commands. Size of the memory buffer is hdr.length */ 229 void *pvCommands; 230 } VMSVGACMDBUF; 231 232 /* Command buffer context. */ 233 typedef struct VMSVGACMDBUFCTX 234 { 235 /* Buffers submitted to processing for the FIFO thread. */ 236 RTLISTANCHOR listSubmitted; 237 /* How many buffers in the queue. */ 238 uint32_t cSubmitted; 239 } VMSVGACMDBUFCTX; 240 215 241 /** 216 242 * Internal SVGA ring-3 only state. … … 250 276 # endif 251 277 252 /** Information obout screens. */278 /** Information about screens. */ 253 279 VMSVGASCREENOBJECT aScreens[64]; 280 281 /** Command buffer contexts. */ 282 PVMSVGACMDBUFCTX apCmdBufCtxs[SVGA_CB_CONTEXT_MAX]; 283 /** The special Device Context for synchronous commands. */ 284 VMSVGACMDBUFCTX CmdBufCtxDC; 285 /** Flag which indicates that there are buffers to be processed. */ 286 uint32_t volatile fCmdBuf; 287 /** Critical section for accessing the command buffer data. */ 288 RTCRITSECT CritSectCmdBuf; 254 289 255 290 /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */ … … 530 565 SSMFIELD_ENTRY( VMSVGAState, u32PitchLock), 531 566 SSMFIELD_ENTRY( VMSVGAState, u32CurrentGMRId), 532 SSMFIELD_ENTRY( VMSVGAState, u32 RegCaps),567 SSMFIELD_ENTRY( VMSVGAState, u32DeviceCaps), 533 568 SSMFIELD_ENTRY( VMSVGAState, u32IndexReg), 534 569 SSMFIELD_ENTRY_IGNORE( VMSVGAState, hFIFORequestSem), … … 566 601 uint32_t uVersion, uint32_t uPass); 567 602 static int vmsvgaR3SaveExecFifo(PCPDMDEVHLPR3 pHlp, PVGASTATECC pThisCC, PSSMHANDLE pSSM); 603 static void vmsvgaR3CmdBufSubmit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, RTGCPHYS GCPhysCB, SVGACBContext CBCtx); 568 604 # ifdef VBOX_WITH_VMSVGA3D 569 605 static void vmsvgaR3GmrFree(PVGASTATECC pThisCC, uint32_t idGMR); … … 604 640 #endif /* IN_RING3 */ 605 641 642 #define SVGA_CASE_ID2STR(idx) case idx: return #idx 643 606 644 #ifdef LOG_ENABLED 607 645 … … 617 655 switch (idxReg) 618 656 { 619 case SVGA_REG_ID: return "SVGA_REG_ID"; 620 case SVGA_REG_ENABLE: return "SVGA_REG_ENABLE"; 621 case SVGA_REG_WIDTH: return "SVGA_REG_WIDTH"; 622 case SVGA_REG_HEIGHT: return "SVGA_REG_HEIGHT"; 623 case SVGA_REG_MAX_WIDTH: return "SVGA_REG_MAX_WIDTH"; 624 case SVGA_REG_MAX_HEIGHT: return "SVGA_REG_MAX_HEIGHT"; 625 case SVGA_REG_DEPTH: return "SVGA_REG_DEPTH"; 626 case SVGA_REG_BITS_PER_PIXEL: return "SVGA_REG_BITS_PER_PIXEL"; /* Current bpp in the guest */ 627 case SVGA_REG_HOST_BITS_PER_PIXEL: return "SVGA_REG_HOST_BITS_PER_PIXEL"; /* (Deprecated) */ 628 case SVGA_REG_PSEUDOCOLOR: return "SVGA_REG_PSEUDOCOLOR"; 629 case SVGA_REG_RED_MASK: return "SVGA_REG_RED_MASK"; 630 case SVGA_REG_GREEN_MASK: return "SVGA_REG_GREEN_MASK"; 631 case SVGA_REG_BLUE_MASK: return "SVGA_REG_BLUE_MASK"; 632 case SVGA_REG_BYTES_PER_LINE: return "SVGA_REG_BYTES_PER_LINE"; 633 case SVGA_REG_VRAM_SIZE: return "SVGA_REG_VRAM_SIZE"; /* VRAM size */ 634 case SVGA_REG_FB_START: return "SVGA_REG_FB_START"; /* Frame buffer physical address. */ 635 case SVGA_REG_FB_OFFSET: return "SVGA_REG_FB_OFFSET"; /* Offset of the frame buffer in VRAM */ 636 case SVGA_REG_FB_SIZE: return "SVGA_REG_FB_SIZE"; /* Frame buffer size */ 637 case SVGA_REG_CAPABILITIES: return "SVGA_REG_CAPABILITIES"; 638 case SVGA_REG_MEM_START: return "SVGA_REG_MEM_START"; /* FIFO start */ 639 case SVGA_REG_MEM_SIZE: return "SVGA_REG_MEM_SIZE"; /* FIFO size */ 640 case SVGA_REG_CONFIG_DONE: return "SVGA_REG_CONFIG_DONE"; /* Set when memory area configured */ 641 case SVGA_REG_SYNC: return "SVGA_REG_SYNC"; /* See "FIFO Synchronization Registers" */ 642 case SVGA_REG_BUSY: return "SVGA_REG_BUSY"; /* See "FIFO Synchronization Registers" */ 643 case SVGA_REG_GUEST_ID: return "SVGA_REG_GUEST_ID"; /* Set guest OS identifier */ 644 case SVGA_REG_SCRATCH_SIZE: return "SVGA_REG_SCRATCH_SIZE"; /* Number of scratch registers */ 645 case SVGA_REG_MEM_REGS: return "SVGA_REG_MEM_REGS"; /* Number of FIFO registers */ 646 case SVGA_REG_PITCHLOCK: return "SVGA_REG_PITCHLOCK"; /* Fixed pitch for all modes */ 647 case SVGA_REG_IRQMASK: return "SVGA_REG_IRQMASK"; /* Interrupt mask */ 648 case SVGA_REG_GMR_ID: return "SVGA_REG_GMR_ID"; 649 case SVGA_REG_GMR_DESCRIPTOR: return "SVGA_REG_GMR_DESCRIPTOR"; 650 case SVGA_REG_GMR_MAX_IDS: return "SVGA_REG_GMR_MAX_IDS"; 651 case SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH:return "SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH"; 652 case SVGA_REG_TRACES: return "SVGA_REG_TRACES"; /* Enable trace-based updates even when FIFO is on */ 653 case SVGA_REG_GMRS_MAX_PAGES: return "SVGA_REG_GMRS_MAX_PAGES"; /* Maximum number of 4KB pages for all GMRs */ 654 case SVGA_REG_MEMORY_SIZE: return "SVGA_REG_MEMORY_SIZE"; /* Total dedicated device memory excluding FIFO */ 655 case SVGA_REG_TOP: return "SVGA_REG_TOP"; /* Must be 1 more than the last register */ 656 case SVGA_PALETTE_BASE: return "SVGA_PALETTE_BASE"; /* Base of SVGA color map */ 657 case SVGA_REG_CURSOR_ID: return "SVGA_REG_CURSOR_ID"; 658 case SVGA_REG_CURSOR_X: return "SVGA_REG_CURSOR_X"; 659 case SVGA_REG_CURSOR_Y: return "SVGA_REG_CURSOR_Y"; 660 case SVGA_REG_CURSOR_ON: return "SVGA_REG_CURSOR_ON"; 661 case SVGA_REG_NUM_GUEST_DISPLAYS: return "SVGA_REG_NUM_GUEST_DISPLAYS"; /* Number of guest displays in X/Y direction */ 662 case SVGA_REG_DISPLAY_ID: return "SVGA_REG_DISPLAY_ID"; /* Display ID for the following display attributes */ 663 case SVGA_REG_DISPLAY_IS_PRIMARY: return "SVGA_REG_DISPLAY_IS_PRIMARY"; /* Whether this is a primary display */ 664 case SVGA_REG_DISPLAY_POSITION_X: return "SVGA_REG_DISPLAY_POSITION_X"; /* The display position x */ 665 case SVGA_REG_DISPLAY_POSITION_Y: return "SVGA_REG_DISPLAY_POSITION_Y"; /* The display position y */ 666 case SVGA_REG_DISPLAY_WIDTH: return "SVGA_REG_DISPLAY_WIDTH"; /* The display's width */ 667 case SVGA_REG_DISPLAY_HEIGHT: return "SVGA_REG_DISPLAY_HEIGHT"; /* The display's height */ 668 case SVGA_REG_NUM_DISPLAYS: return "SVGA_REG_NUM_DISPLAYS"; /* (Deprecated) */ 657 SVGA_CASE_ID2STR(SVGA_REG_ID); 658 SVGA_CASE_ID2STR(SVGA_REG_ENABLE); 659 SVGA_CASE_ID2STR(SVGA_REG_WIDTH); 660 SVGA_CASE_ID2STR(SVGA_REG_HEIGHT); 661 SVGA_CASE_ID2STR(SVGA_REG_MAX_WIDTH); 662 SVGA_CASE_ID2STR(SVGA_REG_MAX_HEIGHT); 663 SVGA_CASE_ID2STR(SVGA_REG_DEPTH); 664 SVGA_CASE_ID2STR(SVGA_REG_BITS_PER_PIXEL); /* Current bpp in the guest */ 665 SVGA_CASE_ID2STR(SVGA_REG_PSEUDOCOLOR); 666 SVGA_CASE_ID2STR(SVGA_REG_RED_MASK); 667 SVGA_CASE_ID2STR(SVGA_REG_GREEN_MASK); 668 SVGA_CASE_ID2STR(SVGA_REG_BLUE_MASK); 669 SVGA_CASE_ID2STR(SVGA_REG_BYTES_PER_LINE); 670 SVGA_CASE_ID2STR(SVGA_REG_FB_START); /* (Deprecated) */ 671 SVGA_CASE_ID2STR(SVGA_REG_FB_OFFSET); 672 SVGA_CASE_ID2STR(SVGA_REG_VRAM_SIZE); 673 SVGA_CASE_ID2STR(SVGA_REG_FB_SIZE); 674 675 /* ID 0 implementation only had the above registers, then the palette */ 676 SVGA_CASE_ID2STR(SVGA_REG_CAPABILITIES); 677 SVGA_CASE_ID2STR(SVGA_REG_MEM_START); /* (Deprecated) */ 678 SVGA_CASE_ID2STR(SVGA_REG_MEM_SIZE); 679 SVGA_CASE_ID2STR(SVGA_REG_CONFIG_DONE); /* Set when memory area configured */ 680 SVGA_CASE_ID2STR(SVGA_REG_SYNC); /* See "FIFO Synchronization Registers" */ 681 SVGA_CASE_ID2STR(SVGA_REG_BUSY); /* See "FIFO Synchronization Registers" */ 682 SVGA_CASE_ID2STR(SVGA_REG_GUEST_ID); /* Set guest OS identifier */ 683 SVGA_CASE_ID2STR(SVGA_REG_CURSOR_ID); /* (Deprecated) */ 684 SVGA_CASE_ID2STR(SVGA_REG_CURSOR_X); /* (Deprecated) */ 685 SVGA_CASE_ID2STR(SVGA_REG_CURSOR_Y); /* (Deprecated) */ 686 SVGA_CASE_ID2STR(SVGA_REG_CURSOR_ON); /* (Deprecated) */ 687 SVGA_CASE_ID2STR(SVGA_REG_HOST_BITS_PER_PIXEL); /* (Deprecated) */ 688 SVGA_CASE_ID2STR(SVGA_REG_SCRATCH_SIZE); /* Number of scratch registers */ 689 SVGA_CASE_ID2STR(SVGA_REG_MEM_REGS); /* Number of FIFO registers */ 690 SVGA_CASE_ID2STR(SVGA_REG_NUM_DISPLAYS); /* (Deprecated) */ 691 SVGA_CASE_ID2STR(SVGA_REG_PITCHLOCK); /* Fixed pitch for all modes */ 692 SVGA_CASE_ID2STR(SVGA_REG_IRQMASK); /* Interrupt mask */ 693 694 /* Legacy multi-monitor support */ 695 SVGA_CASE_ID2STR(SVGA_REG_NUM_GUEST_DISPLAYS); /* Number of guest displays in X/Y direction */ 696 SVGA_CASE_ID2STR(SVGA_REG_DISPLAY_ID); /* Display ID for the following display attributes */ 697 SVGA_CASE_ID2STR(SVGA_REG_DISPLAY_IS_PRIMARY); /* Whether this is a primary display */ 698 SVGA_CASE_ID2STR(SVGA_REG_DISPLAY_POSITION_X); /* The display position x */ 699 SVGA_CASE_ID2STR(SVGA_REG_DISPLAY_POSITION_Y); /* The display position y */ 700 SVGA_CASE_ID2STR(SVGA_REG_DISPLAY_WIDTH); /* The display's width */ 701 SVGA_CASE_ID2STR(SVGA_REG_DISPLAY_HEIGHT); /* The display's height */ 702 703 SVGA_CASE_ID2STR(SVGA_REG_GMR_ID); 704 SVGA_CASE_ID2STR(SVGA_REG_GMR_DESCRIPTOR); 705 SVGA_CASE_ID2STR(SVGA_REG_GMR_MAX_IDS); 706 SVGA_CASE_ID2STR(SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH); 707 708 SVGA_CASE_ID2STR(SVGA_REG_TRACES); /* Enable trace-based updates even when FIFO is on */ 709 SVGA_CASE_ID2STR(SVGA_REG_GMRS_MAX_PAGES); /* Maximum number of 4KB pages for all GMRs */ 710 SVGA_CASE_ID2STR(SVGA_REG_MEMORY_SIZE); /* Total dedicated device memory excluding FIFO */ 711 SVGA_CASE_ID2STR(SVGA_REG_COMMAND_LOW); /* Lower 32 bits and submits commands */ 712 SVGA_CASE_ID2STR(SVGA_REG_COMMAND_HIGH); /* Upper 32 bits of command buffer PA */ 713 SVGA_CASE_ID2STR(SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); /* Max primary memory */ 714 SVGA_CASE_ID2STR(SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); /* Suggested limit on mob mem */ 715 SVGA_CASE_ID2STR(SVGA_REG_DEV_CAP); /* Write dev cap index, read value */ 716 SVGA_CASE_ID2STR(SVGA_REG_CMD_PREPEND_LOW); 717 SVGA_CASE_ID2STR(SVGA_REG_iCMD_PREPEND_HIGH); 718 SVGA_CASE_ID2STR(SVGA_REG_SCREENTARGET_MAX_WIDTH); 719 SVGA_CASE_ID2STR(SVGA_REG_SCREENTARGET_MAX_HEIGHT); 720 SVGA_CASE_ID2STR(SVGA_REG_MOB_MAX_SIZE); 721 SVGA_CASE_ID2STR(SVGA_REG_TOP); /* Must be 1 more than the last register */ 669 722 670 723 default: … … 688 741 switch (u32Cmd) 689 742 { 690 case SVGA_CMD_INVALID_CMD: return "SVGA_CMD_INVALID_CMD"; 691 case SVGA_CMD_UPDATE: return "SVGA_CMD_UPDATE"; 692 case SVGA_CMD_RECT_COPY: return "SVGA_CMD_RECT_COPY"; 693 case SVGA_CMD_RECT_ROP_COPY: return "SVGA_CMD_RECT_ROP_COPY"; 694 case SVGA_CMD_DEFINE_CURSOR: return "SVGA_CMD_DEFINE_CURSOR"; 695 case SVGA_CMD_DISPLAY_CURSOR: return "SVGA_CMD_DISPLAY_CURSOR"; 696 case SVGA_CMD_MOVE_CURSOR: return "SVGA_CMD_MOVE_CURSOR"; 697 case SVGA_CMD_DEFINE_ALPHA_CURSOR: return "SVGA_CMD_DEFINE_ALPHA_CURSOR"; 698 case SVGA_CMD_UPDATE_VERBOSE: return "SVGA_CMD_UPDATE_VERBOSE"; 699 case SVGA_CMD_FRONT_ROP_FILL: return "SVGA_CMD_FRONT_ROP_FILL"; 700 case SVGA_CMD_FENCE: return "SVGA_CMD_FENCE"; 701 case SVGA_CMD_ESCAPE: return "SVGA_CMD_ESCAPE"; 702 case SVGA_CMD_DEFINE_SCREEN: return "SVGA_CMD_DEFINE_SCREEN"; 703 case SVGA_CMD_DESTROY_SCREEN: return "SVGA_CMD_DESTROY_SCREEN"; 704 case SVGA_CMD_DEFINE_GMRFB: return "SVGA_CMD_DEFINE_GMRFB"; 705 case SVGA_CMD_BLIT_GMRFB_TO_SCREEN: return "SVGA_CMD_BLIT_GMRFB_TO_SCREEN"; 706 case SVGA_CMD_BLIT_SCREEN_TO_GMRFB: return "SVGA_CMD_BLIT_SCREEN_TO_GMRFB"; 707 case SVGA_CMD_ANNOTATION_FILL: return "SVGA_CMD_ANNOTATION_FILL"; 708 case SVGA_CMD_ANNOTATION_COPY: return "SVGA_CMD_ANNOTATION_COPY"; 709 case SVGA_CMD_DEFINE_GMR2: return "SVGA_CMD_DEFINE_GMR2"; 710 case SVGA_CMD_REMAP_GMR2: return "SVGA_CMD_REMAP_GMR2"; 711 case SVGA_3D_CMD_SURFACE_DEFINE: return "SVGA_3D_CMD_SURFACE_DEFINE"; 712 case SVGA_3D_CMD_SURFACE_DESTROY: return "SVGA_3D_CMD_SURFACE_DESTROY"; 713 case SVGA_3D_CMD_SURFACE_COPY: return "SVGA_3D_CMD_SURFACE_COPY"; 714 case SVGA_3D_CMD_SURFACE_STRETCHBLT: return "SVGA_3D_CMD_SURFACE_STRETCHBLT"; 715 case SVGA_3D_CMD_SURFACE_DMA: return "SVGA_3D_CMD_SURFACE_DMA"; 716 case SVGA_3D_CMD_CONTEXT_DEFINE: return "SVGA_3D_CMD_CONTEXT_DEFINE"; 717 case SVGA_3D_CMD_CONTEXT_DESTROY: return "SVGA_3D_CMD_CONTEXT_DESTROY"; 718 case SVGA_3D_CMD_SETTRANSFORM: return "SVGA_3D_CMD_SETTRANSFORM"; 719 case SVGA_3D_CMD_SETZRANGE: return "SVGA_3D_CMD_SETZRANGE"; 720 case SVGA_3D_CMD_SETRENDERSTATE: return "SVGA_3D_CMD_SETRENDERSTATE"; 721 case SVGA_3D_CMD_SETRENDERTARGET: return "SVGA_3D_CMD_SETRENDERTARGET"; 722 case SVGA_3D_CMD_SETTEXTURESTATE: return "SVGA_3D_CMD_SETTEXTURESTATE"; 723 case SVGA_3D_CMD_SETMATERIAL: return "SVGA_3D_CMD_SETMATERIAL"; 724 case SVGA_3D_CMD_SETLIGHTDATA: return "SVGA_3D_CMD_SETLIGHTDATA"; 725 case SVGA_3D_CMD_SETLIGHTENABLED: return "SVGA_3D_CMD_SETLIGHTENABLED"; 726 case SVGA_3D_CMD_SETVIEWPORT: return "SVGA_3D_CMD_SETVIEWPORT"; 727 case SVGA_3D_CMD_SETCLIPPLANE: return "SVGA_3D_CMD_SETCLIPPLANE"; 728 case SVGA_3D_CMD_CLEAR: return "SVGA_3D_CMD_CLEAR"; 729 case SVGA_3D_CMD_PRESENT: return "SVGA_3D_CMD_PRESENT"; 730 case SVGA_3D_CMD_SHADER_DEFINE: return "SVGA_3D_CMD_SHADER_DEFINE"; 731 case SVGA_3D_CMD_SHADER_DESTROY: return "SVGA_3D_CMD_SHADER_DESTROY"; 732 case SVGA_3D_CMD_SET_SHADER: return "SVGA_3D_CMD_SET_SHADER"; 733 case SVGA_3D_CMD_SET_SHADER_CONST: return "SVGA_3D_CMD_SET_SHADER_CONST"; 734 case SVGA_3D_CMD_DRAW_PRIMITIVES: return "SVGA_3D_CMD_DRAW_PRIMITIVES"; 735 case SVGA_3D_CMD_SETSCISSORRECT: return "SVGA_3D_CMD_SETSCISSORRECT"; 736 case SVGA_3D_CMD_BEGIN_QUERY: return "SVGA_3D_CMD_BEGIN_QUERY"; 737 case SVGA_3D_CMD_END_QUERY: return "SVGA_3D_CMD_END_QUERY"; 738 case SVGA_3D_CMD_WAIT_FOR_QUERY: return "SVGA_3D_CMD_WAIT_FOR_QUERY"; 739 case SVGA_3D_CMD_PRESENT_READBACK: return "SVGA_3D_CMD_PRESENT_READBACK"; 740 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:return "SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN"; 741 case SVGA_3D_CMD_SURFACE_DEFINE_V2: return "SVGA_3D_CMD_SURFACE_DEFINE_V2"; 742 case SVGA_3D_CMD_GENERATE_MIPMAPS: return "SVGA_3D_CMD_GENERATE_MIPMAPS"; 743 case SVGA_3D_CMD_ACTIVATE_SURFACE: return "SVGA_3D_CMD_ACTIVATE_SURFACE"; 744 case SVGA_3D_CMD_DEACTIVATE_SURFACE: return "SVGA_3D_CMD_DEACTIVATE_SURFACE"; 745 default: return "UNKNOWN"; 743 SVGA_CASE_ID2STR(SVGA_CMD_INVALID_CMD); 744 SVGA_CASE_ID2STR(SVGA_CMD_UPDATE); 745 SVGA_CASE_ID2STR(SVGA_CMD_RECT_FILL); 746 SVGA_CASE_ID2STR(SVGA_CMD_RECT_COPY); 747 SVGA_CASE_ID2STR(SVGA_CMD_RECT_ROP_COPY); 748 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_CURSOR); 749 SVGA_CASE_ID2STR(SVGA_CMD_DISPLAY_CURSOR); 750 SVGA_CASE_ID2STR(SVGA_CMD_MOVE_CURSOR); 751 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_ALPHA_CURSOR); 752 SVGA_CASE_ID2STR(SVGA_CMD_UPDATE_VERBOSE); 753 SVGA_CASE_ID2STR(SVGA_CMD_FRONT_ROP_FILL); 754 SVGA_CASE_ID2STR(SVGA_CMD_FENCE); 755 SVGA_CASE_ID2STR(SVGA_CMD_ESCAPE); 756 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_SCREEN); 757 SVGA_CASE_ID2STR(SVGA_CMD_DESTROY_SCREEN); 758 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_GMRFB); 759 SVGA_CASE_ID2STR(SVGA_CMD_BLIT_GMRFB_TO_SCREEN); 760 SVGA_CASE_ID2STR(SVGA_CMD_BLIT_SCREEN_TO_GMRFB); 761 SVGA_CASE_ID2STR(SVGA_CMD_ANNOTATION_FILL); 762 SVGA_CASE_ID2STR(SVGA_CMD_ANNOTATION_COPY); 763 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_GMR2); 764 SVGA_CASE_ID2STR(SVGA_CMD_REMAP_GMR2); 765 SVGA_CASE_ID2STR(SVGA_CMD_DEAD); 766 SVGA_CASE_ID2STR(SVGA_CMD_DEAD_2); 767 SVGA_CASE_ID2STR(SVGA_CMD_NOP); 768 SVGA_CASE_ID2STR(SVGA_CMD_NOP_ERROR); 769 SVGA_CASE_ID2STR(SVGA_CMD_MAX); 770 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DEFINE); 771 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DESTROY); 772 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_COPY); 773 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_STRETCHBLT); 774 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DMA); 775 SVGA_CASE_ID2STR(SVGA_3D_CMD_CONTEXT_DEFINE); 776 SVGA_CASE_ID2STR(SVGA_3D_CMD_CONTEXT_DESTROY); 777 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETTRANSFORM); 778 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETZRANGE); 779 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETRENDERSTATE); 780 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETRENDERTARGET); 781 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETTEXTURESTATE); 782 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETMATERIAL); 783 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETLIGHTDATA); 784 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETLIGHTENABLED); 785 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETVIEWPORT); 786 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETCLIPPLANE); 787 SVGA_CASE_ID2STR(SVGA_3D_CMD_CLEAR); 788 SVGA_CASE_ID2STR(SVGA_3D_CMD_PRESENT); 789 SVGA_CASE_ID2STR(SVGA_3D_CMD_SHADER_DEFINE); 790 SVGA_CASE_ID2STR(SVGA_3D_CMD_SHADER_DESTROY); 791 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_SHADER); 792 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_SHADER_CONST); 793 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW_PRIMITIVES); 794 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETSCISSORRECT); 795 SVGA_CASE_ID2STR(SVGA_3D_CMD_BEGIN_QUERY); 796 SVGA_CASE_ID2STR(SVGA_3D_CMD_END_QUERY); 797 SVGA_CASE_ID2STR(SVGA_3D_CMD_WAIT_FOR_QUERY); 798 SVGA_CASE_ID2STR(SVGA_3D_CMD_PRESENT_READBACK); 799 SVGA_CASE_ID2STR(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); 800 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DEFINE_V2); 801 SVGA_CASE_ID2STR(SVGA_3D_CMD_GENERATE_MIPMAPS); 802 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_CREATE_DECODER); 803 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DESTROY_DECODER); 804 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_CREATE_PROCESSOR); 805 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DESTROY_PROCESSOR); 806 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_START_FRAME); 807 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_RENDER); 808 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_END_FRAME); 809 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_PROCESS_FRAME); 810 SVGA_CASE_ID2STR(SVGA_3D_CMD_ACTIVATE_SURFACE); 811 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEACTIVATE_SURFACE); 812 SVGA_CASE_ID2STR(SVGA_3D_CMD_SCREEN_DMA); 813 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD1); 814 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD2); 815 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_BITBLT); 816 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_TRANSBLT); 817 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_STRETCHBLT); 818 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_COLORFILL); 819 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_ALPHABLEND); 820 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND); 821 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_OTABLE_BASE); 822 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_OTABLE); 823 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_MOB); 824 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_MOB); 825 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD3); 826 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING); 827 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SURFACE); 828 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SURFACE); 829 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SURFACE); 830 SVGA_CASE_ID2STR(SVGA_3D_CMD_COND_BIND_GB_SURFACE); 831 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_IMAGE); 832 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_SURFACE); 833 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_IMAGE); 834 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_SURFACE); 835 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_IMAGE); 836 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_SURFACE); 837 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_CONTEXT); 838 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_CONTEXT); 839 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_CONTEXT); 840 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_CONTEXT); 841 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_CONTEXT); 842 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SHADER); 843 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SHADER); 844 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SHADER); 845 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_OTABLE_BASE64); 846 SVGA_CASE_ID2STR(SVGA_3D_CMD_BEGIN_GB_QUERY); 847 SVGA_CASE_ID2STR(SVGA_3D_CMD_END_GB_QUERY); 848 SVGA_CASE_ID2STR(SVGA_3D_CMD_WAIT_FOR_GB_QUERY); 849 SVGA_CASE_ID2STR(SVGA_3D_CMD_NOP); 850 SVGA_CASE_ID2STR(SVGA_3D_CMD_ENABLE_GART); 851 SVGA_CASE_ID2STR(SVGA_3D_CMD_DISABLE_GART); 852 SVGA_CASE_ID2STR(SVGA_3D_CMD_MAP_MOB_INTO_GART); 853 SVGA_CASE_ID2STR(SVGA_3D_CMD_UNMAP_GART_RANGE); 854 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SCREENTARGET); 855 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SCREENTARGET); 856 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SCREENTARGET); 857 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_SCREENTARGET); 858 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL); 859 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL); 860 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE); 861 SVGA_CASE_ID2STR(SVGA_3D_CMD_GB_SCREEN_DMA); 862 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH); 863 SVGA_CASE_ID2STR(SVGA_3D_CMD_GB_MOB_FENCE); 864 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SURFACE_V2); 865 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_MOB64); 866 SVGA_CASE_ID2STR(SVGA_3D_CMD_REDEFINE_GB_MOB64); 867 SVGA_CASE_ID2STR(SVGA_3D_CMD_NOP_ERROR); 868 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_STREAMS); 869 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_DECLS); 870 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_DIVISORS); 871 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW); 872 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW_INDEXED); 873 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_CONTEXT); 874 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_CONTEXT); 875 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_CONTEXT); 876 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_CONTEXT); 877 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_INVALIDATE_CONTEXT); 878 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER); 879 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SHADER_RESOURCES); 880 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SHADER); 881 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SAMPLERS); 882 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW); 883 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INDEXED); 884 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INSTANCED); 885 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED); 886 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_AUTO); 887 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT); 888 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS); 889 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_INDEX_BUFFER); 890 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_TOPOLOGY); 891 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_RENDERTARGETS); 892 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_BLEND_STATE); 893 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE); 894 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_RASTERIZER_STATE); 895 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_QUERY); 896 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_QUERY); 897 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_QUERY); 898 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_QUERY_OFFSET); 899 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BEGIN_QUERY); 900 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_END_QUERY); 901 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_QUERY); 902 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_PREDICATION); 903 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SOTARGETS); 904 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VIEWPORTS); 905 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SCISSORRECTS); 906 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW); 907 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW); 908 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_COPY_REGION); 909 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_COPY); 910 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_STRETCHBLT); 911 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_GENMIPS); 912 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE); 913 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_SUBRESOURCE); 914 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE); 915 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW); 916 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW); 917 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW); 918 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW); 919 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW); 920 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW); 921 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT); 922 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT); 923 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_BLEND_STATE); 924 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_BLEND_STATE); 925 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE); 926 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE); 927 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE); 928 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE); 929 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE); 930 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE); 931 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SHADER); 932 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SHADER); 933 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_SHADER); 934 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT); 935 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT); 936 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_STREAMOUTPUT); 937 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_COTABLE); 938 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_COTABLE); 939 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BUFFER_COPY); 940 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER); 941 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK); 942 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MOVE_QUERY); 943 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_ALL_QUERY); 944 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_ALL_QUERY); 945 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER); 946 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MOB_FENCE_64); 947 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_ALL_SHADER); 948 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_HINT); 949 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BUFFER_UPDATE); 950 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET); 951 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET); 952 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET); 953 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED1); 954 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED2); 955 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED3); 956 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER); 957 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MAX); 958 default: return "UNKNOWN"; 746 959 } 747 960 } … … 937 1150 938 1151 /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */ 939 if ( idxReg >= SVGA_REG_ CAPABILITIES1152 if ( idxReg >= SVGA_REG_ID_0_TOP 940 1153 && pThis->svga.u32SVGAId == SVGA_ID_0) 941 1154 { 942 idxReg += SVGA_PALETTE_BASE - SVGA_REG_ CAPABILITIES;1155 idxReg += SVGA_PALETTE_BASE - SVGA_REG_ID_0_TOP; 943 1156 Log(("vmsvgaWritePort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg)); 944 1157 } … … 1152 1365 case SVGA_REG_CAPABILITIES: 1153 1366 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCapabilitesRd); 1154 *pu32 = pThis->svga.u32 RegCaps;1367 *pu32 = pThis->svga.u32DeviceCaps; 1155 1368 break; 1156 1369 … … 1371 1584 break; 1372 1585 1586 /* 1587 * SVGA_CAP_GBOBJECTS+ registers. 1588 */ 1589 case SVGA_REG_COMMAND_LOW: 1590 /* Lower 32 bits of command buffer physical address. */ 1591 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCommandLowRd); 1592 *pu32 = pThis->svga.u32RegCommandLow; 1593 break; 1594 1595 case SVGA_REG_COMMAND_HIGH: 1596 /* Upper 32 bits of command buffer PA. */ 1597 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCommandHighRd); 1598 *pu32 = pThis->svga.u32RegCommandHigh; 1599 break; 1600 1601 case SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM: 1602 /* Max primary (screen) memory. */ 1603 STAM_REL_COUNTER_INC(&pThis->svga.StatRegMaxPrimBBMemRd); 1604 *pu32 = pThis->vram_size; /** @todo Maybe half VRAM? */ 1605 break; 1606 1607 case SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB: 1608 /* Suggested limit on mob mem (i.e. size of the guest mapped VRAM in KB) */ 1609 STAM_REL_COUNTER_INC(&pThis->svga.StatRegGBMemSizeRd); 1610 *pu32 = pThis->vram_size / 1024; 1611 break; 1612 1613 case SVGA_REG_DEV_CAP: 1614 /* Write dev cap index, read value */ 1615 STAM_REL_COUNTER_INC(&pThis->svga.StatRegDevCapRd); 1616 if (pThis->svga.u32DevCapIndex < RT_ELEMENTS(pThis->svga.au32DevCaps)) 1617 { 1618 RT_UNTRUSTED_VALIDATED_FENCE(); 1619 *pu32 = pThis->svga.au32DevCaps[pThis->svga.u32DevCapIndex]; 1620 } 1621 else 1622 *pu32 = 0; 1623 break; 1624 1625 case SVGA_REG_CMD_PREPEND_LOW: 1626 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCmdPrependLowRd); 1627 *pu32 = 0; /* Not supported. */ 1628 break; 1629 1630 case SVGA_REG_iCMD_PREPEND_HIGH: 1631 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCmdPrependHighRd); 1632 *pu32 = 0; /* Not supported. */ 1633 break; 1634 1635 case SVGA_REG_SCREENTARGET_MAX_WIDTH: 1636 STAM_REL_COUNTER_INC(&pThis->svga.StatRegScrnTgtMaxWidthRd); 1637 *pu32 = pThis->svga.u32MaxWidth; 1638 break; 1639 1640 case SVGA_REG_SCREENTARGET_MAX_HEIGHT: 1641 STAM_REL_COUNTER_INC(&pThis->svga.StatRegScrnTgtMaxHeightRd); 1642 *pu32 = pThis->svga.u32MaxHeight; 1643 break; 1644 1645 case SVGA_REG_MOB_MAX_SIZE: 1646 /* Essentially the max texture size */ 1647 STAM_REL_COUNTER_INC(&pThis->svga.StatRegMobMaxSizeRd); 1648 *pu32 = _128M; /** @todo Some actual value. Probably the mapped VRAM size. */ 1649 break; 1650 1373 1651 default: 1374 1652 { … … 1376 1654 if ((offReg = idxReg - SVGA_SCRATCH_BASE) < pThis->svga.cScratchRegion) 1377 1655 { 1656 STAM_REL_COUNTER_INC(&pThis->svga.StatRegScratchRd); 1378 1657 RT_UNTRUSTED_VALIDATED_FENCE(); 1379 1658 *pu32 = pThis->svga.au32ScratchRegion[offReg]; 1380 STAM_REL_COUNTER_INC(&pThis->svga.StatRegScratchRd);1381 1659 } 1382 1660 else if ((offReg = idxReg - SVGA_PALETTE_BASE) < (uint32_t)SVGA_NUM_PALETTE_REGS) … … 1710 1988 1711 1989 /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */ 1712 if ( idxReg >= SVGA_REG_ CAPABILITIES1990 if ( idxReg >= SVGA_REG_ID_0_TOP 1713 1991 && pThis->svga.u32SVGAId == SVGA_ID_0) 1714 1992 { 1715 idxReg += SVGA_PALETTE_BASE - SVGA_REG_ CAPABILITIES;1993 idxReg += SVGA_PALETTE_BASE - SVGA_REG_ID_0_TOP; 1716 1994 Log(("vmsvgaWritePort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg)); 1717 1995 } … … 2096 2374 STAM_REL_COUNTER_INC(&pThis->svga.StatRegNumDisplaysWr); 2097 2375 Log(("Write to deprecated register %x - val %x ignored\n", idxReg, u32)); 2376 break; 2377 2378 /* 2379 * SVGA_CAP_GBOBJECTS+ registers. 2380 */ 2381 case SVGA_REG_COMMAND_LOW: 2382 { 2383 /* Lower 32 bits of command buffer physical address and submit the command buffer. */ 2384 #ifdef IN_RING3 2385 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCommandLowWr); 2386 pThis->svga.u32RegCommandLow = u32; 2387 2388 /* "lower 6 bits are used for the SVGACBContext" */ 2389 RTGCPHYS GCPhysCB = pThis->svga.u32RegCommandHigh; 2390 GCPhysCB <<= 32; 2391 GCPhysCB |= pThis->svga.u32RegCommandLow & ~SVGA_CB_CONTEXT_MASK; 2392 SVGACBContext const CBCtx = (SVGACBContext)(pThis->svga.u32RegCommandLow & SVGA_CB_CONTEXT_MASK); 2393 vmsvgaR3CmdBufSubmit(pDevIns, pThis, pThisCC, GCPhysCB, CBCtx); 2394 #else 2395 rc = VINF_IOM_R3_IOPORT_WRITE; 2396 #endif 2397 break; 2398 } 2399 2400 case SVGA_REG_COMMAND_HIGH: 2401 /* Upper 32 bits of command buffer PA. */ 2402 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCommandHighWr); 2403 pThis->svga.u32RegCommandHigh = u32; 2404 break; 2405 2406 case SVGA_REG_DEV_CAP: 2407 /* Write dev cap index, read value */ 2408 STAM_REL_COUNTER_INC(&pThis->svga.StatRegDevCapWr); 2409 pThis->svga.u32DevCapIndex = u32; 2410 break; 2411 2412 case SVGA_REG_CMD_PREPEND_LOW: 2413 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCmdPrependLowWr); 2414 /* Not supported. */ 2415 break; 2416 2417 case SVGA_REG_iCMD_PREPEND_HIGH: 2418 STAM_REL_COUNTER_INC(&pThis->svga.StatRegCmdPrependHighWr); 2419 /* Not supported. */ 2098 2420 break; 2099 2421 … … 2118 2440 case SVGA_REG_GMR_MAX_IDS: 2119 2441 case SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH: 2442 case SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM: 2443 case SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB: 2444 case SVGA_REG_SCREENTARGET_MAX_WIDTH: 2445 case SVGA_REG_SCREENTARGET_MAX_HEIGHT: 2446 case SVGA_REG_MOB_MAX_SIZE: 2120 2447 /* Read only - ignore. */ 2121 2448 Log(("Write to R/O register %x - val %x ignored\n", idxReg, u32)); … … 2843 3170 2844 3171 2845 /** 2846 * Handles the SVGA_CMD_DEFINE_CURSOR command. 3172 /** SVGA_3D_CMD_* handler. 2847 3173 * 2848 * @param pThis The shared VGA/VMSVGA state. 2849 * @param pThisCC The VGA/VMSVGA state for ring-3. 2850 * @param pSVGAState The VMSVGA ring-3 instance data. 2851 * @param pCursor The cursor. 2852 * @param pbSrcAndMask The AND mask. 2853 * @param cbSrcAndLine The scanline length of the AND mask. 2854 * @param pbSrcXorMask The XOR mask. 2855 * @param cbSrcXorLine The scanline length of the XOR mask. 2856 */ 2857 static void vmsvgaR3CmdDefineCursor(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGAR3STATE pSVGAState, 2858 SVGAFifoCmdDefineCursor const *pCursor, 2859 uint8_t const *pbSrcAndMask, uint32_t cbSrcAndLine, 2860 uint8_t const *pbSrcXorMask, uint32_t cbSrcXorLine) 2861 { 2862 uint32_t const cx = pCursor->width; 2863 uint32_t const cy = pCursor->height; 3174 * @param pThis The shared VGA/VMSVGA state. 3175 * @param pThisCC The VGA/VMSVGA state for the current context. 3176 * @param cmdId SVGA_3D_CMD_* command identifier. 3177 * @param cbCmd Size of the command in bytes. 3178 * @param pvCmd Pointer to the command. 3179 */ 3180 static int vmsvgaR3Process3dCmd(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t cmdId, uint32_t cbCmd, void const *pvCmd) 3181 { 3182 int rc = VINF_SUCCESS; 3183 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State; 3184 3185 /** @def VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK 3186 * Check that the 3D command has at least a_cbMin of payload bytes after the 3187 * header. Will break out of the switch if it doesn't. 3188 */ 3189 # define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \ 3190 if (1) { \ 3191 AssertMsgBreak(cbCmd >= (a_cbMin), ("size=%#x a_cbMin=%#zx\n", cbCmd, (size_t)(a_cbMin))); \ 3192 RT_UNTRUSTED_VALIDATED_FENCE(); \ 3193 } else do {} while (0) 3194 3195 switch (cmdId) 3196 { 3197 case SVGA_3D_CMD_SURFACE_DEFINE: 3198 { 3199 uint32_t cMipLevels; 3200 SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)pvCmd; 3201 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3202 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDefine); 3203 3204 cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 3205 rc = vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0, 3206 SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1)); 3207 # ifdef DEBUG_GMR_ACCESS 3208 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis); 3209 # endif 3210 break; 3211 } 3212 3213 case SVGA_3D_CMD_SURFACE_DEFINE_V2: 3214 { 3215 uint32_t cMipLevels; 3216 SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)pvCmd; 3217 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3218 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDefineV2); 3219 3220 cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 3221 rc = vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face, 3222 pCmd->multisampleCount, pCmd->autogenFilter, 3223 cMipLevels, (SVGA3dSize *)(pCmd + 1)); 3224 break; 3225 } 3226 3227 case SVGA_3D_CMD_SURFACE_DESTROY: 3228 { 3229 SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)pvCmd; 3230 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3231 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDestroy); 3232 rc = vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid); 3233 break; 3234 } 3235 3236 case SVGA_3D_CMD_SURFACE_COPY: 3237 { 3238 uint32_t cCopyBoxes; 3239 SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)pvCmd; 3240 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3241 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceCopy); 3242 3243 cCopyBoxes = (cbCmd - sizeof(pCmd)) / sizeof(SVGA3dCopyBox); 3244 rc = vmsvga3dSurfaceCopy(pThisCC, pCmd->dest, pCmd->src, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1)); 3245 break; 3246 } 3247 3248 case SVGA_3D_CMD_SURFACE_STRETCHBLT: 3249 { 3250 SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)pvCmd; 3251 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3252 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceStretchBlt); 3253 3254 rc = vmsvga3dSurfaceStretchBlt(pThis, pThisCC, &pCmd->dest, &pCmd->boxDest, 3255 &pCmd->src, &pCmd->boxSrc, pCmd->mode); 3256 break; 3257 } 3258 3259 case SVGA_3D_CMD_SURFACE_DMA: 3260 { 3261 uint32_t cCopyBoxes; 3262 SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)pvCmd; 3263 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3264 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDma); 3265 3266 uint64_t u64NanoTS = 0; 3267 if (LogRelIs3Enabled()) 3268 u64NanoTS = RTTimeNanoTS(); 3269 cCopyBoxes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox); 3270 STAM_PROFILE_START(&pSVGAState->StatR3Cmd3dSurfaceDmaProf, a); 3271 rc = vmsvga3dSurfaceDMA(pThis, pThisCC, pCmd->guest, pCmd->host, pCmd->transfer, 3272 cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1)); 3273 STAM_PROFILE_STOP(&pSVGAState->StatR3Cmd3dSurfaceDmaProf, a); 3274 if (LogRelIs3Enabled()) 3275 { 3276 if (cCopyBoxes) 3277 { 3278 SVGA3dCopyBox *pFirstBox = (SVGA3dCopyBox *)(pCmd + 1); 3279 LogRel3(("VMSVGA: SURFACE_DMA: %d us %d boxes %d,%d %dx%d%s\n", 3280 (RTTimeNanoTS() - u64NanoTS) / 1000ULL, cCopyBoxes, 3281 pFirstBox->x, pFirstBox->y, pFirstBox->w, pFirstBox->h, 3282 pCmd->transfer == SVGA3D_READ_HOST_VRAM ? " readback!!!" : "")); 3283 } 3284 } 3285 break; 3286 } 3287 3288 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN: 3289 { 3290 uint32_t cRects; 3291 SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)pvCmd; 3292 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3293 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceScreen); 3294 3295 static uint64_t u64FrameStartNanoTS = 0; 3296 static uint64_t u64ElapsedPerSecNano = 0; 3297 static int cFrames = 0; 3298 uint64_t u64NanoTS = 0; 3299 if (LogRelIs3Enabled()) 3300 u64NanoTS = RTTimeNanoTS(); 3301 cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGASignedRect); 3302 STAM_REL_PROFILE_START(&pSVGAState->StatR3Cmd3dBlitSurfaceToScreenProf, a); 3303 rc = vmsvga3dSurfaceBlitToScreen(pThis, pThisCC, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage, 3304 pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1)); 3305 STAM_REL_PROFILE_STOP(&pSVGAState->StatR3Cmd3dBlitSurfaceToScreenProf, a); 3306 if (LogRelIs3Enabled()) 3307 { 3308 uint64_t u64ElapsedNano = RTTimeNanoTS() - u64NanoTS; 3309 u64ElapsedPerSecNano += u64ElapsedNano; 3310 3311 SVGASignedRect *pFirstRect = cRects ? (SVGASignedRect *)(pCmd + 1) : &pCmd->destRect; 3312 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: %d us %d rects %d,%d %dx%d\n", 3313 (u64ElapsedNano) / 1000ULL, cRects, 3314 pFirstRect->left, pFirstRect->top, 3315 pFirstRect->right - pFirstRect->left, pFirstRect->bottom - pFirstRect->top)); 3316 3317 ++cFrames; 3318 if (u64NanoTS - u64FrameStartNanoTS >= UINT64_C(1000000000)) 3319 { 3320 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: FPS %d, elapsed %llu us\n", 3321 cFrames, u64ElapsedPerSecNano / 1000ULL)); 3322 u64FrameStartNanoTS = u64NanoTS; 3323 cFrames = 0; 3324 u64ElapsedPerSecNano = 0; 3325 } 3326 } 3327 break; 3328 } 3329 3330 case SVGA_3D_CMD_CONTEXT_DEFINE: 3331 { 3332 SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)pvCmd; 3333 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3334 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dContextDefine); 3335 3336 rc = vmsvga3dContextDefine(pThisCC, pCmd->cid); 3337 break; 3338 } 3339 3340 case SVGA_3D_CMD_CONTEXT_DESTROY: 3341 { 3342 SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)pvCmd; 3343 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3344 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dContextDestroy); 3345 3346 rc = vmsvga3dContextDestroy(pThisCC, pCmd->cid); 3347 break; 3348 } 3349 3350 case SVGA_3D_CMD_SETTRANSFORM: 3351 { 3352 SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)pvCmd; 3353 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3354 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetTransform); 3355 3356 rc = vmsvga3dSetTransform(pThisCC, pCmd->cid, pCmd->type, pCmd->matrix); 3357 break; 3358 } 3359 3360 case SVGA_3D_CMD_SETZRANGE: 3361 { 3362 SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)pvCmd; 3363 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3364 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetZRange); 3365 3366 rc = vmsvga3dSetZRange(pThisCC, pCmd->cid, pCmd->zRange); 3367 break; 3368 } 3369 3370 case SVGA_3D_CMD_SETRENDERSTATE: 3371 { 3372 uint32_t cRenderStates; 3373 SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)pvCmd; 3374 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3375 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetRenderState); 3376 3377 cRenderStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRenderState); 3378 rc = vmsvga3dSetRenderState(pThisCC, pCmd->cid, cRenderStates, (SVGA3dRenderState *)(pCmd + 1)); 3379 break; 3380 } 3381 3382 case SVGA_3D_CMD_SETRENDERTARGET: 3383 { 3384 SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)pvCmd; 3385 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3386 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetRenderTarget); 3387 3388 rc = vmsvga3dSetRenderTarget(pThisCC, pCmd->cid, pCmd->type, pCmd->target); 3389 break; 3390 } 3391 3392 case SVGA_3D_CMD_SETTEXTURESTATE: 3393 { 3394 uint32_t cTextureStates; 3395 SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)pvCmd; 3396 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3397 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetTextureState); 3398 3399 cTextureStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dTextureState); 3400 rc = vmsvga3dSetTextureState(pThisCC, pCmd->cid, cTextureStates, (SVGA3dTextureState *)(pCmd + 1)); 3401 break; 3402 } 3403 3404 case SVGA_3D_CMD_SETMATERIAL: 3405 { 3406 SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)pvCmd; 3407 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3408 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetMaterial); 3409 3410 rc = vmsvga3dSetMaterial(pThisCC, pCmd->cid, pCmd->face, &pCmd->material); 3411 break; 3412 } 3413 3414 case SVGA_3D_CMD_SETLIGHTDATA: 3415 { 3416 SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)pvCmd; 3417 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3418 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetLightData); 3419 3420 rc = vmsvga3dSetLightData(pThisCC, pCmd->cid, pCmd->index, &pCmd->data); 3421 break; 3422 } 3423 3424 case SVGA_3D_CMD_SETLIGHTENABLED: 3425 { 3426 SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)pvCmd; 3427 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3428 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetLightEnable); 3429 3430 rc = vmsvga3dSetLightEnabled(pThisCC, pCmd->cid, pCmd->index, pCmd->enabled); 3431 break; 3432 } 3433 3434 case SVGA_3D_CMD_SETVIEWPORT: 3435 { 3436 SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)pvCmd; 3437 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3438 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetViewPort); 3439 3440 rc = vmsvga3dSetViewPort(pThisCC, pCmd->cid, &pCmd->rect); 3441 break; 3442 } 3443 3444 case SVGA_3D_CMD_SETCLIPPLANE: 3445 { 3446 SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)pvCmd; 3447 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3448 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetClipPlane); 3449 3450 rc = vmsvga3dSetClipPlane(pThisCC, pCmd->cid, pCmd->index, pCmd->plane); 3451 break; 3452 } 3453 3454 case SVGA_3D_CMD_CLEAR: 3455 { 3456 SVGA3dCmdClear *pCmd = (SVGA3dCmdClear *)pvCmd; 3457 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3458 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dClear); 3459 3460 uint32_t cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRect); 3461 rc = vmsvga3dCommandClear(pThisCC, pCmd->cid, pCmd->clearFlag, pCmd->color, pCmd->depth, pCmd->stencil, cRects, (SVGA3dRect *)(pCmd + 1)); 3462 break; 3463 } 3464 3465 case SVGA_3D_CMD_PRESENT: 3466 case SVGA_3D_CMD_PRESENT_READBACK: /** @todo SVGA_3D_CMD_PRESENT_READBACK isn't quite the same as present... */ 3467 { 3468 SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)pvCmd; 3469 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3470 if (cmdId == SVGA_3D_CMD_PRESENT) 3471 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dPresent); 3472 else 3473 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dPresentReadBack); 3474 3475 uint32_t cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyRect); 3476 3477 STAM_PROFILE_START(&pSVGAState->StatR3Cmd3dPresentProf, a); 3478 rc = vmsvga3dCommandPresent(pThis, pThisCC, pCmd->sid, cRects, (SVGA3dCopyRect *)(pCmd + 1)); 3479 STAM_PROFILE_STOP(&pSVGAState->StatR3Cmd3dPresentProf, a); 3480 break; 3481 } 3482 3483 case SVGA_3D_CMD_SHADER_DEFINE: 3484 { 3485 SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)pvCmd; 3486 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3487 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dShaderDefine); 3488 3489 uint32_t cbData = (cbCmd - sizeof(*pCmd)); 3490 rc = vmsvga3dShaderDefine(pThisCC, pCmd->cid, pCmd->shid, pCmd->type, cbData, (uint32_t *)(pCmd + 1)); 3491 break; 3492 } 3493 3494 case SVGA_3D_CMD_SHADER_DESTROY: 3495 { 3496 SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)pvCmd; 3497 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3498 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dShaderDestroy); 3499 3500 rc = vmsvga3dShaderDestroy(pThisCC, pCmd->cid, pCmd->shid, pCmd->type); 3501 break; 3502 } 3503 3504 case SVGA_3D_CMD_SET_SHADER: 3505 { 3506 SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)pvCmd; 3507 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3508 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetShader); 3509 3510 rc = vmsvga3dShaderSet(pThisCC, NULL, pCmd->cid, pCmd->type, pCmd->shid); 3511 break; 3512 } 3513 3514 case SVGA_3D_CMD_SET_SHADER_CONST: 3515 { 3516 SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)pvCmd; 3517 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3518 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetShaderConst); 3519 3520 uint32_t cRegisters = (cbCmd - sizeof(*pCmd)) / sizeof(pCmd->values) + 1; 3521 rc = vmsvga3dShaderSetConst(pThisCC, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values); 3522 break; 3523 } 3524 3525 case SVGA_3D_CMD_DRAW_PRIMITIVES: 3526 { 3527 SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)pvCmd; 3528 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3529 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dDrawPrimitives); 3530 3531 AssertBreak(pCmd->numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES); 3532 AssertBreak(pCmd->numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS); 3533 uint32_t const cbRangesAndVertexDecls = pCmd->numVertexDecls * sizeof(SVGA3dVertexDecl) 3534 + pCmd->numRanges * sizeof(SVGA3dPrimitiveRange); 3535 ASSERT_GUEST_BREAK(cbRangesAndVertexDecls <= cbCmd - sizeof(*pCmd)); 3536 3537 uint32_t cVertexDivisor = (cbCmd - sizeof(*pCmd) - cbRangesAndVertexDecls) / sizeof(uint32_t); 3538 AssertBreak(!cVertexDivisor || cVertexDivisor == pCmd->numVertexDecls); 3539 3540 RT_UNTRUSTED_VALIDATED_FENCE(); 3541 3542 SVGA3dVertexDecl *pVertexDecl = (SVGA3dVertexDecl *)(pCmd + 1); 3543 SVGA3dPrimitiveRange *pNumRange = (SVGA3dPrimitiveRange *)&pVertexDecl[pCmd->numVertexDecls]; 3544 SVGA3dVertexDivisor *pVertexDivisor = cVertexDivisor ? (SVGA3dVertexDivisor *)&pNumRange[pCmd->numRanges] : NULL; 3545 3546 STAM_PROFILE_START(&pSVGAState->StatR3Cmd3dDrawPrimitivesProf, a); 3547 rc = vmsvga3dDrawPrimitives(pThisCC, pCmd->cid, pCmd->numVertexDecls, pVertexDecl, pCmd->numRanges, 3548 pNumRange, cVertexDivisor, pVertexDivisor); 3549 STAM_PROFILE_STOP(&pSVGAState->StatR3Cmd3dDrawPrimitivesProf, a); 3550 break; 3551 } 3552 3553 case SVGA_3D_CMD_SETSCISSORRECT: 3554 { 3555 SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)pvCmd; 3556 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3557 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetScissorRect); 3558 3559 rc = vmsvga3dSetScissorRect(pThisCC, pCmd->cid, &pCmd->rect); 3560 break; 3561 } 3562 3563 case SVGA_3D_CMD_BEGIN_QUERY: 3564 { 3565 SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)pvCmd; 3566 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3567 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dBeginQuery); 3568 3569 rc = vmsvga3dQueryBegin(pThisCC, pCmd->cid, pCmd->type); 3570 break; 3571 } 3572 3573 case SVGA_3D_CMD_END_QUERY: 3574 { 3575 SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)pvCmd; 3576 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3577 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dEndQuery); 3578 3579 rc = vmsvga3dQueryEnd(pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult); 3580 break; 3581 } 3582 3583 case SVGA_3D_CMD_WAIT_FOR_QUERY: 3584 { 3585 SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)pvCmd; 3586 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3587 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dWaitForQuery); 3588 3589 rc = vmsvga3dQueryWait(pThis, pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult); 3590 break; 3591 } 3592 3593 case SVGA_3D_CMD_GENERATE_MIPMAPS: 3594 { 3595 SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)pvCmd; 3596 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 3597 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dGenerateMipmaps); 3598 3599 rc = vmsvga3dGenerateMipmaps(pThisCC, pCmd->sid, pCmd->filter); 3600 break; 3601 } 3602 3603 case SVGA_3D_CMD_ACTIVATE_SURFACE: 3604 /* context id + surface id? */ 3605 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dActivateSurface); 3606 break; 3607 case SVGA_3D_CMD_DEACTIVATE_SURFACE: 3608 /* context id + surface id? */ 3609 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dDeactivateSurface); 3610 break; 3611 3612 default: 3613 STAM_REL_COUNTER_INC(&pSVGAState->StatFifoUnkCmds); 3614 AssertMsgFailed(("cmdId=%d\n", cmdId)); 3615 break; 3616 } 3617 3618 # undef VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK 3619 return rc; 3620 } 3621 3622 3623 /* 3624 * 3625 * Handlers for FIFO commands. 3626 * 3627 * Every handler takes the following parameters: 3628 * 3629 * pThis The shared VGA/VMSVGA state. 3630 * pThisCC The VGA/VMSVGA state for ring-3. 3631 * pCmd The command data. 3632 */ 3633 3634 3635 /* SVGA_CMD_UPDATE */ 3636 static void vmsvgaR3CmdUpdate(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdUpdate const *pCmd) 3637 { 3638 RT_NOREF(pThis); 3639 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3640 3641 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdUpdate); 3642 Log(("SVGA_CMD_UPDATE %d,%d %dx%d\n", pCmd->x, pCmd->y, pCmd->width, pCmd->height)); 3643 3644 /** @todo Multiple screens? */ 3645 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 3646 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */ 3647 return; 3648 3649 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->x, pCmd->y, pCmd->width, pCmd->height); 3650 } 3651 3652 3653 /* SVGA_CMD_UPDATE_VERBOSE */ 3654 static void vmsvgaR3CmdUpdateVerbose(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdUpdateVerbose const *pCmd) 3655 { 3656 RT_NOREF(pThis); 3657 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3658 3659 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdUpdateVerbose); 3660 Log(("SVGA_CMD_UPDATE_VERBOSE %d,%d %dx%d reason %#x\n", pCmd->x, pCmd->y, pCmd->width, pCmd->height, pCmd->reason)); 3661 3662 /** @todo Multiple screens? */ 3663 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 3664 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */ 3665 return; 3666 3667 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->x, pCmd->y, pCmd->width, pCmd->height); 3668 } 3669 3670 3671 /* SVGA_CMD_RECT_FILL */ 3672 static void vmsvgaR3CmdRectFill(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectFill const *pCmd) 3673 { 3674 RT_NOREF(pThis, pCmd); 3675 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3676 3677 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectFill); 3678 Log(("SVGA_CMD_RECT_FILL %08X @ %d,%d (%dx%d)\n", pCmd->pixel, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height)); 3679 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_RECT_FILL command ignored.\n")); 3680 } 3681 3682 3683 /* SVGA_CMD_RECT_COPY */ 3684 static void vmsvgaR3CmdRectCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectCopy const *pCmd) 3685 { 3686 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3687 3688 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectCopy); 3689 Log(("SVGA_CMD_RECT_COPY %d,%d -> %d,%d %dx%d\n", pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height)); 3690 3691 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 3692 AssertPtrReturnVoid(pScreen); 3693 3694 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */ 3695 ASSERT_GUEST_RETURN_VOID(pCmd->srcX < pThis->svga.u32MaxWidth); 3696 ASSERT_GUEST_RETURN_VOID(pCmd->destX < pThis->svga.u32MaxWidth); 3697 ASSERT_GUEST_RETURN_VOID(pCmd->width < pThis->svga.u32MaxWidth); 3698 ASSERT_GUEST_RETURN_VOID(pCmd->srcY < pThis->svga.u32MaxHeight); 3699 ASSERT_GUEST_RETURN_VOID(pCmd->destY < pThis->svga.u32MaxHeight); 3700 ASSERT_GUEST_RETURN_VOID(pCmd->height < pThis->svga.u32MaxHeight); 3701 3702 vmsvgaR3RectCopy(pThisCC, pScreen, pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, 3703 pCmd->width, pCmd->height, pThis->vram_size); 3704 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height); 3705 } 3706 3707 3708 /* SVGA_CMD_RECT_ROP_COPY */ 3709 static void vmsvgaR3CmdRectRopCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectRopCopy const *pCmd) 3710 { 3711 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3712 3713 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectRopCopy); 3714 Log(("SVGA_CMD_RECT_ROP_COPY %d,%d -> %d,%d %dx%d ROP %#X\n", pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height, pCmd->rop)); 3715 3716 if (pCmd->rop != SVGA_ROP_COPY) 3717 { 3718 /* We only support the plain copy ROP which makes SVGA_CMD_RECT_ROP_COPY exactly the same 3719 * as SVGA_CMD_RECT_COPY. XFree86 4.1.0 and 4.2.0 drivers (driver version 10.4.0 and 10.7.0, 3720 * respectively) issue SVGA_CMD_RECT_ROP_COPY when SVGA_CAP_RECT_COPY is present even when 3721 * SVGA_CAP_RASTER_OP is not. However, the ROP will always be SVGA_ROP_COPY. 3722 */ 3723 LogRelMax(4, ("VMSVGA: SVGA_CMD_RECT_ROP_COPY %d,%d -> %d,%d (%dx%d) ROP %X unsupported\n", 3724 pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height, pCmd->rop)); 3725 return; 3726 } 3727 3728 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 3729 AssertPtrReturnVoid(pScreen); 3730 3731 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */ 3732 ASSERT_GUEST_RETURN_VOID(pCmd->srcX < pThis->svga.u32MaxWidth); 3733 ASSERT_GUEST_RETURN_VOID(pCmd->destX < pThis->svga.u32MaxWidth); 3734 ASSERT_GUEST_RETURN_VOID(pCmd->width < pThis->svga.u32MaxWidth); 3735 ASSERT_GUEST_RETURN_VOID(pCmd->srcY < pThis->svga.u32MaxHeight); 3736 ASSERT_GUEST_RETURN_VOID(pCmd->destY < pThis->svga.u32MaxHeight); 3737 ASSERT_GUEST_RETURN_VOID(pCmd->height < pThis->svga.u32MaxHeight); 3738 3739 vmsvgaR3RectCopy(pThisCC, pScreen, pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, 3740 pCmd->width, pCmd->height, pThis->vram_size); 3741 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height); 3742 } 3743 3744 3745 /* SVGA_CMD_DISPLAY_CURSOR */ 3746 static void vmsvgaR3CmdDisplayCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDisplayCursor const *pCmd) 3747 { 3748 RT_NOREF(pThis, pCmd); 3749 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3750 3751 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDisplayCursor); 3752 Log(("SVGA_CMD_DISPLAY_CURSOR id=%d state=%d\n", pCmd->id, pCmd->state)); 3753 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_DISPLAY_CURSOR command ignored.\n")); 3754 } 3755 3756 3757 /* SVGA_CMD_MOVE_CURSOR */ 3758 static void vmsvgaR3CmdMoveCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdMoveCursor const *pCmd) 3759 { 3760 RT_NOREF(pThis, pCmd); 3761 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3762 3763 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdMoveCursor); 3764 Log(("SVGA_CMD_MOVE_CURSOR to %d,%d\n", pCmd->pos.x, pCmd->pos.y)); 3765 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_MOVE_CURSOR command ignored.\n")); 3766 } 3767 3768 3769 /* SVGA_CMD_DEFINE_CURSOR */ 3770 static void vmsvgaR3CmdDefineCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineCursor const *pCmd) 3771 { 3772 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 3773 3774 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineCursor); 3775 Log(("SVGA_CMD_DEFINE_CURSOR id=%d size (%dx%d) hotspot (%d,%d) andMaskDepth=%d xorMaskDepth=%d\n", 3776 pCmd->id, pCmd->width, pCmd->height, pCmd->hotspotX, pCmd->hotspotY, pCmd->andMaskDepth, pCmd->xorMaskDepth)); 3777 3778 ASSERT_GUEST_RETURN_VOID(pCmd->height < 2048 && pCmd->width < 2048); 3779 ASSERT_GUEST_RETURN_VOID(pCmd->andMaskDepth <= 32); 3780 ASSERT_GUEST_RETURN_VOID(pCmd->xorMaskDepth <= 32); 3781 RT_UNTRUSTED_VALIDATED_FENCE(); 3782 3783 uint32_t const cbSrcAndLine = RT_ALIGN_32(pCmd->width * (pCmd->andMaskDepth + (pCmd->andMaskDepth == 15)), 32) / 8; 3784 uint32_t const cbSrcAndMask = cbSrcAndLine * pCmd->height; 3785 uint32_t const cbSrcXorLine = RT_ALIGN_32(pCmd->width * (pCmd->xorMaskDepth + (pCmd->xorMaskDepth == 15)), 32) / 8; 3786 3787 uint8_t const *pbSrcAndMask = (uint8_t const *)(pCmd + 1); 3788 uint8_t const *pbSrcXorMask = (uint8_t const *)(pCmd + 1) + cbSrcAndMask; 3789 3790 uint32_t const cx = pCmd->width; 3791 uint32_t const cy = pCmd->height; 2864 3792 2865 3793 /* … … 2879 3807 uint8_t *pbDst = pbCopy; 2880 3808 uint8_t const *pbSrc = pbSrcAndMask; 2881 switch (pC ursor->andMaskDepth)3809 switch (pCmd->andMaskDepth) 2882 3810 { 2883 3811 case 1: … … 3007 3935 uint32_t *pu32Dst = (uint32_t *)(pbCopy + RT_ALIGN_32(cbDstAndMask, 4)); 3008 3936 pbSrc = pbSrcXorMask; 3009 switch (pC ursor->xorMaskDepth)3937 switch (pCmd->xorMaskDepth) 3010 3938 { 3011 3939 case 1: … … 3087 4015 * Pass it to the frontend/whatever. 3088 4016 */ 3089 vmsvgaR3InstallNewCursor(pThisCC, pSVGAState, false /*fAlpha*/, pCursor->hotspotX, pCursor->hotspotY, cx, cy, pbCopy, cbCopy); 4017 vmsvgaR3InstallNewCursor(pThisCC, pSvgaR3State, false /*fAlpha*/, pCmd->hotspotX, pCmd->hotspotY, 4018 cx, cy, pbCopy, cbCopy); 4019 } 4020 4021 4022 /* SVGA_CMD_DEFINE_ALPHA_CURSOR */ 4023 static void vmsvgaR3CmdDefineAlphaCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineAlphaCursor const *pCmd) 4024 { 4025 RT_NOREF(pThis); 4026 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4027 4028 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineAlphaCursor); 4029 Log(("VMSVGA cmd: SVGA_CMD_DEFINE_ALPHA_CURSOR id=%d size (%dx%d) hotspot (%d,%d)\n", pCmd->id, pCmd->width, pCmd->height, pCmd->hotspotX, pCmd->hotspotY)); 4030 4031 /* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */ 4032 ASSERT_GUEST_RETURN_VOID(pCmd->height < 2048 && pCmd->width < 2048); 4033 RT_UNTRUSTED_VALIDATED_FENCE(); 4034 4035 /* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */ 4036 uint32_t cbAndMask = (pCmd->width + 7) / 8 * pCmd->height; /* size of the AND mask */ 4037 cbAndMask = ((cbAndMask + 3) & ~3); /* + gap for alignment */ 4038 uint32_t cbXorMask = pCmd->width * sizeof(uint32_t) * pCmd->height; /* + size of the XOR mask (32-bit BRGA format) */ 4039 uint32_t cbCursorShape = cbAndMask + cbXorMask; 4040 4041 uint8_t *pCursorCopy = (uint8_t *)RTMemAlloc(cbCursorShape); 4042 AssertPtrReturnVoid(pCursorCopy); 4043 4044 /* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */ 4045 memset(pCursorCopy, 0xff, cbAndMask); 4046 /* Colour data */ 4047 memcpy(pCursorCopy + cbAndMask, pCmd + 1, cbXorMask); 4048 4049 vmsvgaR3InstallNewCursor(pThisCC, pSvgaR3State, true /*fAlpha*/, pCmd->hotspotX, pCmd->hotspotY, 4050 pCmd->width, pCmd->height, pCursorCopy, cbCursorShape); 4051 } 4052 4053 4054 /* SVGA_CMD_ESCAPE */ 4055 static void vmsvgaR3CmdEscape(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdEscape const *pCmd) 4056 { 4057 RT_NOREF(pThis); 4058 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4059 4060 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdEscape); 4061 4062 if (pCmd->nsid == SVGA_ESCAPE_NSID_VMWARE) 4063 { 4064 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(uint32_t)); 4065 RT_UNTRUSTED_VALIDATED_FENCE(); 4066 4067 uint32_t const cmd = *(uint32_t *)(pCmd + 1); 4068 Log(("SVGA_CMD_ESCAPE (%#x %#x) VMWARE cmd=%#x\n", pCmd->nsid, pCmd->size, cmd)); 4069 4070 switch (cmd) 4071 { 4072 case SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: 4073 { 4074 SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pCmd + 1); 4075 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(pVideoCmd->header)); 4076 RT_UNTRUSTED_VALIDATED_FENCE(); 4077 4078 uint32_t const cRegs = (pCmd->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]); 4079 4080 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: stream %#x\n", pVideoCmd->header.streamId)); 4081 for (uint32_t iReg = 0; iReg < cRegs; iReg++) 4082 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: reg %#x val %#x\n", pVideoCmd->items[iReg].registerId, pVideoCmd->items[iReg].value)); 4083 RT_NOREF_PV(pVideoCmd); 4084 break; 4085 } 4086 4087 case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: 4088 { 4089 SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pCmd + 1); 4090 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(*pVideoCmd)); 4091 Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %#x\n", pVideoCmd->streamId)); 4092 RT_NOREF_PV(pVideoCmd); 4093 break; 4094 } 4095 4096 default: 4097 Log(("SVGA_CMD_ESCAPE: Unknown vmware escape: %#x\n", cmd)); 4098 break; 4099 } 4100 } 4101 else 4102 Log(("SVGA_CMD_ESCAPE %#x %#x\n", pCmd->nsid, pCmd->size)); 4103 } 4104 4105 4106 /* SVGA_CMD_DEFINE_SCREEN */ 4107 static void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineScreen const *pCmd) 4108 { 4109 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4110 4111 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineScreen); 4112 Log(("SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d) %d:0x%x 0x%x\n", 4113 pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y, 4114 pCmd->screen.backingStore.ptr.gmrId, pCmd->screen.backingStore.ptr.offset, pCmd->screen.backingStore.pitch)); 4115 4116 uint32_t const idScreen = pCmd->screen.id; 4117 ASSERT_GUEST_RETURN_VOID(idScreen < RT_ELEMENTS(pSvgaR3State->aScreens)); 4118 4119 uint32_t const uWidth = pCmd->screen.size.width; 4120 ASSERT_GUEST_RETURN_VOID(uWidth <= pThis->svga.u32MaxWidth); 4121 4122 uint32_t const uHeight = pCmd->screen.size.height; 4123 ASSERT_GUEST_RETURN_VOID(uHeight <= pThis->svga.u32MaxHeight); 4124 4125 uint32_t const cbWidth = uWidth * ((32 + 7) / 8); /** @todo 32? */ 4126 uint32_t const cbPitch = pCmd->screen.backingStore.pitch ? pCmd->screen.backingStore.pitch : cbWidth; 4127 ASSERT_GUEST_RETURN_VOID(cbWidth <= cbPitch); 4128 4129 uint32_t const uScreenOffset = pCmd->screen.backingStore.ptr.offset; 4130 ASSERT_GUEST_RETURN_VOID(uScreenOffset < pThis->vram_size); 4131 4132 uint32_t const cbVram = pThis->vram_size - uScreenOffset; 4133 /* If we have a not zero pitch, then height can't exceed the available VRAM. */ 4134 ASSERT_GUEST_RETURN_VOID( (uHeight == 0 && cbPitch == 0) 4135 || (cbPitch > 0 && uHeight <= cbVram / cbPitch)); 4136 RT_UNTRUSTED_VALIDATED_FENCE(); 4137 4138 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen]; 4139 pScreen->fDefined = true; 4140 pScreen->fModified = true; 4141 pScreen->fuScreen = pCmd->screen.flags; 4142 pScreen->idScreen = idScreen; 4143 if (!RT_BOOL(pCmd->screen.flags & (SVGA_SCREEN_DEACTIVATE | SVGA_SCREEN_BLANKING))) 4144 { 4145 /* Not blanked. */ 4146 ASSERT_GUEST_RETURN_VOID(uWidth > 0 && uHeight > 0); 4147 RT_UNTRUSTED_VALIDATED_FENCE(); 4148 4149 pScreen->xOrigin = pCmd->screen.root.x; 4150 pScreen->yOrigin = pCmd->screen.root.y; 4151 pScreen->cWidth = uWidth; 4152 pScreen->cHeight = uHeight; 4153 pScreen->offVRAM = uScreenOffset; 4154 pScreen->cbPitch = cbPitch; 4155 pScreen->cBpp = 32; 4156 } 4157 else 4158 { 4159 /* Screen blanked. Keep old values. */ 4160 } 4161 4162 pThis->svga.fGFBRegisters = false; 4163 vmsvgaR3ChangeMode(pThis, pThisCC); 4164 4165 # ifdef VBOX_WITH_VMSVGA3D 4166 if (RT_LIKELY(pThis->svga.f3DEnabled)) 4167 vmsvga3dDefineScreen(pThis, pThisCC, pScreen); 4168 # endif 4169 } 4170 4171 4172 /* SVGA_CMD_DESTROY_SCREEN */ 4173 static void vmsvgaR3CmdDestroyScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDestroyScreen const *pCmd) 4174 { 4175 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4176 4177 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDestroyScreen); 4178 Log(("SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId)); 4179 4180 uint32_t const idScreen = pCmd->screenId; 4181 ASSERT_GUEST_RETURN_VOID(idScreen < RT_ELEMENTS(pSvgaR3State->aScreens)); 4182 RT_UNTRUSTED_VALIDATED_FENCE(); 4183 4184 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen]; 4185 pScreen->fModified = true; 4186 pScreen->fDefined = false; 4187 pScreen->idScreen = idScreen; 4188 4189 # ifdef VBOX_WITH_VMSVGA3D 4190 if (RT_LIKELY(pThis->svga.f3DEnabled)) 4191 vmsvga3dDestroyScreen(pThisCC, pScreen); 4192 # endif 4193 vmsvgaR3ChangeMode(pThis, pThisCC); 4194 } 4195 4196 4197 /* SVGA_CMD_DEFINE_GMRFB */ 4198 static void vmsvgaR3CmdDefineGMRFB(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineGMRFB const *pCmd) 4199 { 4200 RT_NOREF(pThis); 4201 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4202 4203 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmrFb); 4204 Log(("SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n", 4205 pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.bitsPerPixel, pCmd->format.colorDepth)); 4206 4207 pSvgaR3State->GMRFB.ptr = pCmd->ptr; 4208 pSvgaR3State->GMRFB.bytesPerLine = pCmd->bytesPerLine; 4209 pSvgaR3State->GMRFB.format = pCmd->format; 4210 } 4211 4212 4213 /* SVGA_CMD_BLIT_GMRFB_TO_SCREEN */ 4214 static void vmsvgaR3CmdBlitGMRFBToScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdBlitGMRFBToScreen const *pCmd) 4215 { 4216 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4217 4218 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdBlitGmrFbToScreen); 4219 Log(("SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n", 4220 pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom)); 4221 4222 ASSERT_GUEST_RETURN_VOID(pCmd->destScreenId < RT_ELEMENTS(pSvgaR3State->aScreens)); 4223 RT_UNTRUSTED_VALIDATED_FENCE(); 4224 4225 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->destScreenId); 4226 AssertPtrReturnVoid(pScreen); 4227 4228 /** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp ? */ 4229 AssertReturnVoid(pSvgaR3State->GMRFB.format.bitsPerPixel == pScreen->cBpp); 4230 4231 /* Clip destRect to the screen dimensions. */ 4232 SVGASignedRect screenRect; 4233 screenRect.left = 0; 4234 screenRect.top = 0; 4235 screenRect.right = pScreen->cWidth; 4236 screenRect.bottom = pScreen->cHeight; 4237 SVGASignedRect clipRect = pCmd->destRect; 4238 vmsvgaR3ClipRect(&screenRect, &clipRect); 4239 RT_UNTRUSTED_VALIDATED_FENCE(); 4240 4241 uint32_t const width = clipRect.right - clipRect.left; 4242 uint32_t const height = clipRect.bottom - clipRect.top; 4243 4244 if ( width == 0 4245 || height == 0) 4246 return; /* Nothing to do. */ 4247 4248 int32_t const srcx = pCmd->srcOrigin.x + (clipRect.left - pCmd->destRect.left); 4249 int32_t const srcy = pCmd->srcOrigin.y + (clipRect.top - pCmd->destRect.top); 4250 4251 /* Copy the defined by GMRFB image to the screen 0 VRAM area. 4252 * Prepare parameters for vmsvgaR3GmrTransfer. 4253 */ 4254 AssertReturnVoid(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */ 4255 4256 /* Destination: host buffer which describes the screen 0 VRAM. 4257 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer. 4258 */ 4259 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM; 4260 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch : 4261 width * (RT_ALIGN(pScreen->cBpp, 8) / 8); 4262 uint32_t cbHstBuf = cbScanline * pScreen->cHeight; 4263 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM) 4264 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */ 4265 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8 4266 + cbScanline * clipRect.top; 4267 int32_t const cbHstPitch = cbScanline; 4268 4269 /* Source: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */ 4270 SVGAGuestPtr const gstPtr = pSvgaR3State->GMRFB.ptr; 4271 uint32_t const offGst = (srcx * RT_ALIGN(pSvgaR3State->GMRFB.format.bitsPerPixel, 8)) / 8 4272 + pSvgaR3State->GMRFB.bytesPerLine * srcy; 4273 int32_t const cbGstPitch = pSvgaR3State->GMRFB.bytesPerLine; 4274 4275 int rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_WRITE_HOST_VRAM, 4276 pbHstBuf, cbHstBuf, offHst, cbHstPitch, 4277 gstPtr, offGst, cbGstPitch, 4278 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height); 4279 AssertRC(rc); 4280 vmsvgaR3UpdateScreen(pThisCC, pScreen, clipRect.left, clipRect.top, width, height); 4281 } 4282 4283 4284 /* SVGA_CMD_BLIT_SCREEN_TO_GMRFB */ 4285 static void vmsvgaR3CmdBlitScreenToGMRFB(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdBlitScreenToGMRFB const *pCmd) 4286 { 4287 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4288 4289 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdBlitScreentoGmrFb); 4290 /* Note! This can fetch 3d render results as well!! */ 4291 Log(("SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n", 4292 pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom)); 4293 4294 ASSERT_GUEST_RETURN_VOID(pCmd->srcScreenId < RT_ELEMENTS(pSvgaR3State->aScreens)); 4295 RT_UNTRUSTED_VALIDATED_FENCE(); 4296 4297 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->srcScreenId); 4298 AssertPtrReturnVoid(pScreen); 4299 4300 /** @todo Support GMRFB.format.bitsPerPixel != pThis->svga.uBpp ? */ 4301 AssertReturnVoid(pSvgaR3State->GMRFB.format.bitsPerPixel == pScreen->cBpp); 4302 4303 /* Clip destRect to the screen dimensions. */ 4304 SVGASignedRect screenRect; 4305 screenRect.left = 0; 4306 screenRect.top = 0; 4307 screenRect.right = pScreen->cWidth; 4308 screenRect.bottom = pScreen->cHeight; 4309 SVGASignedRect clipRect = pCmd->srcRect; 4310 vmsvgaR3ClipRect(&screenRect, &clipRect); 4311 RT_UNTRUSTED_VALIDATED_FENCE(); 4312 4313 uint32_t const width = clipRect.right - clipRect.left; 4314 uint32_t const height = clipRect.bottom - clipRect.top; 4315 4316 if ( width == 0 4317 || height == 0) 4318 return; /* Nothing to do. */ 4319 4320 int32_t const dstx = pCmd->destOrigin.x + (clipRect.left - pCmd->srcRect.left); 4321 int32_t const dsty = pCmd->destOrigin.y + (clipRect.top - pCmd->srcRect.top); 4322 4323 /* Copy the defined by GMRFB image to the screen 0 VRAM area. 4324 * Prepare parameters for vmsvgaR3GmrTransfer. 4325 */ 4326 AssertReturnVoid(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */ 4327 4328 /* Source: host buffer which describes the screen 0 VRAM. 4329 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer. 4330 */ 4331 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM; 4332 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch : 4333 width * (RT_ALIGN(pScreen->cBpp, 8) / 8); 4334 uint32_t cbHstBuf = cbScanline * pScreen->cHeight; 4335 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM) 4336 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */ 4337 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8 4338 + cbScanline * clipRect.top; 4339 int32_t const cbHstPitch = cbScanline; 4340 4341 /* Destination: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */ 4342 SVGAGuestPtr const gstPtr = pSvgaR3State->GMRFB.ptr; 4343 uint32_t const offGst = (dstx * RT_ALIGN(pSvgaR3State->GMRFB.format.bitsPerPixel, 8)) / 8 4344 + pSvgaR3State->GMRFB.bytesPerLine * dsty; 4345 int32_t const cbGstPitch = pSvgaR3State->GMRFB.bytesPerLine; 4346 4347 int rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_READ_HOST_VRAM, 4348 pbHstBuf, cbHstBuf, offHst, cbHstPitch, 4349 gstPtr, offGst, cbGstPitch, 4350 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height); 4351 AssertRC(rc); 4352 } 4353 4354 4355 /* SVGA_CMD_ANNOTATION_FILL */ 4356 static void vmsvgaR3CmdAnnotationFill(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdAnnotationFill const *pCmd) 4357 { 4358 RT_NOREF(pThis); 4359 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4360 4361 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdAnnotationFill); 4362 Log(("SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.r, pCmd->color.g, pCmd->color.b)); 4363 4364 pSvgaR3State->colorAnnotation = pCmd->color; 4365 } 4366 4367 4368 /* SVGA_CMD_ANNOTATION_COPY */ 4369 static void vmsvgaR3CmdAnnotationCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdAnnotationCopy const *pCmd) 4370 { 4371 RT_NOREF(pThis, pCmd); 4372 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4373 4374 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdAnnotationCopy); 4375 Log(("SVGA_CMD_ANNOTATION_COPY srcOrigin %d,%d, srcScreenId %u\n", pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->srcScreenId)); 4376 4377 AssertFailed(); 4378 } 4379 4380 4381 # ifdef VBOX_WITH_VMSVGA3D 4382 /* SVGA_CMD_DEFINE_GMR2 */ 4383 static void vmsvgaR3CmdDefineGMR2(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineGMR2 const *pCmd) 4384 { 4385 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4386 4387 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2); 4388 Log(("SVGA_CMD_DEFINE_GMR2 id=%#x %#x pages\n", pCmd->gmrId, pCmd->numPages)); 4389 4390 /* Validate current GMR id. */ 4391 ASSERT_GUEST_RETURN_VOID(pCmd->gmrId < pThis->svga.cGMR); 4392 ASSERT_GUEST_RETURN_VOID(pCmd->numPages <= VMSVGA_MAX_GMR_PAGES); 4393 RT_UNTRUSTED_VALIDATED_FENCE(); 4394 4395 if (!pCmd->numPages) 4396 { 4397 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2Free); 4398 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId); 4399 } 4400 else 4401 { 4402 PGMR pGMR = &pSvgaR3State->paGMR[pCmd->gmrId]; 4403 if (pGMR->cMaxPages) 4404 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2Modify); 4405 4406 /* Not sure if we should always free the descriptor, but for simplicity 4407 we do so if the new size is smaller than the current. */ 4408 /** @todo always free the descriptor in SVGA_CMD_DEFINE_GMR2? */ 4409 if (pGMR->cbTotal / X86_PAGE_SIZE > pGMR->cMaxPages) 4410 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId); 4411 4412 pGMR->cMaxPages = pCmd->numPages; 4413 /* The rest is done by the REMAP_GMR2 command. */ 4414 } 4415 } 4416 4417 4418 /* SVGA_CMD_REMAP_GMR2 */ 4419 static void vmsvgaR3CmdRemapGMR2(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRemapGMR2 const *pCmd) 4420 { 4421 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4422 4423 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRemapGmr2); 4424 Log(("SVGA_CMD_REMAP_GMR2 id=%#x flags=%#x offset=%#x npages=%#x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages)); 4425 4426 /* Validate current GMR id and size. */ 4427 ASSERT_GUEST_RETURN_VOID(pCmd->gmrId < pThis->svga.cGMR); 4428 RT_UNTRUSTED_VALIDATED_FENCE(); 4429 PGMR pGMR = &pSvgaR3State->paGMR[pCmd->gmrId]; 4430 ASSERT_GUEST_RETURN_VOID( (uint64_t)pCmd->offsetPages + pCmd->numPages 4431 <= RT_MIN(pGMR->cMaxPages, RT_MIN(VMSVGA_MAX_GMR_PAGES, UINT32_MAX / X86_PAGE_SIZE))); 4432 ASSERT_GUEST_RETURN_VOID(!pCmd->offsetPages || pGMR->paDesc); /** @todo */ 4433 4434 if (pCmd->numPages == 0) 4435 return; 4436 RT_UNTRUSTED_VALIDATED_FENCE(); 4437 4438 /* Calc new total page count so we can use it instead of cMaxPages for allocations below. */ 4439 uint32_t const cNewTotalPages = RT_MAX(pGMR->cbTotal >> X86_PAGE_SHIFT, pCmd->offsetPages + pCmd->numPages); 4440 4441 /* 4442 * We flatten the existing descriptors into a page array, overwrite the 4443 * pages specified in this command and then recompress the descriptor. 4444 */ 4445 /** @todo Optimize the GMR remap algorithm! */ 4446 4447 /* Save the old page descriptors as an array of page frame numbers (address >> X86_PAGE_SHIFT) */ 4448 uint64_t *paNewPage64 = NULL; 4449 if (pGMR->paDesc) 4450 { 4451 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRemapGmr2Modify); 4452 4453 paNewPage64 = (uint64_t *)RTMemAllocZ(cNewTotalPages * sizeof(uint64_t)); 4454 AssertPtrReturnVoid(paNewPage64); 4455 4456 uint32_t idxPage = 0; 4457 for (uint32_t i = 0; i < pGMR->numDescriptors; i++) 4458 for (uint32_t j = 0; j < pGMR->paDesc[i].numPages; j++) 4459 paNewPage64[idxPage++] = (pGMR->paDesc[i].GCPhys + j * X86_PAGE_SIZE) >> X86_PAGE_SHIFT; 4460 AssertReturnVoidStmt(idxPage == pGMR->cbTotal >> X86_PAGE_SHIFT, RTMemFree(paNewPage64)); 4461 RT_UNTRUSTED_VALIDATED_FENCE(); 4462 } 4463 4464 /* Free the old GMR if present. */ 4465 if (pGMR->paDesc) 4466 RTMemFree(pGMR->paDesc); 4467 4468 /* Allocate the maximum amount possible (everything non-continuous) */ 4469 PVMSVGAGMRDESCRIPTOR paDescs; 4470 pGMR->paDesc = paDescs = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(cNewTotalPages * sizeof(VMSVGAGMRDESCRIPTOR)); 4471 AssertReturnVoidStmt(paDescs, RTMemFree(paNewPage64)); 4472 4473 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR) 4474 { 4475 /** @todo */ 4476 AssertFailed(); 4477 pGMR->numDescriptors = 0; 4478 } 4479 else 4480 { 4481 uint32_t *paPages32 = (uint32_t *)(pCmd + 1); 4482 uint64_t *paPages64 = (uint64_t *)(pCmd + 1); 4483 bool fGCPhys64 = RT_BOOL(pCmd->flags & SVGA_REMAP_GMR2_PPN64); 4484 4485 uint32_t cPages; 4486 if (paNewPage64) 4487 { 4488 /* Overwrite the old page array with the new page values. */ 4489 if (fGCPhys64) 4490 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++) 4491 paNewPage64[i] = paPages64[i - pCmd->offsetPages]; 4492 else 4493 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++) 4494 paNewPage64[i] = paPages32[i - pCmd->offsetPages]; 4495 4496 /* Use the updated page array instead of the command data. */ 4497 fGCPhys64 = true; 4498 paPages64 = paNewPage64; 4499 cPages = cNewTotalPages; 4500 } 4501 else 4502 cPages = pCmd->numPages; 4503 4504 /* The first page. */ 4505 /** @todo The 0x00000FFFFFFFFFFF mask limits to 44 bits and should not be 4506 * applied to paNewPage64. */ 4507 RTGCPHYS GCPhys; 4508 if (fGCPhys64) 4509 GCPhys = (paPages64[0] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 4510 else 4511 GCPhys = (RTGCPHYS)paPages32[0] << PAGE_SHIFT; 4512 paDescs[0].GCPhys = GCPhys; 4513 paDescs[0].numPages = 1; 4514 4515 /* Subsequent pages. */ 4516 uint32_t iDescriptor = 0; 4517 for (uint32_t i = 1; i < cPages; i++) 4518 { 4519 if (pCmd->flags & SVGA_REMAP_GMR2_PPN64) 4520 GCPhys = (paPages64[i] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 4521 else 4522 GCPhys = (RTGCPHYS)paPages32[i] << X86_PAGE_SHIFT; 4523 4524 /* Continuous physical memory? */ 4525 if (GCPhys == paDescs[iDescriptor].GCPhys + paDescs[iDescriptor].numPages * X86_PAGE_SIZE) 4526 { 4527 Assert(paDescs[iDescriptor].numPages); 4528 paDescs[iDescriptor].numPages++; 4529 Log5Func(("Page %x GCPhys=%RGp successor\n", i, GCPhys)); 4530 } 4531 else 4532 { 4533 iDescriptor++; 4534 paDescs[iDescriptor].GCPhys = GCPhys; 4535 paDescs[iDescriptor].numPages = 1; 4536 Log5Func(("Page %x GCPhys=%RGp\n", i, paDescs[iDescriptor].GCPhys)); 4537 } 4538 } 4539 4540 pGMR->cbTotal = cNewTotalPages << X86_PAGE_SHIFT; 4541 Log5Func(("Nr of descriptors %x; cbTotal=%#x\n", iDescriptor + 1, cNewTotalPages)); 4542 pGMR->numDescriptors = iDescriptor + 1; 4543 } 4544 4545 if (paNewPage64) 4546 RTMemFree(paNewPage64); 4547 } 4548 # endif // VBOX_WITH_VMSVGA3D 4549 4550 4551 /* 4552 * 4553 * Command buffer submission. 4554 * 4555 * Guest submits a buffer by writing to SVGA_REG_COMMAND_LOW register. 4556 * 4557 * EMT thread appends a command buffer to the context queue (VMSVGACMDBUFCTX::listSubmitted) 4558 * and wakes up the FIFO thread. 4559 * 4560 * FIFO thread fetches the command buffer from the queue, processes the commands and writes 4561 * the buffer header back to the guest memory. 4562 * 4563 * If buffers are preempted, then the EMT thread removes all buffers from the context queue. 4564 * 4565 */ 4566 4567 4568 /** Update a command buffer header 'status' and 'errorOffset' fields in the guest memory. 4569 * 4570 * @param pDevIns The device instance. 4571 * @param GCPhysCB Guest physical address of the command buffer header. 4572 * @param status Command buffer status (SVGA_CB_STATUS_*). 4573 * @param errorOffset Offset to the first byte of the failing command for SVGA_CB_STATUS_COMMAND_ERROR. 4574 * errorOffset is ignored if the status is not SVGA_CB_STATUS_COMMAND_ERROR. 4575 * @thread FIFO or EMT. 4576 */ 4577 static void vmsvgaR3CmdBufWriteStatus(PPDMDEVINS pDevIns, RTGCPHYS GCPhysCB, SVGACBStatus status, uint32_t errorOffset) 4578 { 4579 SVGACBHeader hdr; 4580 hdr.status = status; 4581 hdr.errorOffset = errorOffset; 4582 AssertCompile( RT_OFFSETOF(SVGACBHeader, status) == 0 4583 && RT_OFFSETOF(SVGACBHeader, errorOffset) == 4 4584 && RT_OFFSETOF(SVGACBHeader, id) == 8); 4585 size_t const cbWrite = status == SVGA_CB_STATUS_COMMAND_ERROR 4586 ? RT_UOFFSET_AFTER(SVGACBHeader, errorOffset) /* Both 'status' and 'errorOffset' fields. */ 4587 : RT_UOFFSET_AFTER(SVGACBHeader, status); /* Only 'status' field. */ 4588 PDMDevHlpPhysWrite(pDevIns, GCPhysCB, &hdr, cbWrite); 4589 } 4590 4591 4592 /** Raise an IRQ. 4593 * 4594 * @param pDevIns The device instance. 4595 * @param pThis The shared VGA/VMSVGA state. 4596 * @param fIRQ SVGA_IRQFLAG_* bits. 4597 * @thread FIFO or EMT. 4598 */ 4599 static void vmsvgaR3CmdBufRaiseIRQ(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t fIRQ) 4600 { 4601 int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VERR_IGNORED); 4602 AssertRC(rc); 4603 4604 if (pThis->svga.u32IrqMask & fIRQ) 4605 { 4606 LogFunc(("Trigger interrupt with status %#x\n", fIRQ)); 4607 ASMAtomicOrU32(&pThis->svga.u32IrqStatus, fIRQ); 4608 PDMDevHlpPCISetIrq(pDevIns, 0, 1); 4609 } 4610 4611 PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect); 4612 } 4613 4614 4615 /** Allocate a command buffer structure. 4616 * 4617 * @param pCmdBufCtx The command buffer context which must allocate the buffer. 4618 * @return Pointer to the allocated command buffer structure. 4619 */ 4620 static PVMSVGACMDBUF vmsvgaR3CmdBufAlloc(PVMSVGACMDBUFCTX pCmdBufCtx) 4621 { 4622 if (!pCmdBufCtx) 4623 return NULL; 4624 4625 PVMSVGACMDBUF pCmdBuf = (PVMSVGACMDBUF)RTMemAllocZ(sizeof(*pCmdBuf)); 4626 if (pCmdBuf) 4627 { 4628 // RT_ZERO(pCmdBuf->nodeBuffer); 4629 pCmdBuf->pCmdBufCtx = pCmdBufCtx; 4630 // pCmdBuf->GCPhysCB = 0; 4631 // RT_ZERO(pCmdBuf->hdr); 4632 // pCmdBuf->pvCommands = NULL; 4633 } 4634 4635 return pCmdBuf; 4636 } 4637 4638 4639 /** Free a command buffer structure. 4640 * 4641 * @param pCmdBuf The command buffer pointer. 4642 */ 4643 static void vmsvgaR3CmdBufFree(PVMSVGACMDBUF pCmdBuf) 4644 { 4645 if (pCmdBuf) 4646 RTMemFree(pCmdBuf->pvCommands); 4647 RTMemFree(pCmdBuf); 4648 } 4649 4650 4651 /** Initialize a command buffer context. 4652 * 4653 * @param pCmdBufCtx The command buffer context. 4654 */ 4655 static void vmsvgaR3CmdBufCtxInit(PVMSVGACMDBUFCTX pCmdBufCtx) 4656 { 4657 RTListInit(&pCmdBufCtx->listSubmitted); 4658 pCmdBufCtx->cSubmitted = 0; 4659 } 4660 4661 4662 /** Destroy a command buffer context. 4663 * 4664 * @param pCmdBufCtx The command buffer context pointer. 4665 */ 4666 static void vmsvgaR3CmdBufCtxTerm(PVMSVGACMDBUFCTX pCmdBufCtx) 4667 { 4668 if (!pCmdBufCtx) 4669 return; 4670 4671 if (pCmdBufCtx->listSubmitted.pNext) 4672 { 4673 /* If the list has been initialized. */ 4674 PVMSVGACMDBUF pIter, pNext; 4675 RTListForEachSafe(&pCmdBufCtx->listSubmitted, pIter, pNext, VMSVGACMDBUF, nodeBuffer) 4676 { 4677 RTListNodeRemove(&pIter->nodeBuffer); 4678 --pCmdBufCtx->cSubmitted; 4679 vmsvgaR3CmdBufFree(pIter); 4680 } 4681 } 4682 Assert(pCmdBufCtx->cSubmitted == 0); 4683 pCmdBufCtx->cSubmitted = 0; 4684 } 4685 4686 4687 /** Handles SVGA_DC_CMD_START_STOP_CONTEXT command. 4688 * 4689 * @param pSvgaR3State VMSVGA R3 state. 4690 * @param pCmd The command data. 4691 * @return SVGACBStatus code. 4692 * @thread EMT 4693 */ 4694 static SVGACBStatus vmsvgaR3CmdBufDCStartStop(PVMSVGAR3STATE pSvgaR3State, SVGADCCmdStartStop const *pCmd) 4695 { 4696 /* Create or destroy a regular command buffer context. */ 4697 if (pCmd->context >= RT_ELEMENTS(pSvgaR3State->apCmdBufCtxs)) 4698 return SVGA_CB_STATUS_COMMAND_ERROR; 4699 RT_UNTRUSTED_VALIDATED_FENCE(); 4700 4701 SVGACBStatus CBStatus = SVGA_CB_STATUS_COMPLETED; 4702 4703 int rc = RTCritSectEnter(&pSvgaR3State->CritSectCmdBuf); 4704 AssertRC(rc); 4705 if (pCmd->enable) 4706 { 4707 pSvgaR3State->apCmdBufCtxs[pCmd->context] = (PVMSVGACMDBUFCTX)RTMemAlloc(sizeof(VMSVGACMDBUFCTX)); 4708 if (pSvgaR3State->apCmdBufCtxs[pCmd->context]) 4709 vmsvgaR3CmdBufCtxInit(pSvgaR3State->apCmdBufCtxs[pCmd->context]); 4710 else 4711 CBStatus = SVGA_CB_STATUS_QUEUE_FULL; 4712 } 4713 else 4714 { 4715 vmsvgaR3CmdBufCtxTerm(pSvgaR3State->apCmdBufCtxs[pCmd->context]); 4716 pSvgaR3State->apCmdBufCtxs[pCmd->context] = NULL; 4717 } 4718 RTCritSectLeave(&pSvgaR3State->CritSectCmdBuf); 4719 4720 return CBStatus; 4721 } 4722 4723 4724 /** Handles SVGA_DC_CMD_PREEMPT command. 4725 * 4726 * @param pDevIns The device instance. 4727 * @param pSvgaR3State VMSVGA R3 state. 4728 * @param pCmd The command data. 4729 * @return SVGACBStatus code. 4730 * @thread EMT 4731 */ 4732 static SVGACBStatus vmsvgaR3CmdBufDCPreempt(PPDMDEVINS pDevIns, PVMSVGAR3STATE pSvgaR3State, SVGADCCmdPreempt const *pCmd) 4733 { 4734 /* Remove buffers from the processing queue of the specified context. */ 4735 if (pCmd->context >= RT_ELEMENTS(pSvgaR3State->apCmdBufCtxs)) 4736 return SVGA_CB_STATUS_COMMAND_ERROR; 4737 RT_UNTRUSTED_VALIDATED_FENCE(); 4738 4739 PVMSVGACMDBUFCTX const pCmdBufCtx = pSvgaR3State->apCmdBufCtxs[pCmd->context]; 4740 RTLISTANCHOR listPreempted; 4741 4742 int rc = RTCritSectEnter(&pSvgaR3State->CritSectCmdBuf); 4743 AssertRC(rc); 4744 if (pCmd->ignoreIDZero) 4745 { 4746 RTListInit(&listPreempted); 4747 4748 PVMSVGACMDBUF pIter, pNext; 4749 RTListForEachSafe(&pCmdBufCtx->listSubmitted, pIter, pNext, VMSVGACMDBUF, nodeBuffer) 4750 { 4751 if (pIter->hdr.id == 0) 4752 continue; 4753 4754 RTListNodeRemove(&pIter->nodeBuffer); 4755 --pCmdBufCtx->cSubmitted; 4756 RTListAppend(&listPreempted, &pIter->nodeBuffer); 4757 } 4758 } 4759 else 4760 { 4761 RTListMove(&listPreempted, &pCmdBufCtx->listSubmitted); 4762 } 4763 RTCritSectLeave(&pSvgaR3State->CritSectCmdBuf); 4764 4765 PVMSVGACMDBUF pIter, pNext; 4766 RTListForEachSafe(&listPreempted, pIter, pNext, VMSVGACMDBUF, nodeBuffer) 4767 { 4768 RTListNodeRemove(&pIter->nodeBuffer); 4769 vmsvgaR3CmdBufWriteStatus(pDevIns, pIter->GCPhysCB, SVGA_CB_STATUS_PREEMPTED, 0); 4770 vmsvgaR3CmdBufFree(pIter); 4771 } 4772 4773 return SVGA_CB_STATUS_COMPLETED; 4774 } 4775 4776 4777 /** @def VMSVGA_INC_CMD_SIZE_BREAK 4778 * Increments the size of the command cbCmd by a_cbMore. 4779 * Checks that the command buffer has at least cbCmd bytes. Will break out of the switch if it doesn't. 4780 * Used by vmsvgaR3CmdBufProcessDC and vmsvgaR3CmdBufProcessCommands. 4781 */ 4782 #define VMSVGA_INC_CMD_SIZE_BREAK(a_cbMore) \ 4783 if (1) { \ 4784 cbCmd += (a_cbMore); \ 4785 ASSERT_GUEST_MSG_STMT_BREAK(cbRemain >= cbCmd, ("size=%#x remain=%#zx\n", cbCmd, (size_t)cbRemain), CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); \ 4786 RT_UNTRUSTED_VALIDATED_FENCE(); \ 4787 } else do {} while (0) 4788 4789 4790 /** Processes Device Context command buffer. 4791 * 4792 * @param pDevIns The device instance. 4793 * @param pSvgaR3State VMSVGA R3 state. 4794 * @param pvCommands Pointer to the command buffer. 4795 * @param cbCommands Size of the command buffer. 4796 * @param poffNextCmd Where to store the offset of the first unprocessed command. 4797 * @return SVGACBStatus code. 4798 * @thread EMT 4799 */ 4800 static SVGACBStatus vmsvgaR3CmdBufProcessDC(PPDMDEVINS pDevIns, PVMSVGAR3STATE pSvgaR3State, void const *pvCommands, uint32_t cbCommands, uint32_t *poffNextCmd) 4801 { 4802 SVGACBStatus CBstatus = SVGA_CB_STATUS_COMPLETED; 4803 4804 uint8_t const *pu8Cmd = (uint8_t *)pvCommands; 4805 uint32_t cbRemain = cbCommands; 4806 while (cbRemain) 4807 { 4808 /* Command identifier is a 32 bit value. */ 4809 if (cbRemain < sizeof(uint32_t)) 4810 { 4811 CBstatus = SVGA_CB_STATUS_COMMAND_ERROR; 4812 break; 4813 } 4814 4815 /* Fetch the command id. */ 4816 uint32_t const cmdId = *(uint32_t *)pu8Cmd; 4817 uint32_t cbCmd = sizeof(uint32_t); 4818 switch (cmdId) 4819 { 4820 case SVGA_DC_CMD_NOP: 4821 { 4822 /* NOP */ 4823 break; 4824 } 4825 4826 case SVGA_DC_CMD_START_STOP_CONTEXT: 4827 { 4828 SVGADCCmdStartStop *pCmd = (SVGADCCmdStartStop *)&pu8Cmd[cbCmd]; 4829 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 4830 CBstatus = vmsvgaR3CmdBufDCStartStop(pSvgaR3State, pCmd); 4831 break; 4832 } 4833 4834 case SVGA_DC_CMD_PREEMPT: 4835 { 4836 SVGADCCmdPreempt *pCmd = (SVGADCCmdPreempt *)&pu8Cmd[cbCmd]; 4837 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 4838 CBstatus = vmsvgaR3CmdBufDCPreempt(pDevIns, pSvgaR3State, pCmd); 4839 break; 4840 } 4841 4842 default: 4843 { 4844 /* Unsupported command. */ 4845 CBstatus = SVGA_CB_STATUS_COMMAND_ERROR; 4846 break; 4847 } 4848 } 4849 4850 if (CBstatus != SVGA_CB_STATUS_COMPLETED) 4851 break; 4852 4853 pu8Cmd += cbCmd; 4854 cbRemain -= cbCmd; 4855 } 4856 4857 Assert(cbRemain <= cbCommands); 4858 *poffNextCmd = cbCommands - cbRemain; 4859 return CBstatus; 4860 } 4861 4862 4863 /** Submits a device context command buffer for synchronous processing. 4864 * 4865 * @param pDevIns The device instance. 4866 * @param pThisCC The VGA/VMSVGA state for the current context. 4867 * @param ppCmdBuf Pointer to the command buffer pointer. 4868 * The function can set the command buffer pointer to NULL to prevent deallocation by the caller. 4869 * @param poffNextCmd Where to store the offset of the first unprocessed command. 4870 * @return SVGACBStatus code. 4871 * @thread EMT 4872 */ 4873 static SVGACBStatus vmsvgaR3CmdBufSubmitDC(PPDMDEVINS pDevIns, PVGASTATECC pThisCC, PVMSVGACMDBUF *ppCmdBuf, uint32_t *poffNextCmd) 4874 { 4875 /* Synchronously process the device context commands. */ 4876 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4877 return vmsvgaR3CmdBufProcessDC(pDevIns, pSvgaR3State, (*ppCmdBuf)->pvCommands, (*ppCmdBuf)->hdr.length, poffNextCmd); 4878 } 4879 4880 /** Submits a command buffer for asynchronous processing by the FIFO thread. 4881 * 4882 * @param pDevIns The device instance. 4883 * @param pThis The shared VGA/VMSVGA state. 4884 * @param pThisCC The VGA/VMSVGA state for the current context. 4885 * @param ppCmdBuf Pointer to the command buffer pointer. 4886 * The function can set the command buffer pointer to NULL to prevent deallocation by the caller. 4887 * @return SVGACBStatus code. 4888 * @thread EMT 4889 */ 4890 static SVGACBStatus vmsvgaR3CmdBufSubmit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGACMDBUF *ppCmdBuf) 4891 { 4892 /* Command buffer submission. */ 4893 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4894 4895 SVGACBStatus CBstatus = SVGA_CB_STATUS_NONE; 4896 4897 PVMSVGACMDBUF const pCmdBuf = *ppCmdBuf; 4898 PVMSVGACMDBUFCTX const pCmdBufCtx = pCmdBuf->pCmdBufCtx; 4899 4900 int rc = RTCritSectEnter(&pSvgaR3State->CritSectCmdBuf); 4901 AssertRC(rc); 4902 4903 if (RT_LIKELY(pCmdBufCtx->cSubmitted < SVGA_CB_MAX_QUEUED_PER_CONTEXT)) 4904 { 4905 RTListAppend(&pCmdBufCtx->listSubmitted, &pCmdBuf->nodeBuffer); 4906 ++pCmdBufCtx->cSubmitted; 4907 *ppCmdBuf = NULL; /* Consume the buffer. */ 4908 ASMAtomicWriteU32(&pThisCC->svga.pSvgaR3State->fCmdBuf, 1); 4909 } 4910 else 4911 CBstatus = SVGA_CB_STATUS_QUEUE_FULL; 4912 4913 RTCritSectLeave(&pSvgaR3State->CritSectCmdBuf); 4914 4915 /* Inform the FIFO thread. */ 4916 if (*ppCmdBuf == NULL) 4917 PDMDevHlpSUPSemEventSignal(pDevIns, pThis->svga.hFIFORequestSem); 4918 4919 return CBstatus; 4920 } 4921 4922 4923 /** SVGA_REG_COMMAND_LOW write handler. 4924 * Submits a command buffer to the FIFO thread or processes a device context command. 4925 * 4926 * @param pDevIns The device instance. 4927 * @param pThis The shared VGA/VMSVGA state. 4928 * @param pThisCC The VGA/VMSVGA state for the current context. 4929 * @param GCPhysCB Guest physical address of the command buffer header. 4930 * @param CBCtx Context the command buffer is submitted to. 4931 * @thread EMT 4932 */ 4933 static void vmsvgaR3CmdBufSubmit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, RTGCPHYS GCPhysCB, SVGACBContext CBCtx) 4934 { 4935 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 4936 4937 SVGACBStatus CBstatus = SVGA_CB_STATUS_NONE; 4938 uint32_t offNextCmd = 0; 4939 uint32_t fIRQ = 0; 4940 4941 /* Get the context if the device has the capability. */ 4942 PVMSVGACMDBUFCTX pCmdBufCtx = NULL; 4943 if (pThis->svga.u32DeviceCaps & SVGA_CAP_COMMAND_BUFFERS) 4944 { 4945 if (RT_LIKELY(CBCtx < RT_ELEMENTS(pSvgaR3State->apCmdBufCtxs))) 4946 pCmdBufCtx = pSvgaR3State->apCmdBufCtxs[CBCtx]; 4947 else if (CBCtx == SVGA_CB_CONTEXT_DEVICE) 4948 pCmdBufCtx = &pSvgaR3State->CmdBufCtxDC; 4949 RT_UNTRUSTED_VALIDATED_FENCE(); 4950 } 4951 4952 /* Allocate a new command buffer. */ 4953 PVMSVGACMDBUF pCmdBuf = vmsvgaR3CmdBufAlloc(pCmdBufCtx); 4954 if (RT_LIKELY(pCmdBuf)) 4955 { 4956 pCmdBuf->GCPhysCB = GCPhysCB; 4957 4958 int rc = PDMDevHlpPhysRead(pDevIns, GCPhysCB, &pCmdBuf->hdr, sizeof(pCmdBuf->hdr)); 4959 if (RT_SUCCESS(rc)) 4960 { 4961 /* Verify the command buffer header. */ 4962 if (RT_LIKELY( pCmdBuf->hdr.status == SVGA_CB_STATUS_NONE 4963 && (pCmdBuf->hdr.flags & ~(SVGA_CB_FLAG_NO_IRQ)) == 0 /* No unexpected flags. */ 4964 && pCmdBuf->hdr.length <= SVGA_CB_MAX_SIZE)) 4965 { 4966 RT_UNTRUSTED_VALIDATED_FENCE(); 4967 4968 /* Read the command buffer content. */ 4969 pCmdBuf->pvCommands = RTMemAlloc(pCmdBuf->hdr.length); 4970 if (pCmdBuf->pvCommands) 4971 { 4972 RTGCPHYS const GCPhysCmd = (RTGCPHYS)pCmdBuf->hdr.ptr.pa; 4973 rc = PDMDevHlpPhysRead(pDevIns, GCPhysCmd, pCmdBuf->pvCommands, pCmdBuf->hdr.length); 4974 if (RT_SUCCESS(rc)) 4975 { 4976 /* Submit the buffer. Device context buffers will be processed synchronously. */ 4977 if (RT_LIKELY(CBCtx < RT_ELEMENTS(pSvgaR3State->apCmdBufCtxs))) 4978 /* This usually processes the CB async and sets pCmbBuf to NULL. */ 4979 CBstatus = vmsvgaR3CmdBufSubmit(pDevIns, pThis, pThisCC, &pCmdBuf); 4980 else 4981 CBstatus = vmsvgaR3CmdBufSubmitDC(pDevIns, pThisCC, &pCmdBuf, &offNextCmd); 4982 } 4983 else 4984 { 4985 ASSERT_GUEST_MSG_FAILED(("Failed to read commands at %RGp\n", GCPhysCmd)); 4986 CBstatus = SVGA_CB_STATUS_CB_HEADER_ERROR; 4987 fIRQ = SVGA_IRQFLAG_ERROR | SVGA_IRQFLAG_COMMAND_BUFFER; 4988 } 4989 } 4990 else 4991 { 4992 /* No memory for commands. */ 4993 CBstatus = SVGA_CB_STATUS_QUEUE_FULL; 4994 } 4995 } 4996 else 4997 { 4998 ASSERT_GUEST_MSG_FAILED(("Invalid buffer header\n")); 4999 CBstatus = SVGA_CB_STATUS_CB_HEADER_ERROR; 5000 fIRQ = SVGA_IRQFLAG_ERROR | SVGA_IRQFLAG_COMMAND_BUFFER; 5001 } 5002 } 5003 else 5004 { 5005 LogFunc(("Failed to read buffer header at %RGp\n", GCPhysCB)); 5006 ASSERT_GUEST_FAILED(); 5007 /* Do not attempt to write the status. */ 5008 } 5009 5010 /* Free the buffer if pfnCmdBufSubmit did not consume it. */ 5011 vmsvgaR3CmdBufFree(pCmdBuf); 5012 } 5013 else 5014 { 5015 LogFunc(("Can't allocate buffer for context id %#x\n", CBCtx)); 5016 ASSERT_GUEST_FAILED(); 5017 CBstatus = SVGA_CB_STATUS_QUEUE_FULL; 5018 } 5019 5020 if (CBstatus != SVGA_CB_STATUS_NONE) 5021 { 5022 LogFunc(("Write status %#x, offNextCmd %#x (of %#x), fIRQ %#x\n", CBstatus, offNextCmd, pCmdBuf->hdr.length, fIRQ)); 5023 vmsvgaR3CmdBufWriteStatus(pDevIns, GCPhysCB, CBstatus, offNextCmd); 5024 if (fIRQ) 5025 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, fIRQ); 5026 } 5027 } 5028 5029 5030 /** Checks if there are some buffers to be processed. 5031 * 5032 * @param pThisCC The VGA/VMSVGA state for the current context. 5033 * @return true if buffers must be processed. 5034 * @thread FIFO 5035 */ 5036 static bool vmsvgaR3CmdBufHasWork(PVGASTATECC pThisCC) 5037 { 5038 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 5039 return RT_BOOL(ASMAtomicReadU32(&pSvgaR3State->fCmdBuf)); 5040 } 5041 5042 5043 /** Processes a command buffer. 5044 * 5045 * @param pDevIns The device instance. 5046 * @param pThis The shared VGA/VMSVGA state. 5047 * @param pThisCC The VGA/VMSVGA state for the current context. 5048 * @param pvCommands Pointer to the command buffer. 5049 * @param cbCommands Size of the command buffer. 5050 * @param poffNextCmd Where to store the offset of the first unprocessed command. 5051 * @return SVGACBStatus code. 5052 * @thread FIFO 5053 */ 5054 static SVGACBStatus vmsvgaR3CmdBufProcessCommands(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, void const *pvCommands, uint32_t cbCommands, uint32_t *poffNextCmd) 5055 { 5056 SVGACBStatus CBstatus = SVGA_CB_STATUS_COMPLETED; 5057 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 5058 5059 uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO = pThisCC->svga.pau32FIFO; 5060 5061 uint8_t const *pu8Cmd = (uint8_t *)pvCommands; 5062 uint32_t cbRemain = cbCommands; 5063 while (cbRemain) 5064 { 5065 /* Command identifier is a 32 bit value. */ 5066 if (cbRemain < sizeof(uint32_t)) 5067 { 5068 CBstatus = SVGA_CB_STATUS_COMMAND_ERROR; 5069 break; 5070 } 5071 5072 /* Fetch the command id. 5073 * 'cmdId' is actually a SVGAFifoCmdId. It is treated as uint32_t in order to avoid a compiler 5074 * warning. Because we support some obsolete and deprecated commands, which are not included in 5075 * the SVGAFifoCmdId enum in the VMSVGA headers anymore. 5076 */ 5077 uint32_t const cmdId = *(uint32_t *)pu8Cmd; 5078 uint32_t cbCmd = sizeof(uint32_t); 5079 5080 LogFlowFunc(("%s %d\n", vmsvgaR3FifoCmdToString(cmdId), cmdId)); 5081 5082 /* At the end of the switch cbCmd is equal to the total length of the command including the cmdId. 5083 * I.e. pu8Cmd + cbCmd must point to the next command. 5084 * However if CBstatus is set to anything but SVGA_CB_STATUS_COMPLETED in the switch, then 5085 * the cbCmd value is ignored (and pu8Cmd still points to the failed command). 5086 */ 5087 /** @todo This code is very similar to the FIFO loop command processing. Think about merging. */ 5088 switch (cmdId) 5089 { 5090 case SVGA_CMD_INVALID_CMD: 5091 { 5092 /* Nothing to do. */ 5093 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdInvalidCmd); 5094 break; 5095 } 5096 5097 case SVGA_CMD_FENCE: 5098 { 5099 SVGAFifoCmdFence *pCmd = (SVGAFifoCmdFence *)&pu8Cmd[cbCmd]; 5100 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5101 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdFence); 5102 Log(("SVGA_CMD_FENCE %#x\n", pCmd->fence)); 5103 5104 uint32_t const offFifoMin = pFIFO[SVGA_FIFO_MIN]; 5105 if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin)) 5106 { 5107 pFIFO[SVGA_FIFO_FENCE] = pCmd->fence; 5108 5109 uint32_t u32IrqStatus = 0; 5110 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE) 5111 { 5112 Log(("any fence irq\n")); 5113 u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE; 5114 } 5115 else if ( VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin) 5116 && (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL) 5117 && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmd->fence) 5118 { 5119 Log(("fence goal reached irq (fence=%x)\n", pCmd->fence)); 5120 u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL; 5121 } 5122 5123 if (u32IrqStatus) 5124 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, u32IrqStatus); 5125 } 5126 else 5127 Log(("SVGA_CMD_FENCE is bogus when offFifoMin is %#x!\n", offFifoMin)); 5128 break; 5129 } 5130 5131 case SVGA_CMD_UPDATE: 5132 { 5133 SVGAFifoCmdUpdate *pCmd = (SVGAFifoCmdUpdate *)&pu8Cmd[cbCmd]; 5134 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5135 vmsvgaR3CmdUpdate(pThis, pThisCC, pCmd); 5136 break; 5137 } 5138 5139 case SVGA_CMD_UPDATE_VERBOSE: 5140 { 5141 SVGAFifoCmdUpdateVerbose *pCmd = (SVGAFifoCmdUpdateVerbose *)&pu8Cmd[cbCmd]; 5142 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5143 vmsvgaR3CmdUpdateVerbose(pThis, pThisCC, pCmd); 5144 break; 5145 } 5146 5147 case SVGA_CMD_DEFINE_CURSOR: 5148 { 5149 /* Followed by bitmap data. */ 5150 SVGAFifoCmdDefineCursor *pCmd = (SVGAFifoCmdDefineCursor *)&pu8Cmd[cbCmd]; 5151 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5152 5153 /* Figure out the size of the bitmap data. */ 5154 ASSERT_GUEST_STMT_BREAK(pCmd->height < 2048 && pCmd->width < 2048, CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5155 ASSERT_GUEST_STMT_BREAK(pCmd->andMaskDepth <= 32, CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5156 ASSERT_GUEST_STMT_BREAK(pCmd->xorMaskDepth <= 32, CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5157 RT_UNTRUSTED_VALIDATED_FENCE(); 5158 5159 uint32_t const cbAndLine = RT_ALIGN_32(pCmd->width * (pCmd->andMaskDepth + (pCmd->andMaskDepth == 15)), 32) / 8; 5160 uint32_t const cbAndMask = cbAndLine * pCmd->height; 5161 uint32_t const cbXorLine = RT_ALIGN_32(pCmd->width * (pCmd->xorMaskDepth + (pCmd->xorMaskDepth == 15)), 32) / 8; 5162 uint32_t const cbXorMask = cbXorLine * pCmd->height; 5163 5164 VMSVGA_INC_CMD_SIZE_BREAK(cbAndMask + cbXorMask); 5165 vmsvgaR3CmdDefineCursor(pThis, pThisCC, pCmd); 5166 break; 5167 } 5168 5169 case SVGA_CMD_DEFINE_ALPHA_CURSOR: 5170 { 5171 /* Followed by bitmap data. */ 5172 SVGAFifoCmdDefineAlphaCursor *pCmd = (SVGAFifoCmdDefineAlphaCursor *)&pu8Cmd[cbCmd]; 5173 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5174 5175 /* Figure out the size of the bitmap data. */ 5176 ASSERT_GUEST_STMT_BREAK(pCmd->height < 2048 && pCmd->width < 2048, CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5177 5178 VMSVGA_INC_CMD_SIZE_BREAK(pCmd->width * pCmd->height * sizeof(uint32_t)); /* 32-bit BRGA format */ 5179 vmsvgaR3CmdDefineAlphaCursor(pThis, pThisCC, pCmd); 5180 break; 5181 } 5182 5183 case SVGA_CMD_MOVE_CURSOR: 5184 { 5185 /* Deprecated; there should be no driver which *requires* this command. However, if 5186 * we do ecncounter this command, it might be useful to not get the FIFO completely out of 5187 * alignment. 5188 * May be issued by guest if SVGA_CAP_CURSOR_BYPASS is missing. 5189 */ 5190 SVGAFifoCmdMoveCursor *pCmd = (SVGAFifoCmdMoveCursor *)&pu8Cmd[cbCmd]; 5191 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5192 vmsvgaR3CmdMoveCursor(pThis, pThisCC, pCmd); 5193 break; 5194 } 5195 5196 case SVGA_CMD_DISPLAY_CURSOR: 5197 { 5198 /* Deprecated; there should be no driver which *requires* this command. However, if 5199 * we do ecncounter this command, it might be useful to not get the FIFO completely out of 5200 * alignment. 5201 * May be issued by guest if SVGA_CAP_CURSOR_BYPASS is missing. 5202 */ 5203 SVGAFifoCmdDisplayCursor *pCmd = (SVGAFifoCmdDisplayCursor *)&pu8Cmd[cbCmd]; 5204 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5205 vmsvgaR3CmdDisplayCursor(pThis, pThisCC, pCmd); 5206 break; 5207 } 5208 5209 case SVGA_CMD_RECT_FILL: 5210 { 5211 SVGAFifoCmdRectFill *pCmd = (SVGAFifoCmdRectFill *)&pu8Cmd[cbCmd]; 5212 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5213 vmsvgaR3CmdRectFill(pThis, pThisCC, pCmd); 5214 break; 5215 } 5216 5217 case SVGA_CMD_RECT_COPY: 5218 { 5219 SVGAFifoCmdRectCopy *pCmd = (SVGAFifoCmdRectCopy *)&pu8Cmd[cbCmd]; 5220 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5221 vmsvgaR3CmdRectCopy(pThis, pThisCC, pCmd); 5222 break; 5223 } 5224 5225 case SVGA_CMD_RECT_ROP_COPY: 5226 { 5227 SVGAFifoCmdRectRopCopy *pCmd = (SVGAFifoCmdRectRopCopy *)&pu8Cmd[cbCmd]; 5228 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5229 vmsvgaR3CmdRectRopCopy(pThis, pThisCC, pCmd); 5230 break; 5231 } 5232 5233 case SVGA_CMD_ESCAPE: 5234 { 5235 /* Followed by 'size' bytes of data. */ 5236 SVGAFifoCmdEscape *pCmd = (SVGAFifoCmdEscape *)&pu8Cmd[cbCmd]; 5237 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5238 5239 ASSERT_GUEST_STMT_BREAK(pCmd->size < pThis->svga.cbFIFO - sizeof(SVGAFifoCmdEscape), CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5240 RT_UNTRUSTED_VALIDATED_FENCE(); 5241 5242 VMSVGA_INC_CMD_SIZE_BREAK(pCmd->size); 5243 vmsvgaR3CmdEscape(pThis, pThisCC, pCmd); 5244 break; 5245 } 5246 # ifdef VBOX_WITH_VMSVGA3D 5247 case SVGA_CMD_DEFINE_GMR2: 5248 { 5249 SVGAFifoCmdDefineGMR2 *pCmd = (SVGAFifoCmdDefineGMR2 *)&pu8Cmd[cbCmd]; 5250 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5251 vmsvgaR3CmdDefineGMR2(pThis, pThisCC, pCmd); 5252 break; 5253 } 5254 5255 case SVGA_CMD_REMAP_GMR2: 5256 { 5257 /* Followed by page descriptors or guest ptr. */ 5258 SVGAFifoCmdRemapGMR2 *pCmd = (SVGAFifoCmdRemapGMR2 *)&pu8Cmd[cbCmd]; 5259 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5260 5261 /* Calculate the size of what comes after next and fetch it. */ 5262 uint32_t cbMore = 0; 5263 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR) 5264 cbMore = sizeof(SVGAGuestPtr); 5265 else 5266 { 5267 uint32_t const cbPageDesc = (pCmd->flags & SVGA_REMAP_GMR2_PPN64) ? sizeof(uint64_t) : sizeof(uint32_t); 5268 if (pCmd->flags & SVGA_REMAP_GMR2_SINGLE_PPN) 5269 { 5270 cbMore = cbPageDesc; 5271 pCmd->numPages = 1; 5272 } 5273 else 5274 { 5275 ASSERT_GUEST_STMT_BREAK(pCmd->numPages <= pThis->svga.cbFIFO / cbPageDesc, CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5276 cbMore = cbPageDesc * pCmd->numPages; 5277 } 5278 } 5279 VMSVGA_INC_CMD_SIZE_BREAK(cbMore); 5280 vmsvgaR3CmdRemapGMR2(pThis, pThisCC, pCmd); 5281 # ifdef DEBUG_GMR_ACCESS 5282 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3RegisterGmr, 2, pDevIns, pCmd->gmrId); 5283 # endif 5284 break; 5285 } 5286 # endif // VBOX_WITH_VMSVGA3D 5287 case SVGA_CMD_DEFINE_SCREEN: 5288 { 5289 /* The size of this command is specified by the guest and depends on capabilities. */ 5290 SVGAFifoCmdDefineScreen *pCmd = (SVGAFifoCmdDefineScreen *)&pu8Cmd[cbCmd]; 5291 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(pCmd->screen.structSize)); 5292 ASSERT_GUEST_STMT_BREAK(pCmd->screen.structSize < pThis->svga.cbFIFO, CBstatus = SVGA_CB_STATUS_COMMAND_ERROR); 5293 RT_UNTRUSTED_VALIDATED_FENCE(); 5294 5295 VMSVGA_INC_CMD_SIZE_BREAK(RT_MAX(sizeof(pCmd->screen.structSize), pCmd->screen.structSize) - sizeof(pCmd->screen.structSize)); 5296 vmsvgaR3CmdDefineScreen(pThis, pThisCC, pCmd); 5297 break; 5298 } 5299 5300 case SVGA_CMD_DESTROY_SCREEN: 5301 { 5302 SVGAFifoCmdDestroyScreen *pCmd = (SVGAFifoCmdDestroyScreen *)&pu8Cmd[cbCmd]; 5303 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5304 vmsvgaR3CmdDestroyScreen(pThis, pThisCC, pCmd); 5305 break; 5306 } 5307 5308 case SVGA_CMD_DEFINE_GMRFB: 5309 { 5310 SVGAFifoCmdDefineGMRFB *pCmd = (SVGAFifoCmdDefineGMRFB *)&pu8Cmd[cbCmd]; 5311 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5312 vmsvgaR3CmdDefineGMRFB(pThis, pThisCC, pCmd); 5313 break; 5314 } 5315 5316 case SVGA_CMD_BLIT_GMRFB_TO_SCREEN: 5317 { 5318 SVGAFifoCmdBlitGMRFBToScreen *pCmd = (SVGAFifoCmdBlitGMRFBToScreen *)&pu8Cmd[cbCmd]; 5319 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5320 vmsvgaR3CmdBlitGMRFBToScreen(pThis, pThisCC, pCmd); 5321 break; 5322 } 5323 5324 case SVGA_CMD_BLIT_SCREEN_TO_GMRFB: 5325 { 5326 SVGAFifoCmdBlitScreenToGMRFB *pCmd = (SVGAFifoCmdBlitScreenToGMRFB *)&pu8Cmd[cbCmd]; 5327 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5328 vmsvgaR3CmdBlitScreenToGMRFB(pThis, pThisCC, pCmd); 5329 break; 5330 } 5331 5332 case SVGA_CMD_ANNOTATION_FILL: 5333 { 5334 SVGAFifoCmdAnnotationFill *pCmd = (SVGAFifoCmdAnnotationFill *)&pu8Cmd[cbCmd]; 5335 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5336 vmsvgaR3CmdAnnotationFill(pThis, pThisCC, pCmd); 5337 break; 5338 } 5339 5340 case SVGA_CMD_ANNOTATION_COPY: 5341 { 5342 SVGAFifoCmdAnnotationCopy *pCmd = (SVGAFifoCmdAnnotationCopy *)&pu8Cmd[cbCmd]; 5343 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pCmd)); 5344 vmsvgaR3CmdAnnotationCopy(pThis, pThisCC, pCmd); 5345 break; 5346 } 5347 5348 default: 5349 { 5350 # ifdef VBOX_WITH_VMSVGA3D 5351 if ( cmdId >= SVGA_3D_CMD_BASE 5352 && cmdId < SVGA_3D_CMD_MAX) 5353 { 5354 RT_UNTRUSTED_VALIDATED_FENCE(); 5355 5356 /* All 3d commands start with a common header, which defines the identifier and the size 5357 * of the command. The identifier has been already read. Fetch the size. 5358 */ 5359 uint32_t const *pcbMore = (uint32_t const *)&pu8Cmd[cbCmd]; 5360 VMSVGA_INC_CMD_SIZE_BREAK(sizeof(*pcbMore)); 5361 VMSVGA_INC_CMD_SIZE_BREAK(*pcbMore); 5362 if (RT_LIKELY(pThis->svga.f3DEnabled)) 5363 { /* likely */ } 5364 else 5365 { 5366 LogRelMax(8, ("VMSVGA: 3D disabled, command %d skipped\n", cmdId)); 5367 break; 5368 } 5369 5370 /* Command data begins after the 32 bit command length. */ 5371 vmsvgaR3Process3dCmd(pThis, pThisCC, cmdId, *pcbMore, pcbMore + 1); 5372 } 5373 else 5374 # endif // VBOX_WITH_VMSVGA3D 5375 { 5376 /* Unsupported command. */ 5377 STAM_REL_COUNTER_INC(&pSvgaR3State->StatFifoUnkCmds); 5378 ASSERT_GUEST_MSG_FAILED(("cmdId=%d\n", cmdId)); 5379 CBstatus = SVGA_CB_STATUS_COMMAND_ERROR; 5380 break; 5381 } 5382 } 5383 } 5384 5385 if (CBstatus != SVGA_CB_STATUS_COMPLETED) 5386 break; 5387 5388 pu8Cmd += cbCmd; 5389 cbRemain -= cbCmd; 5390 } 5391 5392 Assert(cbRemain <= cbCommands); 5393 *poffNextCmd = cbCommands - cbRemain; 5394 return CBstatus; 5395 } 5396 5397 5398 /** Process command buffers. 5399 * 5400 * @param pDevIns The device instance. 5401 * @param pThis The shared VGA/VMSVGA state. 5402 * @param pThisCC The VGA/VMSVGA state for the current context. 5403 * @param pThread Handle of the FIFO thread. 5404 * @thread FIFO 5405 */ 5406 static void vmsvgaR3CmdBufProcessBuffers(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, PPDMTHREAD pThread) 5407 { 5408 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State; 5409 5410 for (;;) 5411 { 5412 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 5413 break; 5414 5415 /* See if there is a submitted buffer. */ 5416 PVMSVGACMDBUF pCmdBuf = NULL; 5417 5418 int rc = RTCritSectEnter(&pSvgaR3State->CritSectCmdBuf); 5419 AssertRC(rc); 5420 5421 /* It seems that a higher queue index has a higher priority. 5422 * See SVGACBContext in svga_reg.h from latest vmwgfx Linux driver. 5423 */ 5424 for (unsigned i = RT_ELEMENTS(pSvgaR3State->apCmdBufCtxs); i > 0; --i) 5425 { 5426 PVMSVGACMDBUFCTX pCmdBufCtx = pSvgaR3State->apCmdBufCtxs[i - 1]; 5427 if (pCmdBufCtx) 5428 { 5429 pCmdBuf = RTListRemoveFirst(&pCmdBufCtx->listSubmitted, VMSVGACMDBUF, nodeBuffer); 5430 if (pCmdBuf) 5431 { 5432 Assert(pCmdBufCtx->cSubmitted > 0); 5433 --pCmdBufCtx->cSubmitted; 5434 break; 5435 } 5436 } 5437 } 5438 5439 if (!pCmdBuf) 5440 { 5441 ASMAtomicWriteU32(&pSvgaR3State->fCmdBuf, 0); 5442 RTCritSectLeave(&pSvgaR3State->CritSectCmdBuf); 5443 break; 5444 } 5445 5446 RTCritSectLeave(&pSvgaR3State->CritSectCmdBuf); 5447 5448 SVGACBStatus CBstatus = SVGA_CB_STATUS_NONE; 5449 uint32_t offNextCmd = 0; 5450 5451 /* Process one buffer. */ 5452 CBstatus = vmsvgaR3CmdBufProcessCommands(pDevIns, pThis, pThisCC, pCmdBuf->pvCommands, pCmdBuf->hdr.length, &offNextCmd); 5453 5454 uint32_t fIRQ = 0; 5455 if (!RT_BOOL(pCmdBuf->hdr.flags & SVGA_CB_FLAG_NO_IRQ)) 5456 fIRQ |= SVGA_IRQFLAG_COMMAND_BUFFER; 5457 if (CBstatus == SVGA_CB_STATUS_COMMAND_ERROR) 5458 fIRQ |= SVGA_IRQFLAG_ERROR; 5459 5460 vmsvgaR3CmdBufWriteStatus(pDevIns, pCmdBuf->GCPhysCB, CBstatus, offNextCmd); 5461 if (fIRQ) 5462 vmsvgaR3CmdBufRaiseIRQ(pDevIns, pThis, fIRQ); 5463 5464 vmsvgaR3CmdBufFree(pCmdBuf); 5465 } 3090 5466 } 3091 5467 … … 3557 5933 * 3558 5934 * @returns true if pending work, false if not. 3559 * @param p FIFO The FIFO to examine.5935 * @param pThisCC The VGA/VMSVGA state for ring-3. 3560 5936 * @param uLastCursorCount The last cursor update counter value. 3561 5937 */ 3562 DECLINLINE(bool) vmsvgaR3FifoHasWork(uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO, uint32_t uLastCursorCount) 3563 { 5938 DECLINLINE(bool) vmsvgaR3FifoHasWork(PVGASTATECC pThisCC, uint32_t uLastCursorCount) 5939 { 5940 /* If FIFO does not exist than there is nothing to do. Command buffers also require the enabled FIFO. */ 5941 uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO = pThisCC->svga.pau32FIFO; 5942 AssertReturn(pFIFO, false); 5943 5944 if (vmsvgaR3CmdBufHasWork(pThisCC)) 5945 return true; 5946 3564 5947 if (pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP]) 3565 5948 return true; … … 3584 5967 /* Caller already checked pThis->svga.fFIFOThreadSleeping, so we only have 3585 5968 to recheck it before doing the signalling. */ 3586 uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO = pThisCC->svga.pau32FIFO; 3587 AssertReturnVoid(pFIFO); 3588 if ( vmsvgaR3FifoHasWork(pFIFO, ASMAtomicReadU32(&pThis->svga.uLastCursorUpdateCount)) 5969 if ( vmsvgaR3FifoHasWork(pThisCC, ASMAtomicReadU32(&pThis->svga.uLastCursorUpdateCount)) 3589 5970 && pThis->svga.fFIFOThreadSleeping) 3590 5971 { … … 3762 6143 */ 3763 6144 if ( fBadOrDisabledFifo 3764 || !vmsvgaR3FifoHasWork(p FIFO, pThis->svga.uLastCursorUpdateCount))6145 || !vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount)) 3765 6146 { 3766 6147 ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, true); … … 3775 6156 # endif 3776 6157 if ( !fBadOrDisabledFifo 3777 && vmsvgaR3FifoHasWork(p FIFO, pThis->svga.uLastCursorUpdateCount))6158 && vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount)) 3778 6159 rc = VINF_SUCCESS; 3779 6160 else … … 3797 6178 if (rc == VERR_TIMEOUT) 3798 6179 { 3799 if (!vmsvgaR3FifoHasWork(p FIFO, pThis->svga.uLastCursorUpdateCount))6180 if (!vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount)) 3800 6181 { 3801 6182 cMsSleep = RT_MIN(cMsSleep + cMsIncSleep, cMsMaxSleep); … … 3806 6187 Log(("vmsvgaR3FifoLoop: timeout\n")); 3807 6188 } 3808 else if (vmsvgaR3FifoHasWork(p FIFO, pThis->svga.uLastCursorUpdateCount))6189 else if (vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount)) 3809 6190 STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoWoken); 3810 6191 cMsSleep = cMsMinSleep; … … 3892 6273 3893 6274 /* 6275 * Process all submitted command buffers. 6276 */ 6277 vmsvgaR3CmdBufProcessBuffers(pDevIns, pThis, pThisCC, pThread); 6278 6279 /* 3894 6280 * Execute all queued FIFO commands. 3895 6281 * Quit if pending external command or changes in the thread state. … … 3915 6301 */ 3916 6302 /* 'enmCmdId' is actually a SVGAFifoCmdId. It is treated as uint32_t in order to avoid a compiler 3917 * warning. Because we support some obsolete and deprecated commands, which are not included in6303 * warning. Because we implement some obsolete and deprecated commands, which are not included in 3918 6304 * the SVGAFifoCmdId enum in the VMSVGA headers anymore. 3919 6305 */ 3920 6306 uint32_t const enmCmdId = pFIFO[offCurrentCmd / sizeof(uint32_t)]; 3921 6307 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 3922 LogFlow(("vmsvgaR3FifoLoop: FIFO command (iCmd=0x%x) %s 0x%x\n",6308 LogFlow(("vmsvgaR3FifoLoop: FIFO command (iCmd=0x%x) %s %d\n", 3923 6309 offCurrentCmd / sizeof(uint32_t), vmsvgaR3FifoCmdToString(enmCmdId), enmCmdId)); 3924 6310 switch (enmCmdId) … … 3936 6322 if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin)) 3937 6323 { 3938 Log(("vmsvgaR3FifoLoop: SVGA_CMD_FENCE % x\n", pCmdFence->fence));6324 Log(("vmsvgaR3FifoLoop: SVGA_CMD_FENCE %#x\n", pCmdFence->fence)); 3939 6325 pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence; 3940 6326 … … 3949 6335 && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence) 3950 6336 { 3951 Log(("vmsvgaR3FifoLoop: fence goal reached irq (fence=% x)\n", pCmdFence->fence));6337 Log(("vmsvgaR3FifoLoop: fence goal reached irq (fence=%#x)\n", pCmdFence->fence)); 3952 6338 u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL; 3953 6339 } … … 3957 6343 break; 3958 6344 } 6345 3959 6346 case SVGA_CMD_UPDATE: 6347 { 6348 SVGAFifoCmdUpdate *pCmd; 6349 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdUpdate, sizeof(*pCmd)); 6350 vmsvgaR3CmdUpdate(pThis, pThisCC, pCmd); 6351 break; 6352 } 6353 3960 6354 case SVGA_CMD_UPDATE_VERBOSE: 3961 6355 { 3962 SVGAFifoCmdUpdate *pUpdate; 3963 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pUpdate, SVGAFifoCmdUpdate, sizeof(*pUpdate)); 3964 if (enmCmdId == SVGA_CMD_UPDATE) 3965 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdUpdate); 3966 else 3967 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdUpdateVerbose); 3968 Log(("vmsvgaR3FifoLoop: UPDATE (%d,%d)(%d,%d)\n", pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height)); 3969 /** @todo Multiple screens? */ 3970 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 3971 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */ 3972 break; 3973 vmsvgaR3UpdateScreen(pThisCC, pScreen, pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height); 6356 SVGAFifoCmdUpdateVerbose *pCmd; 6357 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdUpdateVerbose, sizeof(*pCmd)); 6358 vmsvgaR3CmdUpdateVerbose(pThis, pThisCC, pCmd); 3974 6359 break; 3975 6360 } … … 3978 6363 { 3979 6364 /* Followed by bitmap data. */ 3980 SVGAFifoCmdDefineCursor *pCursor; 3981 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineCursor, sizeof(*pCursor)); 3982 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineCursor); 3983 3984 Log(("vmsvgaR3FifoLoop: CURSOR id=%d size (%d,%d) hotspot (%d,%d) andMaskDepth=%d xorMaskDepth=%d\n", 3985 pCursor->id, pCursor->width, pCursor->height, pCursor->hotspotX, pCursor->hotspotY, 3986 pCursor->andMaskDepth, pCursor->xorMaskDepth)); 3987 AssertBreak(pCursor->height < 2048 && pCursor->width < 2048); 3988 AssertBreak(pCursor->andMaskDepth <= 32); 3989 AssertBreak(pCursor->xorMaskDepth <= 32); 6365 SVGAFifoCmdDefineCursor *pCmd; 6366 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineCursor, sizeof(*pCmd)); 6367 6368 /* Figure out the size of the bitmap data. */ 6369 ASSERT_GUEST_BREAK(pCmd->height < 2048 && pCmd->width < 2048); 6370 ASSERT_GUEST_BREAK(pCmd->andMaskDepth <= 32); 6371 ASSERT_GUEST_BREAK(pCmd->xorMaskDepth <= 32); 3990 6372 RT_UNTRUSTED_VALIDATED_FENCE(); 3991 6373 3992 uint32_t c bAndLine = RT_ALIGN_32(pCursor->width * (pCursor->andMaskDepth + (pCursor->andMaskDepth == 15)), 32) / 8;3993 uint32_t c bAndMask = cbAndLine * pCursor->height;3994 uint32_t c bXorLine = RT_ALIGN_32(pCursor->width * (pCursor->xorMaskDepth + (pCursor->xorMaskDepth == 15)), 32) / 8;3995 uint32_t c bXorMask = cbXorLine * pCursor->height;3996 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineCursor, sizeof(*pCursor) + cbAndMask + cbXorMask); 3997 3998 vmsvgaR3CmdDefineCursor(pThis, pThisCC, pSVGAState, pCursor, (uint8_t const *)(pCursor + 1), cbAndLine,3999 (uint8_t const *)(pCursor + 1) + cbAndMask, cbXorLine);6374 uint32_t const cbAndLine = RT_ALIGN_32(pCmd->width * (pCmd->andMaskDepth + (pCmd->andMaskDepth == 15)), 32) / 8; 6375 uint32_t const cbAndMask = cbAndLine * pCmd->height; 6376 uint32_t const cbXorLine = RT_ALIGN_32(pCmd->width * (pCmd->xorMaskDepth + (pCmd->xorMaskDepth == 15)), 32) / 8; 6377 uint32_t const cbXorMask = cbXorLine * pCmd->height; 6378 6379 uint32_t const cbCmd = sizeof(SVGAFifoCmdDefineCursor) + cbAndMask + cbXorMask; 6380 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineCursor, cbCmd); 6381 vmsvgaR3CmdDefineCursor(pThis, pThisCC, pCmd); 4000 6382 break; 4001 6383 } … … 4004 6386 { 4005 6387 /* Followed by bitmap data. */ 4006 uint32_t cbCursorShape, cbAndMask; 4007 uint8_t *pCursorCopy; 4008 uint32_t cbCmd; 4009 4010 SVGAFifoCmdDefineAlphaCursor *pCursor; 4011 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineAlphaCursor, sizeof(*pCursor)); 4012 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineAlphaCursor); 4013 4014 Log(("vmsvgaR3FifoLoop: ALPHA_CURSOR id=%d size (%d,%d) hotspot (%d,%d)\n", pCursor->id, pCursor->width, pCursor->height, pCursor->hotspotX, pCursor->hotspotY)); 4015 4016 /* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */ 4017 AssertBreak(pCursor->height < 2048 && pCursor->width < 2048); 4018 RT_UNTRUSTED_VALIDATED_FENCE(); 4019 4020 /* Refetch the bitmap data as well. */ 4021 cbCmd = sizeof(SVGAFifoCmdDefineAlphaCursor) + pCursor->width * pCursor->height * sizeof(uint32_t) /* 32-bit BRGA format */; 4022 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineAlphaCursor, cbCmd); 4023 /** @todo Would be more efficient to copy the data straight into pCursorCopy (memcpy below). */ 4024 4025 /* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */ 4026 cbAndMask = (pCursor->width + 7) / 8 * pCursor->height; /* size of the AND mask */ 4027 cbAndMask = ((cbAndMask + 3) & ~3); /* + gap for alignment */ 4028 cbCursorShape = cbAndMask + pCursor->width * sizeof(uint32_t) * pCursor->height; /* + size of the XOR mask (32-bit BRGA format) */ 4029 4030 pCursorCopy = (uint8_t *)RTMemAlloc(cbCursorShape); 4031 AssertPtrBreak(pCursorCopy); 4032 4033 /* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */ 4034 memset(pCursorCopy, 0xff, cbAndMask); 4035 /* Colour data */ 4036 memcpy(pCursorCopy + cbAndMask, (pCursor + 1), pCursor->width * pCursor->height * sizeof(uint32_t)); 4037 4038 vmsvgaR3InstallNewCursor(pThisCC, pSVGAState, true /*fAlpha*/, pCursor->hotspotX, pCursor->hotspotY, 4039 pCursor->width, pCursor->height, pCursorCopy, cbCursorShape); 6388 SVGAFifoCmdDefineAlphaCursor *pCmd; 6389 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineAlphaCursor, sizeof(*pCmd)); 6390 6391 /* Figure out the size of the bitmap data. */ 6392 ASSERT_GUEST_BREAK(pCmd->height < 2048 && pCmd->width < 2048); 6393 6394 uint32_t const cbCmd = sizeof(SVGAFifoCmdDefineAlphaCursor) + pCmd->width * pCmd->height * sizeof(uint32_t) /* 32-bit BRGA format */; 6395 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineAlphaCursor, cbCmd); 6396 vmsvgaR3CmdDefineAlphaCursor(pThis, pThisCC, pCmd); 4040 6397 break; 4041 6398 } … … 4048 6405 * May be issued by guest if SVGA_CAP_CURSOR_BYPASS is missing. 4049 6406 */ 4050 SVGAFifoCmdMoveCursor *pMoveCursor; 4051 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pMoveCursor, SVGAFifoCmdMoveCursor, sizeof(*pMoveCursor)); 4052 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdMoveCursor); 4053 4054 Log(("vmsvgaR3FifoLoop: MOVE CURSOR to %d,%d\n", pMoveCursor->pos.x, pMoveCursor->pos.y)); 4055 LogRelMax(4, ("Unsupported SVGA_CMD_MOVE_CURSOR command ignored.\n")); 6407 SVGAFifoCmdMoveCursor *pCmd; 6408 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdMoveCursor, sizeof(*pCmd)); 6409 vmsvgaR3CmdMoveCursor(pThis, pThisCC, pCmd); 4056 6410 break; 4057 6411 } … … 4064 6418 * May be issued by guest if SVGA_CAP_CURSOR_BYPASS is missing. 4065 6419 */ 4066 SVGAFifoCmdDisplayCursor *pDisplayCursor; 4067 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pDisplayCursor, SVGAFifoCmdDisplayCursor, sizeof(*pDisplayCursor)); 4068 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDisplayCursor); 4069 4070 Log(("vmsvgaR3FifoLoop: DISPLAY CURSOR id=%d state=%d\n", pDisplayCursor->id, pDisplayCursor->state)); 4071 LogRelMax(4, ("Unsupported SVGA_CMD_DISPLAY_CURSOR command ignored.\n")); 6420 SVGAFifoCmdDisplayCursor *pCmd; 6421 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDisplayCursor, sizeof(*pCmd)); 6422 vmsvgaR3CmdDisplayCursor(pThis, pThisCC, pCmd); 4072 6423 break; 4073 6424 } … … 4075 6426 case SVGA_CMD_RECT_FILL: 4076 6427 { 4077 SVGAFifoCmdRectFill *pRectFill; 4078 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pRectFill, SVGAFifoCmdRectFill, sizeof(*pRectFill)); 4079 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRectFill); 4080 4081 Log(("vmsvgaR3FifoLoop: RECT FILL %08X @ %d,%d (%dx%d)\n", pRectFill->pixel, pRectFill->destX, pRectFill->destY, pRectFill->width, pRectFill->height)); 4082 LogRelMax(4, ("Unsupported SVGA_CMD_RECT_FILL command ignored.\n")); 6428 SVGAFifoCmdRectFill *pCmd; 6429 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRectFill, sizeof(*pCmd)); 6430 vmsvgaR3CmdRectFill(pThis, pThisCC, pCmd); 4083 6431 break; 4084 6432 } … … 4086 6434 case SVGA_CMD_RECT_COPY: 4087 6435 { 4088 SVGAFifoCmdRectCopy *pRectCopy; 4089 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pRectCopy, SVGAFifoCmdRectCopy, sizeof(*pRectCopy)); 4090 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRectCopy); 4091 4092 Log(("vmsvgaR3FifoLoop: RECT COPY %d,%d -> %d,%d (%dx%d)\n", pRectCopy->srcX, pRectCopy->srcY, pRectCopy->destX, pRectCopy->destY, pRectCopy->width, pRectCopy->height)); 4093 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 4094 AssertPtrBreak(pScreen); 4095 4096 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */ 4097 AssertBreak(pRectCopy->srcX < pThis->svga.u32MaxWidth); 4098 AssertBreak(pRectCopy->destX < pThis->svga.u32MaxWidth); 4099 AssertBreak(pRectCopy->width < pThis->svga.u32MaxWidth); 4100 AssertBreak(pRectCopy->srcY < pThis->svga.u32MaxHeight); 4101 AssertBreak(pRectCopy->destY < pThis->svga.u32MaxHeight); 4102 AssertBreak(pRectCopy->height < pThis->svga.u32MaxHeight); 4103 4104 vmsvgaR3RectCopy(pThisCC, pScreen, pRectCopy->srcX, pRectCopy->srcY, pRectCopy->destX, pRectCopy->destY, 4105 pRectCopy->width, pRectCopy->height, pThis->vram_size); 4106 vmsvgaR3UpdateScreen(pThisCC, pScreen, pRectCopy->destX, pRectCopy->destY, pRectCopy->width, pRectCopy->height); 6436 SVGAFifoCmdRectCopy *pCmd; 6437 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRectCopy, sizeof(*pCmd)); 6438 vmsvgaR3CmdRectCopy(pThis, pThisCC, pCmd); 4107 6439 break; 4108 6440 } … … 4110 6442 case SVGA_CMD_RECT_ROP_COPY: 4111 6443 { 4112 SVGAFifoCmdRectRopCopy *pRRCopy; 4113 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pRRCopy, SVGAFifoCmdRectRopCopy, sizeof(*pRRCopy)); 4114 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRectRopCopy); 4115 4116 Log(("vmsvgaR3FifoLoop: RECT ROP COPY %d,%d -> %d,%d (%dx%d) ROP %X\n", pRRCopy->srcX, pRRCopy->srcY, pRRCopy->destX, pRRCopy->destY, pRRCopy->width, pRRCopy->height, pRRCopy->rop)); 4117 if (pRRCopy->rop != SVGA_ROP_COPY) 4118 { 4119 /* We only support the plain copy ROP which makes SVGA_CMD_RECT_ROP_COPY exactly the same 4120 * as SVGA_CMD_RECT_COPY. XFree86 4.1.0 and 4.2.0 drivers (driver version 10.4.0 and 10.7.0, 4121 * respectively) issue SVGA_CMD_RECT_ROP_COPY when SVGA_CAP_RECT_COPY is present even when 4122 * SVGA_CAP_RASTER_OP is not. However, the ROP will always be SVGA_ROP_COPY. 4123 */ 4124 LogRelMax(4, ("RECT ROP COPY %d,%d -> %d,%d (%dx%d) ROP %X unsupported\n", pRRCopy->srcX, pRRCopy->srcY, pRRCopy->destX, pRRCopy->destY, pRRCopy->width, pRRCopy->height, pRRCopy->rop)); 4125 break; 4126 } 4127 4128 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0); 4129 AssertPtrBreak(pScreen); 4130 4131 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */ 4132 AssertBreak(pRRCopy->srcX < pThis->svga.u32MaxWidth); 4133 AssertBreak(pRRCopy->destX < pThis->svga.u32MaxWidth); 4134 AssertBreak(pRRCopy->width < pThis->svga.u32MaxWidth); 4135 AssertBreak(pRRCopy->srcY < pThis->svga.u32MaxHeight); 4136 AssertBreak(pRRCopy->destY < pThis->svga.u32MaxHeight); 4137 AssertBreak(pRRCopy->height < pThis->svga.u32MaxHeight); 4138 4139 vmsvgaR3RectCopy(pThisCC, pScreen, pRRCopy->srcX, pRRCopy->srcY, pRRCopy->destX, pRRCopy->destY, 4140 pRRCopy->width, pRRCopy->height, pThis->vram_size); 4141 vmsvgaR3UpdateScreen(pThisCC, pScreen, pRRCopy->destX, pRRCopy->destY, pRRCopy->width, pRRCopy->height); 6444 SVGAFifoCmdRectRopCopy *pCmd; 6445 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRectRopCopy, sizeof(*pCmd)); 6446 vmsvgaR3CmdRectRopCopy(pThis, pThisCC, pCmd); 4142 6447 break; 4143 6448 } … … 4145 6450 case SVGA_CMD_ESCAPE: 4146 6451 { 4147 /* Followed by nsize bytes of data. */ 4148 SVGAFifoCmdEscape *pEscape; 4149 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pEscape, SVGAFifoCmdEscape, sizeof(*pEscape)); 4150 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdEscape); 4151 4152 /* Refetch the command buffer with the variable data; undo size increase (ugly) */ 4153 AssertBreak(pEscape->size < pThis->svga.cbFIFO); 6452 /* Followed by 'size' bytes of data. */ 6453 SVGAFifoCmdEscape *pCmd; 6454 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdEscape, sizeof(*pCmd)); 6455 6456 ASSERT_GUEST_BREAK(pCmd->size < pThis->svga.cbFIFO - sizeof(SVGAFifoCmdEscape)); 4154 6457 RT_UNTRUSTED_VALIDATED_FENCE(); 4155 uint32_t cbCmd = sizeof(SVGAFifoCmdEscape) + pEscape->size; 4156 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pEscape, SVGAFifoCmdEscape, cbCmd); 4157 4158 if (pEscape->nsid == SVGA_ESCAPE_NSID_VMWARE) 4159 { 4160 AssertBreak(pEscape->size >= sizeof(uint32_t)); 4161 RT_UNTRUSTED_VALIDATED_FENCE(); 4162 uint32_t cmd = *(uint32_t *)(pEscape + 1); 4163 Log(("vmsvgaR3FifoLoop: ESCAPE (%x %x) VMWARE cmd=%x\n", pEscape->nsid, pEscape->size, cmd)); 4164 4165 switch (cmd) 4166 { 4167 case SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: 4168 { 4169 SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pEscape + 1); 4170 AssertBreak(pEscape->size >= sizeof(pVideoCmd->header)); 4171 uint32_t cRegs = (pEscape->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]); 4172 4173 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: stream %x\n", pVideoCmd->header.streamId)); 4174 for (uint32_t iReg = 0; iReg < cRegs; iReg++) 4175 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: reg %x val %x\n", pVideoCmd->items[iReg].registerId, pVideoCmd->items[iReg].value)); 4176 4177 RT_NOREF_PV(pVideoCmd); 4178 break; 4179 4180 } 4181 4182 case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: 4183 { 4184 SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pEscape + 1); 4185 AssertBreak(pEscape->size >= sizeof(*pVideoCmd)); 4186 Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %x\n", pVideoCmd->streamId)); 4187 RT_NOREF_PV(pVideoCmd); 4188 break; 4189 } 4190 4191 default: 4192 Log(("SVGA_CMD_ESCAPE: Unknown vmware escape: %x\n", cmd)); 4193 break; 4194 } 4195 } 4196 else 4197 Log(("vmsvgaR3FifoLoop: ESCAPE %x %x\n", pEscape->nsid, pEscape->size)); 4198 6458 6459 uint32_t const cbCmd = sizeof(SVGAFifoCmdEscape) + pCmd->size; 6460 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdEscape, cbCmd); 6461 vmsvgaR3CmdEscape(pThis, pThisCC, pCmd); 4199 6462 break; 4200 6463 } … … 4204 6467 SVGAFifoCmdDefineGMR2 *pCmd; 4205 6468 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineGMR2, sizeof(*pCmd)); 4206 Log(("vmsvgaR3FifoLoop: SVGA_CMD_DEFINE_GMR2 id=%x %x pages\n", pCmd->gmrId, pCmd->numPages)); 4207 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineGmr2); 4208 4209 /* Validate current GMR id. */ 4210 AssertBreak(pCmd->gmrId < pThis->svga.cGMR); 4211 AssertBreak(pCmd->numPages <= VMSVGA_MAX_GMR_PAGES); 4212 RT_UNTRUSTED_VALIDATED_FENCE(); 4213 4214 if (!pCmd->numPages) 4215 { 4216 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineGmr2Free); 4217 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId); 4218 } 4219 else 4220 { 4221 PGMR pGMR = &pSVGAState->paGMR[pCmd->gmrId]; 4222 if (pGMR->cMaxPages) 4223 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineGmr2Modify); 4224 4225 /* Not sure if we should always free the descriptor, but for simplicity 4226 we do so if the new size is smaller than the current. */ 4227 /** @todo always free the descriptor in SVGA_CMD_DEFINE_GMR2? */ 4228 if (pGMR->cbTotal / X86_PAGE_SIZE > pGMR->cMaxPages) 4229 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId); 4230 4231 pGMR->cMaxPages = pCmd->numPages; 4232 /* The rest is done by the REMAP_GMR2 command. */ 4233 } 6469 vmsvgaR3CmdDefineGMR2(pThis, pThisCC, pCmd); 4234 6470 break; 4235 6471 } … … 4240 6476 SVGAFifoCmdRemapGMR2 *pCmd; 4241 6477 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRemapGMR2, sizeof(*pCmd)); 4242 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRemapGmr2);4243 4244 Log(("vmsvgaR3FifoLoop: SVGA_CMD_REMAP_GMR2 id=%x flags=%x offset=%x npages=%x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));4245 AssertBreak(pCmd->gmrId < pThis->svga.cGMR);4246 RT_UNTRUSTED_VALIDATED_FENCE();4247 6478 4248 6479 /* Calculate the size of what comes after next and fetch it. */ … … 4260 6491 else 4261 6492 { 4262 A ssertBreak(pCmd->numPages <= pThis->svga.cbFIFO / cbPageDesc);6493 ASSERT_GUEST_BREAK(pCmd->numPages <= pThis->svga.cbFIFO / cbPageDesc); 4263 6494 cbCmd += cbPageDesc * pCmd->numPages; 4264 6495 } 4265 6496 } 4266 6497 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRemapGMR2, cbCmd); 4267 4268 /* Validate current GMR id and size. */ 4269 AssertBreak(pCmd->gmrId < pThis->svga.cGMR); 4270 RT_UNTRUSTED_VALIDATED_FENCE(); 4271 PGMR pGMR = &pSVGAState->paGMR[pCmd->gmrId]; 4272 AssertBreak( (uint64_t)pCmd->offsetPages + pCmd->numPages 4273 <= RT_MIN(pGMR->cMaxPages, RT_MIN(VMSVGA_MAX_GMR_PAGES, UINT32_MAX / X86_PAGE_SIZE))); 4274 AssertBreak(!pCmd->offsetPages || pGMR->paDesc); /** @todo */ 4275 4276 if (pCmd->numPages == 0) 4277 break; 4278 4279 /** @todo Move to a separate function vmsvgaGMRRemap() */ 4280 4281 /* Calc new total page count so we can use it instead of cMaxPages for allocations below. */ 4282 uint32_t const cNewTotalPages = RT_MAX(pGMR->cbTotal >> X86_PAGE_SHIFT, pCmd->offsetPages + pCmd->numPages); 4283 4284 /* 4285 * We flatten the existing descriptors into a page array, overwrite the 4286 * pages specified in this command and then recompress the descriptor. 4287 */ 4288 /** @todo Optimize the GMR remap algorithm! */ 4289 4290 /* Save the old page descriptors as an array of page frame numbers (address >> X86_PAGE_SHIFT) */ 4291 uint64_t *paNewPage64 = NULL; 4292 if (pGMR->paDesc) 4293 { 4294 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRemapGmr2Modify); 4295 4296 paNewPage64 = (uint64_t *)RTMemAllocZ(cNewTotalPages * sizeof(uint64_t)); 4297 AssertPtrBreak(paNewPage64); 4298 4299 uint32_t idxPage = 0; 4300 for (uint32_t i = 0; i < pGMR->numDescriptors; i++) 4301 for (uint32_t j = 0; j < pGMR->paDesc[i].numPages; j++) 4302 paNewPage64[idxPage++] = (pGMR->paDesc[i].GCPhys + j * X86_PAGE_SIZE) >> X86_PAGE_SHIFT; 4303 AssertBreakStmt(idxPage == pGMR->cbTotal >> X86_PAGE_SHIFT, RTMemFree(paNewPage64)); 4304 RT_UNTRUSTED_VALIDATED_FENCE(); 4305 } 4306 4307 /* Free the old GMR if present. */ 4308 if (pGMR->paDesc) 4309 RTMemFree(pGMR->paDesc); 4310 4311 /* Allocate the maximum amount possible (everything non-continuous) */ 4312 PVMSVGAGMRDESCRIPTOR paDescs; 4313 pGMR->paDesc = paDescs = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(cNewTotalPages * sizeof(VMSVGAGMRDESCRIPTOR)); 4314 AssertBreakStmt(paDescs, RTMemFree(paNewPage64)); 4315 4316 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR) 4317 { 4318 /** @todo */ 4319 AssertFailed(); 4320 pGMR->numDescriptors = 0; 4321 } 4322 else 4323 { 4324 uint32_t *paPages32 = (uint32_t *)(pCmd + 1); 4325 uint64_t *paPages64 = (uint64_t *)(pCmd + 1); 4326 bool fGCPhys64 = RT_BOOL(pCmd->flags & SVGA_REMAP_GMR2_PPN64); 4327 4328 if (paNewPage64) 4329 { 4330 /* Overwrite the old page array with the new page values. */ 4331 if (fGCPhys64) 4332 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++) 4333 paNewPage64[i] = paPages64[i - pCmd->offsetPages]; 4334 else 4335 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++) 4336 paNewPage64[i] = paPages32[i - pCmd->offsetPages]; 4337 4338 /* Use the updated page array instead of the command data. */ 4339 fGCPhys64 = true; 4340 paPages64 = paNewPage64; 4341 pCmd->numPages = cNewTotalPages; 4342 } 4343 4344 /* The first page. */ 4345 /** @todo The 0x00000FFFFFFFFFFF mask limits to 44 bits and should not be 4346 * applied to paNewPage64. */ 4347 RTGCPHYS GCPhys; 4348 if (fGCPhys64) 4349 GCPhys = (paPages64[0] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 4350 else 4351 GCPhys = (RTGCPHYS)paPages32[0] << PAGE_SHIFT; 4352 paDescs[0].GCPhys = GCPhys; 4353 paDescs[0].numPages = 1; 4354 4355 /* Subsequent pages. */ 4356 uint32_t iDescriptor = 0; 4357 for (uint32_t i = 1; i < pCmd->numPages; i++) 4358 { 4359 if (pCmd->flags & SVGA_REMAP_GMR2_PPN64) 4360 GCPhys = (paPages64[i] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */ 4361 else 4362 GCPhys = (RTGCPHYS)paPages32[i] << X86_PAGE_SHIFT; 4363 4364 /* Continuous physical memory? */ 4365 if (GCPhys == paDescs[iDescriptor].GCPhys + paDescs[iDescriptor].numPages * X86_PAGE_SIZE) 4366 { 4367 Assert(paDescs[iDescriptor].numPages); 4368 paDescs[iDescriptor].numPages++; 4369 Log5Func(("Page %x GCPhys=%RGp successor\n", i, GCPhys)); 4370 } 4371 else 4372 { 4373 iDescriptor++; 4374 paDescs[iDescriptor].GCPhys = GCPhys; 4375 paDescs[iDescriptor].numPages = 1; 4376 Log5Func(("Page %x GCPhys=%RGp\n", i, paDescs[iDescriptor].GCPhys)); 4377 } 4378 } 4379 4380 pGMR->cbTotal = cNewTotalPages << X86_PAGE_SHIFT; 4381 Log5Func(("Nr of descriptors %x; cbTotal=%#x\n", iDescriptor + 1, cNewTotalPages)); 4382 pGMR->numDescriptors = iDescriptor + 1; 4383 } 4384 4385 if (paNewPage64) 4386 RTMemFree(paNewPage64); 4387 6498 vmsvgaR3CmdRemapGMR2(pThis, pThisCC, pCmd); 4388 6499 # ifdef DEBUG_GMR_ACCESS 4389 6500 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3RegisterGmr, 2, pDevIns, pCmd->gmrId); … … 4404 6515 RT_BZERO(&pCmd->screen.id, sizeof(*pCmd) - RT_OFFSETOF(SVGAFifoCmdDefineScreen, screen.id)); 4405 6516 VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineScreen, RT_MAX(sizeof(pCmd->screen.structSize), pCmd->screen.structSize)); 4406 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineScreen); 4407 4408 LogFunc(("SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d) %d:0x%x 0x%x\n", 4409 pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y, 4410 pCmd->screen.backingStore.ptr.gmrId, pCmd->screen.backingStore.ptr.offset, pCmd->screen.backingStore.pitch)); 4411 4412 uint32_t const idScreen = pCmd->screen.id; 4413 AssertBreak(idScreen < RT_ELEMENTS(pThisCC->svga.pSvgaR3State->aScreens)); 4414 4415 uint32_t const uWidth = pCmd->screen.size.width; 4416 AssertBreak(uWidth <= pThis->svga.u32MaxWidth); 4417 4418 uint32_t const uHeight = pCmd->screen.size.height; 4419 AssertBreak(uHeight <= pThis->svga.u32MaxHeight); 4420 4421 uint32_t const cbWidth = uWidth * ((32 + 7) / 8); /** @todo 32? */ 4422 uint32_t const cbPitch = pCmd->screen.backingStore.pitch ? pCmd->screen.backingStore.pitch : cbWidth; 4423 AssertBreak(cbWidth <= cbPitch); 4424 4425 uint32_t const uScreenOffset = pCmd->screen.backingStore.ptr.offset; 4426 AssertBreak(uScreenOffset < pThis->vram_size); 4427 4428 uint32_t const cbVram = pThis->vram_size - uScreenOffset; 4429 /* If we have a not zero pitch, then height can't exceed the available VRAM. */ 4430 AssertBreak( (uHeight == 0 && cbPitch == 0) 4431 || (cbPitch > 0 && uHeight <= cbVram / cbPitch)); 4432 RT_UNTRUSTED_VALIDATED_FENCE(); 4433 4434 VMSVGASCREENOBJECT *pScreen = &pThisCC->svga.pSvgaR3State->aScreens[idScreen]; 4435 4436 bool const fBlank = RT_BOOL(pCmd->screen.flags & (SVGA_SCREEN_DEACTIVATE | SVGA_SCREEN_BLANKING)); 4437 4438 pScreen->fDefined = true; 4439 pScreen->fModified = true; 4440 pScreen->fuScreen = pCmd->screen.flags; 4441 pScreen->idScreen = idScreen; 4442 if (!fBlank) 4443 { 4444 AssertBreak(uWidth > 0 && uHeight > 0); 4445 4446 pScreen->xOrigin = pCmd->screen.root.x; 4447 pScreen->yOrigin = pCmd->screen.root.y; 4448 pScreen->cWidth = uWidth; 4449 pScreen->cHeight = uHeight; 4450 pScreen->offVRAM = uScreenOffset; 4451 pScreen->cbPitch = cbPitch; 4452 pScreen->cBpp = 32; 4453 } 4454 else 4455 { 4456 /* Keep old values. */ 4457 } 4458 4459 pThis->svga.fGFBRegisters = false; 4460 vmsvgaR3ChangeMode(pThis, pThisCC); 4461 4462 # ifdef VBOX_WITH_VMSVGA3D 4463 if (RT_LIKELY(pThis->svga.f3DEnabled)) 4464 vmsvga3dDefineScreen(pThis, pThisCC, pScreen); 4465 # endif 6517 vmsvgaR3CmdDefineScreen(pThis, pThisCC, pCmd); 4466 6518 break; 4467 6519 } … … 4471 6523 SVGAFifoCmdDestroyScreen *pCmd; 4472 6524 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDestroyScreen, sizeof(*pCmd)); 4473 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDestroyScreen); 4474 4475 Log(("vmsvgaR3FifoLoop: SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId)); 4476 4477 uint32_t const idScreen = pCmd->screenId; 4478 AssertBreak(idScreen < RT_ELEMENTS(pThisCC->svga.pSvgaR3State->aScreens)); 4479 RT_UNTRUSTED_VALIDATED_FENCE(); 4480 4481 VMSVGASCREENOBJECT *pScreen = &pThisCC->svga.pSvgaR3State->aScreens[idScreen]; 4482 pScreen->fModified = true; 4483 pScreen->fDefined = false; 4484 pScreen->idScreen = idScreen; 4485 4486 # ifdef VBOX_WITH_VMSVGA3D 4487 if (RT_LIKELY(pThis->svga.f3DEnabled)) 4488 vmsvga3dDestroyScreen(pThisCC, pScreen); 4489 # endif 4490 vmsvgaR3ChangeMode(pThis, pThisCC); 6525 vmsvgaR3CmdDestroyScreen(pThis, pThisCC, pCmd); 4491 6526 break; 4492 6527 } … … 4496 6531 SVGAFifoCmdDefineGMRFB *pCmd; 4497 6532 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineGMRFB, sizeof(*pCmd)); 4498 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdDefineGmrFb); 4499 4500 Log(("vmsvgaR3FifoLoop: SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n", pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.bitsPerPixel, pCmd->format.colorDepth)); 4501 pSVGAState->GMRFB.ptr = pCmd->ptr; 4502 pSVGAState->GMRFB.bytesPerLine = pCmd->bytesPerLine; 4503 pSVGAState->GMRFB.format = pCmd->format; 6533 vmsvgaR3CmdDefineGMRFB(pThis, pThisCC, pCmd); 4504 6534 break; 4505 6535 } … … 4509 6539 SVGAFifoCmdBlitGMRFBToScreen *pCmd; 4510 6540 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdBlitGMRFBToScreen, sizeof(*pCmd)); 4511 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdBlitGmrFbToScreen); 4512 4513 LogFunc(("SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n", 4514 pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom)); 4515 4516 AssertBreak(pCmd->destScreenId < RT_ELEMENTS(pThisCC->svga.pSvgaR3State->aScreens)); 4517 RT_UNTRUSTED_VALIDATED_FENCE(); 4518 4519 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->destScreenId); 4520 AssertPtrBreak(pScreen); 4521 4522 /** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp */ 4523 AssertBreak(pSVGAState->GMRFB.format.bitsPerPixel == pScreen->cBpp); 4524 4525 /* Clip destRect to the screen dimensions. */ 4526 SVGASignedRect screenRect; 4527 screenRect.left = 0; 4528 screenRect.top = 0; 4529 screenRect.right = pScreen->cWidth; 4530 screenRect.bottom = pScreen->cHeight; 4531 SVGASignedRect clipRect = pCmd->destRect; 4532 vmsvgaR3ClipRect(&screenRect, &clipRect); 4533 RT_UNTRUSTED_VALIDATED_FENCE(); 4534 4535 uint32_t const width = clipRect.right - clipRect.left; 4536 uint32_t const height = clipRect.bottom - clipRect.top; 4537 4538 if ( width == 0 4539 || height == 0) 4540 break; /* Nothing to do. */ 4541 4542 int32_t const srcx = pCmd->srcOrigin.x + (clipRect.left - pCmd->destRect.left); 4543 int32_t const srcy = pCmd->srcOrigin.y + (clipRect.top - pCmd->destRect.top); 4544 4545 /* Copy the defined by GMRFB image to the screen 0 VRAM area. 4546 * Prepare parameters for vmsvgaR3GmrTransfer. 4547 */ 4548 AssertBreak(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */ 4549 4550 /* Destination: host buffer which describes the screen 0 VRAM. 4551 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer. 4552 */ 4553 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM; 4554 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch : 4555 width * (RT_ALIGN(pScreen->cBpp, 8) / 8); 4556 uint32_t cbHstBuf = cbScanline * pScreen->cHeight; 4557 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM) 4558 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */ 4559 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8 4560 + cbScanline * clipRect.top; 4561 int32_t const cbHstPitch = cbScanline; 4562 4563 /* Source: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */ 4564 SVGAGuestPtr const gstPtr = pSVGAState->GMRFB.ptr; 4565 uint32_t const offGst = (srcx * RT_ALIGN(pSVGAState->GMRFB.format.bitsPerPixel, 8)) / 8 4566 + pSVGAState->GMRFB.bytesPerLine * srcy; 4567 int32_t const cbGstPitch = pSVGAState->GMRFB.bytesPerLine; 4568 4569 rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_WRITE_HOST_VRAM, 4570 pbHstBuf, cbHstBuf, offHst, cbHstPitch, 4571 gstPtr, offGst, cbGstPitch, 4572 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height); 4573 AssertRC(rc); 4574 vmsvgaR3UpdateScreen(pThisCC, pScreen, clipRect.left, clipRect.top, width, height); 6541 vmsvgaR3CmdBlitGMRFBToScreen(pThis, pThisCC, pCmd); 4575 6542 break; 4576 6543 } … … 4580 6547 SVGAFifoCmdBlitScreenToGMRFB *pCmd; 4581 6548 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdBlitScreenToGMRFB, sizeof(*pCmd)); 4582 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdBlitScreentoGmrFb); 4583 4584 /* Note! This can fetch 3d render results as well!! */ 4585 LogFunc(("SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n", 4586 pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom)); 4587 4588 AssertBreak(pCmd->srcScreenId < RT_ELEMENTS(pThisCC->svga.pSvgaR3State->aScreens)); 4589 RT_UNTRUSTED_VALIDATED_FENCE(); 4590 4591 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->srcScreenId); 4592 AssertPtrBreak(pScreen); 4593 4594 /** @todo Support GMRFB.format.bitsPerPixel != pThis->svga.uBpp? */ 4595 AssertBreak(pSVGAState->GMRFB.format.bitsPerPixel == pScreen->cBpp); 4596 4597 /* Clip destRect to the screen dimensions. */ 4598 SVGASignedRect screenRect; 4599 screenRect.left = 0; 4600 screenRect.top = 0; 4601 screenRect.right = pScreen->cWidth; 4602 screenRect.bottom = pScreen->cHeight; 4603 SVGASignedRect clipRect = pCmd->srcRect; 4604 vmsvgaR3ClipRect(&screenRect, &clipRect); 4605 RT_UNTRUSTED_VALIDATED_FENCE(); 4606 4607 uint32_t const width = clipRect.right - clipRect.left; 4608 uint32_t const height = clipRect.bottom - clipRect.top; 4609 4610 if ( width == 0 4611 || height == 0) 4612 break; /* Nothing to do. */ 4613 4614 int32_t const dstx = pCmd->destOrigin.x + (clipRect.left - pCmd->srcRect.left); 4615 int32_t const dsty = pCmd->destOrigin.y + (clipRect.top - pCmd->srcRect.top); 4616 4617 /* Copy the defined by GMRFB image to the screen 0 VRAM area. 4618 * Prepare parameters for vmsvgaR3GmrTransfer. 4619 */ 4620 AssertBreak(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */ 4621 4622 /* Source: host buffer which describes the screen 0 VRAM. 4623 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer. 4624 */ 4625 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM; 4626 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch : 4627 width * (RT_ALIGN(pScreen->cBpp, 8) / 8); 4628 uint32_t cbHstBuf = cbScanline * pScreen->cHeight; 4629 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM) 4630 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */ 4631 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8 4632 + cbScanline * clipRect.top; 4633 int32_t const cbHstPitch = cbScanline; 4634 4635 /* Destination: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */ 4636 SVGAGuestPtr const gstPtr = pSVGAState->GMRFB.ptr; 4637 uint32_t const offGst = (dstx * RT_ALIGN(pSVGAState->GMRFB.format.bitsPerPixel, 8)) / 8 4638 + pSVGAState->GMRFB.bytesPerLine * dsty; 4639 int32_t const cbGstPitch = pSVGAState->GMRFB.bytesPerLine; 4640 4641 rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_READ_HOST_VRAM, 4642 pbHstBuf, cbHstBuf, offHst, cbHstPitch, 4643 gstPtr, offGst, cbGstPitch, 4644 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height); 4645 AssertRC(rc); 6549 vmsvgaR3CmdBlitScreenToGMRFB(pThis, pThisCC, pCmd); 4646 6550 break; 4647 6551 } … … 4651 6555 SVGAFifoCmdAnnotationFill *pCmd; 4652 6556 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdAnnotationFill, sizeof(*pCmd)); 4653 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdAnnotationFill); 4654 4655 Log(("vmsvgaR3FifoLoop: SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.r, pCmd->color.g, pCmd->color.b)); 4656 pSVGAState->colorAnnotation = pCmd->color; 6557 vmsvgaR3CmdAnnotationFill(pThis, pThisCC, pCmd); 4657 6558 break; 4658 6559 } … … 4662 6563 SVGAFifoCmdAnnotationCopy *pCmd; 4663 6564 VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdAnnotationCopy, sizeof(*pCmd)); 4664 STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdAnnotationCopy); 4665 4666 Log(("vmsvgaR3FifoLoop: SVGA_CMD_ANNOTATION_COPY\n")); 4667 AssertFailed(); 6565 vmsvgaR3CmdAnnotationCopy(pThis, pThisCC, pCmd); 4668 6566 break; 4669 6567 } … … 4691 6589 else 4692 6590 { 4693 LogRelMax(8, ("VMSVGA 3d: 3D disabled, command %d skipped\n", enmCmdId));6591 LogRelMax(8, ("VMSVGA: 3D disabled, command %d skipped\n", enmCmdId)); 4694 6592 break; 4695 6593 } 4696 6594 4697 /** @def VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK 4698 * Check that the 3D command has at least a_cbMin of payload bytes after the 4699 * header. Will break out of the switch if it doesn't. 4700 */ 4701 # define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \ 4702 if (1) { \ 4703 AssertMsgBreak(cbCmd >= (a_cbMin), ("size=%#x a_cbMin=%#zx\n", cbCmd, (size_t)(a_cbMin))); \ 4704 RT_UNTRUSTED_VALIDATED_FENCE(); \ 4705 } else do {} while (0) 4706 switch ((int)enmCmdId) 4707 { 4708 case SVGA_3D_CMD_SURFACE_DEFINE: 4709 { 4710 uint32_t cMipLevels; 4711 SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)pu32Cmd; 4712 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4713 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDefine); 4714 4715 cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 4716 rc = vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0, 4717 SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1)); 4718 # ifdef DEBUG_GMR_ACCESS 4719 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis); 4720 # endif 4721 break; 4722 } 4723 4724 case SVGA_3D_CMD_SURFACE_DEFINE_V2: 4725 { 4726 uint32_t cMipLevels; 4727 SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)pu32Cmd; 4728 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4729 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDefineV2); 4730 4731 cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize); 4732 rc = vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face, 4733 pCmd->multisampleCount, pCmd->autogenFilter, 4734 cMipLevels, (SVGA3dSize *)(pCmd + 1)); 4735 break; 4736 } 4737 4738 case SVGA_3D_CMD_SURFACE_DESTROY: 4739 { 4740 SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)pu32Cmd; 4741 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4742 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDestroy); 4743 rc = vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid); 4744 break; 4745 } 4746 4747 case SVGA_3D_CMD_SURFACE_COPY: 4748 { 4749 uint32_t cCopyBoxes; 4750 SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)pu32Cmd; 4751 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4752 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceCopy); 4753 4754 cCopyBoxes = (cbCmd - sizeof(pCmd)) / sizeof(SVGA3dCopyBox); 4755 rc = vmsvga3dSurfaceCopy(pThisCC, pCmd->dest, pCmd->src, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1)); 4756 break; 4757 } 4758 4759 case SVGA_3D_CMD_SURFACE_STRETCHBLT: 4760 { 4761 SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)pu32Cmd; 4762 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4763 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceStretchBlt); 4764 4765 rc = vmsvga3dSurfaceStretchBlt(pThis, pThisCC, &pCmd->dest, &pCmd->boxDest, 4766 &pCmd->src, &pCmd->boxSrc, pCmd->mode); 4767 break; 4768 } 4769 4770 case SVGA_3D_CMD_SURFACE_DMA: 4771 { 4772 uint32_t cCopyBoxes; 4773 SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)pu32Cmd; 4774 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4775 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceDma); 4776 4777 uint64_t u64NanoTS = 0; 4778 if (LogRelIs3Enabled()) 4779 u64NanoTS = RTTimeNanoTS(); 4780 cCopyBoxes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox); 4781 STAM_PROFILE_START(&pSVGAState->StatR3Cmd3dSurfaceDmaProf, a); 4782 rc = vmsvga3dSurfaceDMA(pThis, pThisCC, pCmd->guest, pCmd->host, pCmd->transfer, 4783 cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1)); 4784 STAM_PROFILE_STOP(&pSVGAState->StatR3Cmd3dSurfaceDmaProf, a); 4785 if (LogRelIs3Enabled()) 4786 { 4787 if (cCopyBoxes) 4788 { 4789 SVGA3dCopyBox *pFirstBox = (SVGA3dCopyBox *)(pCmd + 1); 4790 LogRel3(("VMSVGA: SURFACE_DMA: %d us %d boxes %d,%d %dx%d%s\n", 4791 (RTTimeNanoTS() - u64NanoTS) / 1000ULL, cCopyBoxes, 4792 pFirstBox->x, pFirstBox->y, pFirstBox->w, pFirstBox->h, 4793 pCmd->transfer == SVGA3D_READ_HOST_VRAM ? " readback!!!" : "")); 4794 } 4795 } 4796 break; 4797 } 4798 4799 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN: 4800 { 4801 uint32_t cRects; 4802 SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)pu32Cmd; 4803 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4804 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSurfaceScreen); 4805 4806 static uint64_t u64FrameStartNanoTS = 0; 4807 static uint64_t u64ElapsedPerSecNano = 0; 4808 static int cFrames = 0; 4809 uint64_t u64NanoTS = 0; 4810 if (LogRelIs3Enabled()) 4811 u64NanoTS = RTTimeNanoTS(); 4812 cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGASignedRect); 4813 STAM_REL_PROFILE_START(&pSVGAState->StatR3Cmd3dBlitSurfaceToScreenProf, a); 4814 rc = vmsvga3dSurfaceBlitToScreen(pThis, pThisCC, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage, 4815 pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1)); 4816 STAM_REL_PROFILE_STOP(&pSVGAState->StatR3Cmd3dBlitSurfaceToScreenProf, a); 4817 if (LogRelIs3Enabled()) 4818 { 4819 uint64_t u64ElapsedNano = RTTimeNanoTS() - u64NanoTS; 4820 u64ElapsedPerSecNano += u64ElapsedNano; 4821 4822 SVGASignedRect *pFirstRect = cRects ? (SVGASignedRect *)(pCmd + 1) : &pCmd->destRect; 4823 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: %d us %d rects %d,%d %dx%d\n", 4824 (u64ElapsedNano) / 1000ULL, cRects, 4825 pFirstRect->left, pFirstRect->top, 4826 pFirstRect->right - pFirstRect->left, pFirstRect->bottom - pFirstRect->top)); 4827 4828 ++cFrames; 4829 if (u64NanoTS - u64FrameStartNanoTS >= UINT64_C(1000000000)) 4830 { 4831 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: FPS %d, elapsed %llu us\n", 4832 cFrames, u64ElapsedPerSecNano / 1000ULL)); 4833 u64FrameStartNanoTS = u64NanoTS; 4834 cFrames = 0; 4835 u64ElapsedPerSecNano = 0; 4836 } 4837 } 4838 break; 4839 } 4840 4841 case SVGA_3D_CMD_CONTEXT_DEFINE: 4842 { 4843 SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)pu32Cmd; 4844 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4845 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dContextDefine); 4846 4847 rc = vmsvga3dContextDefine(pThisCC, pCmd->cid); 4848 break; 4849 } 4850 4851 case SVGA_3D_CMD_CONTEXT_DESTROY: 4852 { 4853 SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)pu32Cmd; 4854 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4855 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dContextDestroy); 4856 4857 rc = vmsvga3dContextDestroy(pThisCC, pCmd->cid); 4858 break; 4859 } 4860 4861 case SVGA_3D_CMD_SETTRANSFORM: 4862 { 4863 SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)pu32Cmd; 4864 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4865 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetTransform); 4866 4867 rc = vmsvga3dSetTransform(pThisCC, pCmd->cid, pCmd->type, pCmd->matrix); 4868 break; 4869 } 4870 4871 case SVGA_3D_CMD_SETZRANGE: 4872 { 4873 SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)pu32Cmd; 4874 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4875 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetZRange); 4876 4877 rc = vmsvga3dSetZRange(pThisCC, pCmd->cid, pCmd->zRange); 4878 break; 4879 } 4880 4881 case SVGA_3D_CMD_SETRENDERSTATE: 4882 { 4883 uint32_t cRenderStates; 4884 SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)pu32Cmd; 4885 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4886 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetRenderState); 4887 4888 cRenderStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRenderState); 4889 rc = vmsvga3dSetRenderState(pThisCC, pCmd->cid, cRenderStates, (SVGA3dRenderState *)(pCmd + 1)); 4890 break; 4891 } 4892 4893 case SVGA_3D_CMD_SETRENDERTARGET: 4894 { 4895 SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)pu32Cmd; 4896 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4897 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetRenderTarget); 4898 4899 rc = vmsvga3dSetRenderTarget(pThisCC, pCmd->cid, pCmd->type, pCmd->target); 4900 break; 4901 } 4902 4903 case SVGA_3D_CMD_SETTEXTURESTATE: 4904 { 4905 uint32_t cTextureStates; 4906 SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)pu32Cmd; 4907 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4908 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetTextureState); 4909 4910 cTextureStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dTextureState); 4911 rc = vmsvga3dSetTextureState(pThisCC, pCmd->cid, cTextureStates, (SVGA3dTextureState *)(pCmd + 1)); 4912 break; 4913 } 4914 4915 case SVGA_3D_CMD_SETMATERIAL: 4916 { 4917 SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)pu32Cmd; 4918 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4919 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetMaterial); 4920 4921 rc = vmsvga3dSetMaterial(pThisCC, pCmd->cid, pCmd->face, &pCmd->material); 4922 break; 4923 } 4924 4925 case SVGA_3D_CMD_SETLIGHTDATA: 4926 { 4927 SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)pu32Cmd; 4928 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4929 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetLightData); 4930 4931 rc = vmsvga3dSetLightData(pThisCC, pCmd->cid, pCmd->index, &pCmd->data); 4932 break; 4933 } 4934 4935 case SVGA_3D_CMD_SETLIGHTENABLED: 4936 { 4937 SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)pu32Cmd; 4938 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4939 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetLightEnable); 4940 4941 rc = vmsvga3dSetLightEnabled(pThisCC, pCmd->cid, pCmd->index, pCmd->enabled); 4942 break; 4943 } 4944 4945 case SVGA_3D_CMD_SETVIEWPORT: 4946 { 4947 SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)pu32Cmd; 4948 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4949 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetViewPort); 4950 4951 rc = vmsvga3dSetViewPort(pThisCC, pCmd->cid, &pCmd->rect); 4952 break; 4953 } 4954 4955 case SVGA_3D_CMD_SETCLIPPLANE: 4956 { 4957 SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)pu32Cmd; 4958 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4959 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetClipPlane); 4960 4961 rc = vmsvga3dSetClipPlane(pThisCC, pCmd->cid, pCmd->index, pCmd->plane); 4962 break; 4963 } 4964 4965 case SVGA_3D_CMD_CLEAR: 4966 { 4967 SVGA3dCmdClear *pCmd = (SVGA3dCmdClear *)pu32Cmd; 4968 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4969 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dClear); 4970 4971 uint32_t cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRect); 4972 rc = vmsvga3dCommandClear(pThisCC, pCmd->cid, pCmd->clearFlag, pCmd->color, pCmd->depth, pCmd->stencil, cRects, (SVGA3dRect *)(pCmd + 1)); 4973 break; 4974 } 4975 4976 case SVGA_3D_CMD_PRESENT: 4977 case SVGA_3D_CMD_PRESENT_READBACK: /** @todo SVGA_3D_CMD_PRESENT_READBACK isn't quite the same as present... */ 4978 { 4979 SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)pu32Cmd; 4980 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4981 if ((unsigned)enmCmdId == SVGA_3D_CMD_PRESENT) 4982 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dPresent); 4983 else 4984 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dPresentReadBack); 4985 4986 uint32_t cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyRect); 4987 4988 STAM_PROFILE_START(&pSVGAState->StatR3Cmd3dPresentProf, a); 4989 rc = vmsvga3dCommandPresent(pThis, pThisCC, pCmd->sid, cRects, (SVGA3dCopyRect *)(pCmd + 1)); 4990 STAM_PROFILE_STOP(&pSVGAState->StatR3Cmd3dPresentProf, a); 4991 break; 4992 } 4993 4994 case SVGA_3D_CMD_SHADER_DEFINE: 4995 { 4996 SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)pu32Cmd; 4997 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 4998 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dShaderDefine); 4999 5000 uint32_t cbData = (cbCmd - sizeof(*pCmd)); 5001 rc = vmsvga3dShaderDefine(pThisCC, pCmd->cid, pCmd->shid, pCmd->type, cbData, (uint32_t *)(pCmd + 1)); 5002 break; 5003 } 5004 5005 case SVGA_3D_CMD_SHADER_DESTROY: 5006 { 5007 SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)pu32Cmd; 5008 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5009 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dShaderDestroy); 5010 5011 rc = vmsvga3dShaderDestroy(pThisCC, pCmd->cid, pCmd->shid, pCmd->type); 5012 break; 5013 } 5014 5015 case SVGA_3D_CMD_SET_SHADER: 5016 { 5017 SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)pu32Cmd; 5018 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5019 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetShader); 5020 5021 rc = vmsvga3dShaderSet(pThisCC, NULL, pCmd->cid, pCmd->type, pCmd->shid); 5022 break; 5023 } 5024 5025 case SVGA_3D_CMD_SET_SHADER_CONST: 5026 { 5027 SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)pu32Cmd; 5028 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5029 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetShaderConst); 5030 5031 uint32_t cRegisters = (cbCmd - sizeof(*pCmd)) / sizeof(pCmd->values) + 1; 5032 rc = vmsvga3dShaderSetConst(pThisCC, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values); 5033 break; 5034 } 5035 5036 case SVGA_3D_CMD_DRAW_PRIMITIVES: 5037 { 5038 SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)pu32Cmd; 5039 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5040 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dDrawPrimitives); 5041 5042 AssertBreak(pCmd->numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES); 5043 AssertBreak(pCmd->numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS); 5044 uint32_t const cbRangesAndVertexDecls = pCmd->numVertexDecls * sizeof(SVGA3dVertexDecl) 5045 + pCmd->numRanges * sizeof(SVGA3dPrimitiveRange); 5046 ASSERT_GUEST_BREAK(cbRangesAndVertexDecls <= cbCmd - sizeof(*pCmd)); 5047 5048 uint32_t cVertexDivisor = (cbCmd - sizeof(*pCmd) - cbRangesAndVertexDecls) / sizeof(uint32_t); 5049 AssertBreak(!cVertexDivisor || cVertexDivisor == pCmd->numVertexDecls); 5050 5051 RT_UNTRUSTED_VALIDATED_FENCE(); 5052 5053 SVGA3dVertexDecl *pVertexDecl = (SVGA3dVertexDecl *)(pCmd + 1); 5054 SVGA3dPrimitiveRange *pNumRange = (SVGA3dPrimitiveRange *)&pVertexDecl[pCmd->numVertexDecls]; 5055 SVGA3dVertexDivisor *pVertexDivisor = cVertexDivisor ? (SVGA3dVertexDivisor *)&pNumRange[pCmd->numRanges] : NULL; 5056 5057 STAM_PROFILE_START(&pSVGAState->StatR3Cmd3dDrawPrimitivesProf, a); 5058 rc = vmsvga3dDrawPrimitives(pThisCC, pCmd->cid, pCmd->numVertexDecls, pVertexDecl, pCmd->numRanges, 5059 pNumRange, cVertexDivisor, pVertexDivisor); 5060 STAM_PROFILE_STOP(&pSVGAState->StatR3Cmd3dDrawPrimitivesProf, a); 5061 break; 5062 } 5063 5064 case SVGA_3D_CMD_SETSCISSORRECT: 5065 { 5066 SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)pu32Cmd; 5067 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5068 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dSetScissorRect); 5069 5070 rc = vmsvga3dSetScissorRect(pThisCC, pCmd->cid, &pCmd->rect); 5071 break; 5072 } 5073 5074 case SVGA_3D_CMD_BEGIN_QUERY: 5075 { 5076 SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)pu32Cmd; 5077 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5078 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dBeginQuery); 5079 5080 rc = vmsvga3dQueryBegin(pThisCC, pCmd->cid, pCmd->type); 5081 break; 5082 } 5083 5084 case SVGA_3D_CMD_END_QUERY: 5085 { 5086 SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)pu32Cmd; 5087 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5088 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dEndQuery); 5089 5090 rc = vmsvga3dQueryEnd(pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult); 5091 break; 5092 } 5093 5094 case SVGA_3D_CMD_WAIT_FOR_QUERY: 5095 { 5096 SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)pu32Cmd; 5097 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5098 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dWaitForQuery); 5099 5100 rc = vmsvga3dQueryWait(pThis, pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult); 5101 break; 5102 } 5103 5104 case SVGA_3D_CMD_GENERATE_MIPMAPS: 5105 { 5106 SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)pu32Cmd; 5107 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd)); 5108 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dGenerateMipmaps); 5109 5110 rc = vmsvga3dGenerateMipmaps(pThisCC, pCmd->sid, pCmd->filter); 5111 break; 5112 } 5113 5114 case SVGA_3D_CMD_ACTIVATE_SURFACE: 5115 /* context id + surface id? */ 5116 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dActivateSurface); 5117 break; 5118 case SVGA_3D_CMD_DEACTIVATE_SURFACE: 5119 /* context id + surface id? */ 5120 STAM_REL_COUNTER_INC(&pSVGAState->StatR3Cmd3dDeactivateSurface); 5121 break; 5122 5123 default: 5124 STAM_REL_COUNTER_INC(&pSVGAState->StatFifoUnkCmds); 5125 AssertMsgFailed(("enmCmdId=%d\n", enmCmdId)); 5126 break; 5127 } 6595 vmsvgaR3Process3dCmd(pThis, pThisCC, enmCmdId, cbCmd, pu32Cmd); 5128 6596 } 5129 6597 else … … 5193 6661 } 5194 6662 5195 #undef VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK5196 6663 #undef VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK 5197 6664 #undef VMSVGAFIFO_GET_CMD_BUFFER_BREAK … … 5880 7347 pHlp->pfnPrintf(pHlp, "Pitch lock: %#x (FIFO:%#x)\n", pThis->svga.u32PitchLock, pFIFO[SVGA_FIFO_PITCHLOCK]); 5881 7348 pHlp->pfnPrintf(pHlp, "Current GMR ID: %#x\n", pThis->svga.u32CurrentGMRId); 5882 pHlp->pfnPrintf(pHlp, " Capabilites reg: %#x\n", pThis->svga.u32RegCaps);7349 pHlp->pfnPrintf(pHlp, "Device Capabilites: %#x\n", pThis->svga.u32DeviceCaps); 5883 7350 pHlp->pfnPrintf(pHlp, "Index reg: %#x\n", pThis->svga.u32IndexReg); 5884 7351 pHlp->pfnPrintf(pHlp, "Action flags: %#x\n", pThis->svga.u32ActionFlags); … … 6270 7737 pSVGAState->paGMR = NULL; 6271 7738 } 7739 7740 if (RTCritSectIsInitialized(&pSVGAState->CritSectCmdBuf)) 7741 { 7742 RTCritSectEnter(&pSVGAState->CritSectCmdBuf); 7743 for (unsigned i = 0; i < RT_ELEMENTS(pSVGAState->apCmdBufCtxs); ++i) 7744 { 7745 vmsvgaR3CmdBufCtxTerm(pSVGAState->apCmdBufCtxs[i]); 7746 pSVGAState->apCmdBufCtxs[i] = NULL; 7747 } 7748 vmsvgaR3CmdBufCtxTerm(&pSVGAState->CmdBufCtxDC); 7749 RTCritSectLeave(&pSVGAState->CritSectCmdBuf); 7750 RTCritSectDelete(&pSVGAState->CritSectCmdBuf); 7751 } 6272 7752 } 6273 7753 … … 6293 7773 # endif 6294 7774 7775 rc = RTCritSectInit(&pSVGAState->CritSectCmdBuf); 7776 AssertRCReturn(rc, rc); 7777 7778 vmsvgaR3CmdBufCtxInit(&pSVGAState->CmdBufCtxDC); 6295 7779 return rc; 6296 7780 } 6297 7781 6298 7782 /** 6299 * Initializes the host capabilities: registersand FIFO.7783 * Initializes the host capabilities: device and FIFO. 6300 7784 * 6301 7785 * @returns VBox status code. … … 6305 7789 static void vmsvgaR3InitCaps(PVGASTATE pThis, PVGASTATECC pThisCC) 6306 7790 { 6307 /* Register caps. */ 6308 pThis->svga.u32RegCaps = SVGA_CAP_GMR 6309 | SVGA_CAP_GMR2 6310 | SVGA_CAP_CURSOR 6311 | SVGA_CAP_CURSOR_BYPASS 6312 | SVGA_CAP_CURSOR_BYPASS_2 6313 | SVGA_CAP_EXTENDED_FIFO 6314 | SVGA_CAP_IRQMASK 6315 | SVGA_CAP_PITCHLOCK 6316 | SVGA_CAP_RECT_COPY 6317 | SVGA_CAP_TRACES 6318 | SVGA_CAP_SCREEN_OBJECT_2 6319 | SVGA_CAP_ALPHA_CURSOR; 7791 /* Device caps. */ 7792 pThis->svga.u32DeviceCaps = SVGA_CAP_GMR 7793 | SVGA_CAP_GMR2 7794 | SVGA_CAP_CURSOR 7795 | SVGA_CAP_CURSOR_BYPASS 7796 | SVGA_CAP_CURSOR_BYPASS_2 7797 | SVGA_CAP_EXTENDED_FIFO 7798 | SVGA_CAP_IRQMASK 7799 | SVGA_CAP_PITCHLOCK 7800 | SVGA_CAP_RECT_COPY 7801 | SVGA_CAP_TRACES 7802 | SVGA_CAP_SCREEN_OBJECT_2 7803 | SVGA_CAP_ALPHA_CURSOR; 7804 7805 /* VGPU10 capabilities. */ 7806 // pThis->svga.u32DeviceCaps |= SVGA_CAP_COMMAND_BUFFERS /* Enable register based command buffer submission. */ 7807 // | SVGA_CAP_CMD_BUFFERS_2 /* Support for SVGA_REG_CMD_PREPEND_LOW/HIGH */ 7808 // | SVGA_CAP_GBOBJECTS /* Enable guest-backed objects and surfaces. */ 7809 // | SVGA_CAP_CMD_BUFFERS_3 /* AKA SVGA_CAP_DX. Enable support for DX commands, and command buffers in a mob. */ 7810 // ; 7811 6320 7812 # ifdef VBOX_WITH_VMSVGA3D 6321 pThis->svga.u32 RegCaps |= SVGA_CAP_3D;7813 pThis->svga.u32DeviceCaps |= SVGA_CAP_3D; 6322 7814 # endif 6323 7815 … … 6327 7819 /* Setup FIFO capabilities. */ 6328 7820 pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE 6329 | SVGA_FIFO_CAP_CURSOR_BYPASS_36330 | SVGA_FIFO_CAP_GMR26331 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED6332 | SVGA_FIFO_CAP_SCREEN_OBJECT_26333 | SVGA_FIFO_CAP_RESERVE6334 | SVGA_FIFO_CAP_PITCHLOCK;7821 | SVGA_FIFO_CAP_PITCHLOCK 7822 | SVGA_FIFO_CAP_CURSOR_BYPASS_3 7823 | SVGA_FIFO_CAP_RESERVE 7824 | SVGA_FIFO_CAP_GMR2 7825 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED 7826 | SVGA_FIFO_CAP_SCREEN_OBJECT_2; 6335 7827 6336 7828 /* Valid with SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ … … 6426 7918 "xSURFACEFMT_ATI1", 6427 7919 "xSURFACEFMT_ATI2", /* 83 */ 7920 "xDEAD1", 7921 "xVIDEO_DECODE", 7922 "xVIDEO_PROCESS", 7923 "xLINE_AA", 7924 "xLINE_STIPPLE", 7925 "rMAX_LINE_WIDTH", 7926 "rMAX_AA_LINE_WIDTH", 7927 "xSURFACEFMT_YV12", 7928 "xLOGICOPS", 7929 "xTS_COLOR_KEY", 7930 "xDEAD2", 7931 "xDX", 7932 "xMAX_TEXTURE_ARRAY_SIZE", 7933 "xDX_MAX_VERTEXBUFFERS", 7934 "xDX_MAX_CONSTANT_BUFFERS", 7935 "xDX_PROVOKING_VERTEX", 7936 "xDXFMT_X8R8G8B8", 7937 "xDXFMT_A8R8G8B8", 7938 "xDXFMT_R5G6B5", 7939 "xDXFMT_X1R5G5B5", 7940 "xDXFMT_A1R5G5B5", 7941 "xDXFMT_A4R4G4B4", 7942 "xDXFMT_Z_D32", 7943 "xDXFMT_Z_D16", 7944 "xDXFMT_Z_D24S8", 7945 "xDXFMT_Z_D15S1", 7946 "xDXFMT_LUMINANCE8", 7947 "xDXFMT_LUMINANCE4_ALPHA4", 7948 "xDXFMT_LUMINANCE16", 7949 "xDXFMT_LUMINANCE8_ALPHA8", 7950 "xDXFMT_DXT1", 7951 "xDXFMT_DXT2", 7952 "xDXFMT_DXT3", 7953 "xDXFMT_DXT4", 7954 "xDXFMT_DXT5", 7955 "xDXFMT_BUMPU8V8", 7956 "xDXFMT_BUMPL6V5U5", 7957 "xDXFMT_BUMPX8L8V8U8", 7958 "xDXFMT_FORMAT_DEAD1", 7959 "xDXFMT_ARGB_S10E5", 7960 "xDXFMT_ARGB_S23E8", 7961 "xDXFMT_A2R10G10B10", 7962 "xDXFMT_V8U8", 7963 "xDXFMT_Q8W8V8U8", 7964 "xDXFMT_CxV8U8", 7965 "xDXFMT_X8L8V8U8", 7966 "xDXFMT_A2W10V10U10", 7967 "xDXFMT_ALPHA8", 7968 "xDXFMT_R_S10E5", 7969 "xDXFMT_R_S23E8", 7970 "xDXFMT_RG_S10E5", 7971 "xDXFMT_RG_S23E8", 7972 "xDXFMT_BUFFER", 7973 "xDXFMT_Z_D24X8", 7974 "xDXFMT_V16U16", 7975 "xDXFMT_G16R16", 7976 "xDXFMT_A16B16G16R16", 7977 "xDXFMT_UYVY", 7978 "xDXFMT_YUY2", 7979 "xDXFMT_NV12", 7980 "xDXFMT_AYUV", 7981 "xDXFMT_R32G32B32A32_TYPELESS", 7982 "xDXFMT_R32G32B32A32_UINT", 7983 "xDXFMT_R32G32B32A32_SINT", 7984 "xDXFMT_R32G32B32_TYPELESS", 7985 "xDXFMT_R32G32B32_FLOAT", 7986 "xDXFMT_R32G32B32_UINT", 7987 "xDXFMT_R32G32B32_SINT", 7988 "xDXFMT_R16G16B16A16_TYPELESS", 7989 "xDXFMT_R16G16B16A16_UINT", 7990 "xDXFMT_R16G16B16A16_SNORM", 7991 "xDXFMT_R16G16B16A16_SINT", 7992 "xDXFMT_R32G32_TYPELESS", 7993 "xDXFMT_R32G32_UINT", 7994 "xDXFMT_R32G32_SINT", 7995 "xDXFMT_R32G8X24_TYPELESS", 7996 "xDXFMT_D32_FLOAT_S8X24_UINT", 7997 "xDXFMT_R32_FLOAT_X8X24_TYPELESS", 7998 "xDXFMT_X32_TYPELESS_G8X24_UINT", 7999 "xDXFMT_R10G10B10A2_TYPELESS", 8000 "xDXFMT_R10G10B10A2_UINT", 8001 "xDXFMT_R11G11B10_FLOAT", 8002 "xDXFMT_R8G8B8A8_TYPELESS", 8003 "xDXFMT_R8G8B8A8_UNORM", 8004 "xDXFMT_R8G8B8A8_UNORM_SRGB", 8005 "xDXFMT_R8G8B8A8_UINT", 8006 "xDXFMT_R8G8B8A8_SINT", 8007 "xDXFMT_R16G16_TYPELESS", 8008 "xDXFMT_R16G16_UINT", 8009 "xDXFMT_R16G16_SINT", 8010 "xDXFMT_R32_TYPELESS", 8011 "xDXFMT_D32_FLOAT", 8012 "xDXFMT_R32_UINT", 8013 "xDXFMT_R32_SINT", 8014 "xDXFMT_R24G8_TYPELESS", 8015 "xDXFMT_D24_UNORM_S8_UINT", 8016 "xDXFMT_R24_UNORM_X8_TYPELESS", 8017 "xDXFMT_X24_TYPELESS_G8_UINT", 8018 "xDXFMT_R8G8_TYPELESS", 8019 "xDXFMT_R8G8_UNORM", 8020 "xDXFMT_R8G8_UINT", 8021 "xDXFMT_R8G8_SINT", 8022 "xDXFMT_R16_TYPELESS", 8023 "xDXFMT_R16_UNORM", 8024 "xDXFMT_R16_UINT", 8025 "xDXFMT_R16_SNORM", 8026 "xDXFMT_R16_SINT", 8027 "xDXFMT_R8_TYPELESS", 8028 "xDXFMT_R8_UNORM", 8029 "xDXFMT_R8_UINT", 8030 "xDXFMT_R8_SNORM", 8031 "xDXFMT_R8_SINT", 8032 "xDXFMT_P8", 8033 "xDXFMT_R9G9B9E5_SHAREDEXP", 8034 "xDXFMT_R8G8_B8G8_UNORM", 8035 "xDXFMT_G8R8_G8B8_UNORM", 8036 "xDXFMT_BC1_TYPELESS", 8037 "xDXFMT_BC1_UNORM_SRGB", 8038 "xDXFMT_BC2_TYPELESS", 8039 "xDXFMT_BC2_UNORM_SRGB", 8040 "xDXFMT_BC3_TYPELESS", 8041 "xDXFMT_BC3_UNORM_SRGB", 8042 "xDXFMT_BC4_TYPELESS", 8043 "xDXFMT_ATI1", 8044 "xDXFMT_BC4_SNORM", 8045 "xDXFMT_BC5_TYPELESS", 8046 "xDXFMT_ATI2", 8047 "xDXFMT_BC5_SNORM", 8048 "xDXFMT_R10G10B10_XR_BIAS_A2_UNORM", 8049 "xDXFMT_B8G8R8A8_TYPELESS", 8050 "xDXFMT_B8G8R8A8_UNORM_SRGB", 8051 "xDXFMT_B8G8R8X8_TYPELESS", 8052 "xDXFMT_B8G8R8X8_UNORM_SRGB", 8053 "xDXFMT_Z_DF16", 8054 "xDXFMT_Z_DF24", 8055 "xDXFMT_Z_D24S8_INT", 8056 "xDXFMT_YV12", 8057 "xDXFMT_R32G32B32A32_FLOAT", 8058 "xDXFMT_R16G16B16A16_FLOAT", 8059 "xDXFMT_R16G16B16A16_UNORM", 8060 "xDXFMT_R32G32_FLOAT", 8061 "xDXFMT_R10G10B10A2_UNORM", 8062 "xDXFMT_R8G8B8A8_SNORM", 8063 "xDXFMT_R16G16_FLOAT", 8064 "xDXFMT_R16G16_UNORM", 8065 "xDXFMT_R16G16_SNORM", 8066 "xDXFMT_R32_FLOAT", 8067 "xDXFMT_R8G8_SNORM", 8068 "xDXFMT_R16_FLOAT", 8069 "xDXFMT_D16_UNORM", 8070 "xDXFMT_A8_UNORM", 8071 "xDXFMT_BC1_UNORM", 8072 "xDXFMT_BC2_UNORM", 8073 "xDXFMT_BC3_UNORM", 8074 "xDXFMT_B5G6R5_UNORM", 8075 "xDXFMT_B5G5R5A1_UNORM", 8076 "xDXFMT_B8G8R8A8_UNORM", 8077 "xDXFMT_B8G8R8X8_UNORM", 8078 "xDXFMT_BC4_UNORM", 8079 "xDXFMT_BC5_UNORM", 6428 8080 }; 6429 8081 6430 8082 /** 6431 * Initializes the host 3D capabilities in FIFO.8083 * Initializes the host 3D capabilities and writes them to FIFO memory. 6432 8084 * 6433 8085 * @returns VBox status code. … … 6435 8087 * @param pThisCC The VGA/VMSVGA state for ring-3. 6436 8088 */ 6437 static void vmsvgaR3InitFifo3DCaps(PVGASTATECC pThisCC) 6438 { 6439 /** @todo Probably query the capabilities once and cache in a memory buffer. */ 6440 bool fSavedBuffering = RTLogRelSetBuffering(true); 6441 SVGA3dCapsRecord *pCaps; 6442 SVGA3dCapPair *pData; 6443 uint32_t idxCap = 0; 8089 static void vmsvgaR3InitFifo3DCaps(PVGASTATE pThis, PVGASTATECC pThisCC) 8090 { 8091 /* Query the capabilities and store them in the pThis->svga.au32DevCaps array. */ 8092 bool const fSavedBuffering = RTLogRelSetBuffering(true); 8093 8094 for (unsigned i = 0; i < RT_ELEMENTS(pThis->svga.au32DevCaps); ++i) 8095 { 8096 uint32_t val = 0; 8097 int rc = vmsvga3dQueryCaps(pThisCC, i, &val); 8098 if (RT_SUCCESS(rc)) 8099 pThis->svga.au32DevCaps[i] = val; 8100 else 8101 pThis->svga.au32DevCaps[i] = 0; 8102 8103 /* LogRel the capability value. */ 8104 if (i < RT_ELEMENTS(g_apszVmSvgaDevCapNames)) 8105 { 8106 if (RT_SUCCESS(rc)) 8107 { 8108 if (g_apszVmSvgaDevCapNames[i][0] == 'x') 8109 LogRel(("VMSVGA3d: cap[%u]=%#010x {%s}\n", i, val, &g_apszVmSvgaDevCapNames[i][1])); 8110 else 8111 { 8112 float const fval = *(float *)&val; 8113 LogRel(("VMSVGA3d: cap[%u]=" FLOAT_FMT_STR " {%s}\n", i, FLOAT_FMT_ARGS(fval), &g_apszVmSvgaDevCapNames[i][1])); 8114 } 8115 } 8116 else 8117 LogRel(("VMSVGA3d: cap[%u]=failed rc=%Rrc {%s}\n", i, rc, &g_apszVmSvgaDevCapNames[i][1])); 8118 } 8119 else 8120 LogRel(("VMSVGA3d: new cap[%u]=%#010x rc=%Rrc\n", i, val, rc)); 8121 } 8122 8123 RTLogRelSetBuffering(fSavedBuffering); 6444 8124 6445 8125 /* 3d hardware version; latest and greatest */ … … 6447 8127 pThisCC->svga.pau32FIFO[SVGA_FIFO_3D_HWVERSION] = SVGA3D_HWVERSION_CURRENT; 6448 8128 8129 /* Fill out 3d capabilities up to SVGA3D_DEVCAP_SURFACEFMT_ATI2 in the FIFO memory. 8130 * SVGA3D_DEVCAP_SURFACEFMT_ATI2 is the last capabiltiy for pre-SVGA_CAP_GBOBJECTS hardware. 8131 * If the VMSVGA device supports SVGA_CAP_GBOBJECTS capability, then the guest has to use SVGA_REG_DEV_CAP 8132 * register to query the devcaps. Older guests will still try to read the devcaps from FIFO. 8133 */ 8134 SVGA3dCapsRecord *pCaps; 8135 SVGA3dCapPair *pData; 8136 6449 8137 pCaps = (SVGA3dCapsRecord *)&pThisCC->svga.pau32FIFO[SVGA_FIFO_3D_CAPS]; 6450 8138 pCaps->header.type = SVGA3DCAPS_RECORD_DEVCAPS; 6451 8139 pData = (SVGA3dCapPair *)&pCaps->data; 6452 8140 6453 /* Fill out all 3d capabilities. */6454 /** @todo The current implementation stores the capabilities in the FIFO.6455 * Newer VMSVGA uses SVGA_REG_DEV_CAP register to query 3d caps.6456 * Prerequisite for the new interface is support for SVGA_CAP_GBOBJECTS.6457 */6458 8141 AssertCompile(SVGA3D_DEVCAP_DEAD1 == SVGA3D_DEVCAP_SURFACEFMT_ATI2 + 1); 6459 for (unsigned i = 0; i < SVGA3D_DEVCAP_DEAD1; i++) 6460 { 6461 uint32_t val = 0; 6462 6463 int rc = vmsvga3dQueryCaps(pThisCC, i, &val); 6464 if (RT_SUCCESS(rc)) 6465 { 6466 pData[idxCap][0] = i; 6467 pData[idxCap][1] = val; 6468 idxCap++; 6469 if (g_apszVmSvgaDevCapNames[i][0] == 'x') 6470 LogRel(("VMSVGA3d: cap[%u]=%#010x {%s}\n", i, val, &g_apszVmSvgaDevCapNames[i][1])); 6471 else 6472 LogRel(("VMSVGA3d: cap[%u]=%d.%04u {%s}\n", i, (int)*(float *)&val, (unsigned)(*(float *)&val * 10000) % 10000, 6473 &g_apszVmSvgaDevCapNames[i][1])); 6474 } 6475 else 6476 LogRel(("VMSVGA3d: cap[%u]=failed rc=%Rrc! {%s}\n", i, rc, &g_apszVmSvgaDevCapNames[i][1])); 6477 } 6478 pCaps->header.length = (sizeof(pCaps->header) + idxCap * sizeof(SVGA3dCapPair)) / sizeof(uint32_t); 8142 for (unsigned i = 0; i < SVGA3D_DEVCAP_DEAD1; ++i) 8143 { 8144 pData[i][0] = i; 8145 pData[i][1] = pThis->svga.au32DevCaps[i]; 8146 } 8147 pCaps->header.length = (sizeof(pCaps->header) + SVGA3D_DEVCAP_DEAD1 * sizeof(SVGA3dCapPair)) / sizeof(uint32_t); 6479 8148 pCaps = (SVGA3dCapsRecord *)((uint32_t *)pCaps + pCaps->header.length); 6480 8149 6481 /* Mark end of record array . */8150 /* Mark end of record array (a zero word). */ 6482 8151 pCaps->header.length = 0; 6483 6484 RTLogRelSetBuffering(fSavedBuffering);6485 8152 } 6486 8153 … … 6523 8190 # ifdef VBOX_WITH_VMSVGA3D 6524 8191 if (pThis->svga.f3DEnabled) 6525 vmsvgaR3InitFifo3DCaps(pThis CC);8192 vmsvgaR3InitFifo3DCaps(pThis, pThisCC); 6526 8193 # endif 6527 8194 … … 6821 8488 REG_CNT(&pThis->svga.StatRegUnknownWr, "VMSVGA/Reg/UnknownWrite", "Writes to unknown register."); 6822 8489 REG_CNT(&pThis->svga.StatRegWidthWr, "VMSVGA/Reg/WidthWrite", "SVGA_REG_WIDTH writes."); 8490 REG_CNT(&pThis->svga.StatRegCommandLowWr, "VMSVGA/Reg/CommandLowWrite", "SVGA_REG_COMMAND_LOW writes."); 8491 REG_CNT(&pThis->svga.StatRegCommandHighWr, "VMSVGA/Reg/CommandHighWrite", "SVGA_REG_COMMAND_HIGH writes."); 8492 REG_CNT(&pThis->svga.StatRegDevCapWr, "VMSVGA/Reg/DevCapWrite", "SVGA_REG_DEV_CAP writes."); 8493 REG_CNT(&pThis->svga.StatRegCmdPrependLowWr, "VMSVGA/Reg/CmdPrependLowWrite", "SVGA_REG_CMD_PREPEND_LOW writes."); 8494 REG_CNT(&pThis->svga.StatRegCmdPrependHighWr, "VMSVGA/Reg/CmdPrependHighWrite", "SVGA_REG_iCMD_PREPEND_HIGH writes."); 6823 8495 6824 8496 REG_CNT(&pThis->svga.StatRegBitsPerPixelRd, "VMSVGA/Reg/BitsPerPixelRead", "SVGA_REG_BITS_PER_PIXEL reads."); … … 6874 8546 REG_CNT(&pThis->svga.StatRegWidthRd, "VMSVGA/Reg/WidthRead", "SVGA_REG_WIDTH reads."); 6875 8547 REG_CNT(&pThis->svga.StatRegWriteOnlyRd, "VMSVGA/Reg/WriteOnlyRead", "Write-only SVGA_REG_XXXX reads."); 8548 REG_CNT(&pThis->svga.StatRegCommandLowRd, "VMSVGA/Reg/CommandLowRead", "SVGA_REG_COMMAND_LOW reads."); 8549 REG_CNT(&pThis->svga.StatRegCommandHighRd, "VMSVGA/Reg/CommandHighRead", "SVGA_REG_COMMAND_HIGH reads."); 8550 REG_CNT(&pThis->svga.StatRegMaxPrimBBMemRd, "VMSVGA/Reg/MaxPrimBBMemRead", "SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM reads."); 8551 REG_CNT(&pThis->svga.StatRegGBMemSizeRd, "VMSVGA/Reg/GBMemSizeRead", "SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB reads."); 8552 REG_CNT(&pThis->svga.StatRegDevCapRd, "VMSVGA/Reg/DevCapRead", "SVGA_REG_DEV_CAP reads."); 8553 REG_CNT(&pThis->svga.StatRegCmdPrependLowRd, "VMSVGA/Reg/CmdPrependLowRead", "SVGA_REG_CMD_PREPEND_LOW reads."); 8554 REG_CNT(&pThis->svga.StatRegCmdPrependHighRd, "VMSVGA/Reg/CmdPrependHighRead", "SVGA_REG_iCMD_PREPEND_HIGH reads."); 8555 REG_CNT(&pThis->svga.StatRegScrnTgtMaxWidthRd, "VMSVGA/Reg/ScrnTgtMaxWidthRead", "SVGA_REG_SCREENTARGET_MAX_WIDTH reads."); 8556 REG_CNT(&pThis->svga.StatRegScrnTgtMaxHeightRd, "VMSVGA/Reg/ScrnTgtMaxHeightRead", "SVGA_REG_SCREENTARGET_MAX_HEIGHT reads."); 8557 REG_CNT(&pThis->svga.StatRegMobMaxSizeRd, "VMSVGA/Reg/MobMaxSizeRead", "SVGA_REG_MOB_MAX_SIZE reads."); 6876 8558 6877 8559 REG_PRF(&pSVGAState->StatBusyDelayEmts, "VMSVGA/EmtDelayOnBusyFifo", "Time we've delayed EMTs because of busy FIFO thread."); … … 6930 8612 { 6931 8613 int rc = vmsvga3dPowerOn(pDevIns, pThis, pThisCC); 6932 6933 8614 if (RT_SUCCESS(rc)) 6934 8615 { 6935 8616 /* Initialize FIFO 3D capabilities. */ 6936 vmsvgaR3InitFifo3DCaps(pThis CC);8617 vmsvgaR3InitFifo3DCaps(pThis, pThisCC); 6937 8618 } 6938 8619 } -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
r86025 r86193 301 301 /** Current GMR id. (SVGA_REG_GMR_ID) */ 302 302 uint32_t u32CurrentGMRId; 303 /** Register caps. */304 uint32_t u32 RegCaps;303 /** SVGA device capabilities. */ 304 uint32_t u32DeviceCaps; 305 305 uint32_t Padding0; /* Used to be I/O port base address. */ 306 306 /** Port io index register. */ … … 367 367 uint32_t au32ScratchRegion[VMSVGA_SCRATCH_SIZE]; 368 368 369 /** Array of SVGA3D_DEVCAP values, which are accessed via SVGA_REG_DEV_CAP. */ 370 uint32_t au32DevCaps[SVGA3D_DEVCAP_MAX]; 371 /** Index written to the SVGA_REG_DEV_CAP register. */ 372 uint32_t u32DevCapIndex; 373 uint32_t u32RegCommandLow; 374 uint32_t u32RegCommandHigh; 375 369 376 STAMCOUNTER StatRegBitsPerPixelWr; 370 377 STAMCOUNTER StatRegBusyWr; … … 398 405 STAMCOUNTER StatRegUnknownWr; 399 406 STAMCOUNTER StatRegWidthWr; 407 STAMCOUNTER StatRegCommandLowWr; 408 STAMCOUNTER StatRegCommandHighWr; 409 STAMCOUNTER StatRegDevCapWr; 410 STAMCOUNTER StatRegCmdPrependLowWr; 411 STAMCOUNTER StatRegCmdPrependHighWr; 400 412 401 413 STAMCOUNTER StatRegBitsPerPixelRd; … … 451 463 STAMCOUNTER StatRegWidthRd; 452 464 STAMCOUNTER StatRegWriteOnlyRd; 465 STAMCOUNTER StatRegCommandLowRd; 466 STAMCOUNTER StatRegCommandHighRd; 467 STAMCOUNTER StatRegMaxPrimBBMemRd; 468 STAMCOUNTER StatRegGBMemSizeRd; 469 STAMCOUNTER StatRegDevCapRd; 470 STAMCOUNTER StatRegCmdPrependLowRd; 471 STAMCOUNTER StatRegCmdPrependHighRd; 472 STAMCOUNTER StatRegScrnTgtMaxWidthRd; 473 STAMCOUNTER StatRegScrnTgtMaxHeightRd; 474 STAMCOUNTER StatRegMobMaxSizeRd; 453 475 } VMSVGAState, VMSVGASTATE; 454 476
Note:
See TracChangeset
for help on using the changeset viewer.