VirtualBox

Changeset 86193 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 21, 2020 12:37:31 PM (4 years ago)
Author:
vboxsync
Message:

Devices/Graphics: New VMSVGA registers. Register based command buffers SVGA_CAP_COMMAND_BUFFERS capability (not enabled yet). Separate functions for the SVGA command handlers. bugref:9830

Location:
trunk/src/VBox/Devices/Graphics
Files:
2 edited

Legend:

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

    r86024 r86193  
    213213
    214214#ifdef IN_RING3
     215typedef struct VMSVGACMDBUF *PVMSVGACMDBUF;
     216typedef struct VMSVGACMDBUFCTX *PVMSVGACMDBUFCTX;
     217
     218/* Command buffer. */
     219typedef 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. */
     233typedef 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
    215241/**
    216242 * Internal SVGA ring-3 only state.
     
    250276# endif
    251277
    252     /** Information obout screens. */
     278    /** Information about screens. */
    253279    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;
    254289
    255290    /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */
     
    530565    SSMFIELD_ENTRY(                 VMSVGAState, u32PitchLock),
    531566    SSMFIELD_ENTRY(                 VMSVGAState, u32CurrentGMRId),
    532     SSMFIELD_ENTRY(                 VMSVGAState, u32RegCaps),
     567    SSMFIELD_ENTRY(                 VMSVGAState, u32DeviceCaps),
    533568    SSMFIELD_ENTRY(                 VMSVGAState, u32IndexReg),
    534569    SSMFIELD_ENTRY_IGNORE(          VMSVGAState, hFIFORequestSem),
     
    566601                                uint32_t uVersion, uint32_t uPass);
    567602static int vmsvgaR3SaveExecFifo(PCPDMDEVHLPR3 pHlp, PVGASTATECC pThisCC, PSSMHANDLE pSSM);
     603static void vmsvgaR3CmdBufSubmit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, RTGCPHYS GCPhysCB, SVGACBContext CBCtx);
    568604# ifdef VBOX_WITH_VMSVGA3D
    569605static void vmsvgaR3GmrFree(PVGASTATECC pThisCC, uint32_t idGMR);
     
    604640#endif /* IN_RING3 */
    605641
     642#define SVGA_CASE_ID2STR(idx) case idx: return #idx
     643
    606644#ifdef LOG_ENABLED
    607645
     
    617655    switch (idxReg)
    618656    {
    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 */
    669722
    670723        default:
     
    688741    switch (u32Cmd)
    689742    {
    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";
    746959    }
    747960}
     
    9371150
    9381151    /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */
    939     if (   idxReg >= SVGA_REG_CAPABILITIES
     1152    if (   idxReg >= SVGA_REG_ID_0_TOP
    9401153        && pThis->svga.u32SVGAId == SVGA_ID_0)
    9411154    {
    942         idxReg += SVGA_PALETTE_BASE - SVGA_REG_CAPABILITIES;
     1155        idxReg += SVGA_PALETTE_BASE - SVGA_REG_ID_0_TOP;
    9431156        Log(("vmsvgaWritePort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg));
    9441157    }
     
    11521365        case SVGA_REG_CAPABILITIES:
    11531366            STAM_REL_COUNTER_INC(&pThis->svga.StatRegCapabilitesRd);
    1154             *pu32 = pThis->svga.u32RegCaps;
     1367            *pu32 = pThis->svga.u32DeviceCaps;
    11551368            break;
    11561369
     
    13711584            break;
    13721585
     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
    13731651        default:
    13741652        {
     
    13761654            if ((offReg = idxReg - SVGA_SCRATCH_BASE) < pThis->svga.cScratchRegion)
    13771655            {
     1656                STAM_REL_COUNTER_INC(&pThis->svga.StatRegScratchRd);
    13781657                RT_UNTRUSTED_VALIDATED_FENCE();
    13791658                *pu32 = pThis->svga.au32ScratchRegion[offReg];
    1380                 STAM_REL_COUNTER_INC(&pThis->svga.StatRegScratchRd);
    13811659            }
    13821660            else if ((offReg = idxReg - SVGA_PALETTE_BASE) < (uint32_t)SVGA_NUM_PALETTE_REGS)
     
    17101988
    17111989    /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */
    1712     if (   idxReg >= SVGA_REG_CAPABILITIES
     1990    if (   idxReg >= SVGA_REG_ID_0_TOP
    17131991        && pThis->svga.u32SVGAId == SVGA_ID_0)
    17141992    {
    1715         idxReg += SVGA_PALETTE_BASE - SVGA_REG_CAPABILITIES;
     1993        idxReg += SVGA_PALETTE_BASE - SVGA_REG_ID_0_TOP;
    17161994        Log(("vmsvgaWritePort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg));
    17171995    }
     
    20962374            STAM_REL_COUNTER_INC(&pThis->svga.StatRegNumDisplaysWr);
    20972375            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. */
    20982420            break;
    20992421
     
    21182440        case SVGA_REG_GMR_MAX_IDS:
    21192441        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:
    21202447            /* Read only - ignore. */
    21212448            Log(("Write to R/O register %x - val %x ignored\n", idxReg, u32));
     
    28433170
    28443171
    2845 /**
    2846  * Handles the SVGA_CMD_DEFINE_CURSOR command.
     3172/** SVGA_3D_CMD_* handler.
    28473173 *
    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 */
     3180static 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 */
     3636static 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 */
     3654static 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 */
     3672static 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 */
     3684static 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 */
     3709static 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 */
     3746static 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 */
     3758static 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 */
     3770static 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;
    28643792
    28653793    /*
     
    28793807    uint8_t       *pbDst     = pbCopy;
    28803808    uint8_t const *pbSrc     = pbSrcAndMask;
    2881     switch (pCursor->andMaskDepth)
     3809    switch (pCmd->andMaskDepth)
    28823810    {
    28833811        case 1:
     
    30073935    uint32_t *pu32Dst = (uint32_t *)(pbCopy + RT_ALIGN_32(cbDstAndMask, 4));
    30083936    pbSrc  = pbSrcXorMask;
    3009     switch (pCursor->xorMaskDepth)
     3937    switch (pCmd->xorMaskDepth)
    30103938    {
    30113939        case 1:
     
    30874015     * Pass it to the frontend/whatever.
    30884016     */
    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 */
     4023static 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 */
     4055static 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 */
     4107static 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 */
     4173static 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 */
     4198static 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 */
     4214static 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 */
     4285static 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 */
     4356static 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 */
     4369static 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 */
     4383static 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 */
     4419static 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 */
     4577static 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 */
     4599static 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 */
     4620static 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 */
     4643static 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 */
     4655static 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 */
     4666static 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 */
     4694static 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 */
     4732static 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 */
     4800static 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 */
     4873static 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 */
     4890static 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 */
     4933static 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 */
     5036static 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 */
     5054static 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 */
     5406static 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    }
    30905466}
    30915467
     
    35575933 *
    35585934 * @returns true if pending work, false if not.
    3559  * @param   pFIFO               The FIFO to examine.
     5935 * @param   pThisCC             The VGA/VMSVGA state for ring-3.
    35605936 * @param   uLastCursorCount    The last cursor update counter value.
    35615937 */
    3562 DECLINLINE(bool) vmsvgaR3FifoHasWork(uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO, uint32_t uLastCursorCount)
    3563 {
     5938DECLINLINE(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
    35645947    if (pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
    35655948        return true;
     
    35845967    /* Caller already checked pThis->svga.fFIFOThreadSleeping, so we only have
    35855968       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))
    35895970        && pThis->svga.fFIFOThreadSleeping)
    35905971    {
     
    37626143         */
    37636144        if (   fBadOrDisabledFifo
    3764             || !vmsvgaR3FifoHasWork(pFIFO, pThis->svga.uLastCursorUpdateCount))
     6145            || !vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount))
    37656146        {
    37666147            ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, true);
     
    37756156# endif
    37766157                if (   !fBadOrDisabledFifo
    3777                     && vmsvgaR3FifoHasWork(pFIFO, pThis->svga.uLastCursorUpdateCount))
     6158                    && vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount))
    37786159                    rc = VINF_SUCCESS;
    37796160                else
     
    37976178        if (rc == VERR_TIMEOUT)
    37986179        {
    3799             if (!vmsvgaR3FifoHasWork(pFIFO, pThis->svga.uLastCursorUpdateCount))
     6180            if (!vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount))
    38006181            {
    38016182                cMsSleep = RT_MIN(cMsSleep + cMsIncSleep, cMsMaxSleep);
     
    38066187            Log(("vmsvgaR3FifoLoop: timeout\n"));
    38076188        }
    3808         else if (vmsvgaR3FifoHasWork(pFIFO, pThis->svga.uLastCursorUpdateCount))
     6189        else if (vmsvgaR3FifoHasWork(pThisCC, pThis->svga.uLastCursorUpdateCount))
    38096190            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoWoken);
    38106191        cMsSleep = cMsMinSleep;
     
    38926273
    38936274        /*
     6275         * Process all submitted command buffers.
     6276         */
     6277        vmsvgaR3CmdBufProcessBuffers(pDevIns, pThis, pThisCC, pThread);
     6278
     6279        /*
    38946280         * Execute all queued FIFO commands.
    38956281         * Quit if pending external command or changes in the thread state.
     
    39156301             */
    39166302            /* '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 in
     6303             * warning. Because we implement some obsolete and deprecated commands, which are not included in
    39186304             * the SVGAFifoCmdId enum in the VMSVGA headers anymore.
    39196305             */
    39206306            uint32_t const enmCmdId = pFIFO[offCurrentCmd / sizeof(uint32_t)];
    39216307            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",
    39236309                     offCurrentCmd / sizeof(uint32_t), vmsvgaR3FifoCmdToString(enmCmdId), enmCmdId));
    39246310            switch (enmCmdId)
     
    39366322                if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin))
    39376323                {
    3938                     Log(("vmsvgaR3FifoLoop: SVGA_CMD_FENCE %x\n", pCmdFence->fence));
     6324                    Log(("vmsvgaR3FifoLoop: SVGA_CMD_FENCE %#x\n", pCmdFence->fence));
    39396325                    pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence;
    39406326
     
    39496335                        &&  pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence)
    39506336                    {
    3951                         Log(("vmsvgaR3FifoLoop: fence goal reached irq (fence=%x)\n", pCmdFence->fence));
     6337                        Log(("vmsvgaR3FifoLoop: fence goal reached irq (fence=%#x)\n", pCmdFence->fence));
    39526338                        u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
    39536339                    }
     
    39576343                break;
    39586344            }
     6345
    39596346            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
    39606354            case SVGA_CMD_UPDATE_VERBOSE:
    39616355            {
    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);
    39746359                break;
    39756360            }
     
    39786363            {
    39796364                /* 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);
    39906372                RT_UNTRUSTED_VALIDATED_FENCE();
    39916373
    3992                 uint32_t cbAndLine = RT_ALIGN_32(pCursor->width * (pCursor->andMaskDepth + (pCursor->andMaskDepth == 15)), 32) / 8;
    3993                 uint32_t cbAndMask = cbAndLine * pCursor->height;
    3994                 uint32_t cbXorLine = RT_ALIGN_32(pCursor->width * (pCursor->xorMaskDepth + (pCursor->xorMaskDepth == 15)), 32) / 8;
    3995                 uint32_t cbXorMask = 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);
    40006382                break;
    40016383            }
     
    40046386            {
    40056387                /* 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);
    40406397                break;
    40416398            }
     
    40486405                 * May be issued by guest if SVGA_CAP_CURSOR_BYPASS is missing.
    40496406                 */
    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);
    40566410                break;
    40576411            }
     
    40646418                 * May be issued by guest if SVGA_CAP_CURSOR_BYPASS is missing.
    40656419                 */
    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);
    40726423                break;
    40736424            }
     
    40756426            case SVGA_CMD_RECT_FILL:
    40766427            {
    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);
    40836431                break;
    40846432            }
     
    40866434            case SVGA_CMD_RECT_COPY:
    40876435            {
    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);
    41076439                break;
    41086440            }
     
    41106442            case SVGA_CMD_RECT_ROP_COPY:
    41116443            {
    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);
    41426447                break;
    41436448            }
     
    41456450            case SVGA_CMD_ESCAPE:
    41466451            {
    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));
    41546457                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);
    41996462                break;
    42006463            }
     
    42046467                SVGAFifoCmdDefineGMR2 *pCmd;
    42056468                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);
    42346470                break;
    42356471            }
     
    42406476                SVGAFifoCmdRemapGMR2 *pCmd;
    42416477                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();
    42476478
    42486479                /* Calculate the size of what comes after next and fetch it. */
     
    42606491                    else
    42616492                    {
    4262                         AssertBreak(pCmd->numPages <= pThis->svga.cbFIFO / cbPageDesc);
     6493                        ASSERT_GUEST_BREAK(pCmd->numPages <= pThis->svga.cbFIFO / cbPageDesc);
    42636494                        cbCmd += cbPageDesc * pCmd->numPages;
    42646495                    }
    42656496                }
    42666497                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);
    43886499#  ifdef DEBUG_GMR_ACCESS
    43896500                VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3RegisterGmr, 2, pDevIns, pCmd->gmrId);
     
    44046515                RT_BZERO(&pCmd->screen.id, sizeof(*pCmd) - RT_OFFSETOF(SVGAFifoCmdDefineScreen, screen.id));
    44056516                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);
    44666518                break;
    44676519            }
     
    44716523                SVGAFifoCmdDestroyScreen *pCmd;
    44726524                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);
    44916526                break;
    44926527            }
     
    44966531                SVGAFifoCmdDefineGMRFB *pCmd;
    44976532                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);
    45046534                break;
    45056535            }
     
    45096539                SVGAFifoCmdBlitGMRFBToScreen *pCmd;
    45106540                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);
    45756542                break;
    45766543            }
     
    45806547                SVGAFifoCmdBlitScreenToGMRFB *pCmd;
    45816548                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);
    46466550                break;
    46476551            }
     
    46516555                SVGAFifoCmdAnnotationFill *pCmd;
    46526556                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);
    46576558                break;
    46586559            }
     
    46626563                SVGAFifoCmdAnnotationCopy *pCmd;
    46636564                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);
    46686566                break;
    46696567            }
     
    46916589                    else
    46926590                    {
    4693                         LogRelMax(8, ("VMSVGA3d: 3D disabled, command %d skipped\n", enmCmdId));
     6591                        LogRelMax(8, ("VMSVGA: 3D disabled, command %d skipped\n", enmCmdId));
    46946592                        break;
    46956593                    }
    46966594
    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);
    51286596                }
    51296597                else
     
    51936661}
    51946662
    5195 #undef VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK
    51966663#undef VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK
    51976664#undef VMSVGAFIFO_GET_CMD_BUFFER_BREAK
     
    58807347    pHlp->pfnPrintf(pHlp, "Pitch lock:         %#x (FIFO:%#x)\n", pThis->svga.u32PitchLock, pFIFO[SVGA_FIFO_PITCHLOCK]);
    58817348    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);
    58837350    pHlp->pfnPrintf(pHlp, "Index reg:          %#x\n", pThis->svga.u32IndexReg);
    58847351    pHlp->pfnPrintf(pHlp, "Action flags:       %#x\n", pThis->svga.u32ActionFlags);
     
    62707737        pSVGAState->paGMR = NULL;
    62717738    }
     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    }
    62727752}
    62737753
     
    62937773# endif
    62947774
     7775    rc = RTCritSectInit(&pSVGAState->CritSectCmdBuf);
     7776    AssertRCReturn(rc, rc);
     7777
     7778    vmsvgaR3CmdBufCtxInit(&pSVGAState->CmdBufCtxDC);
    62957779    return rc;
    62967780}
    62977781
    62987782/**
    6299  * Initializes the host capabilities: registers and FIFO.
     7783 * Initializes the host capabilities: device and FIFO.
    63007784 *
    63017785 * @returns VBox status code.
     
    63057789static void vmsvgaR3InitCaps(PVGASTATE pThis, PVGASTATECC pThisCC)
    63067790{
    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
    63207812# ifdef VBOX_WITH_VMSVGA3D
    6321     pThis->svga.u32RegCaps |= SVGA_CAP_3D;
     7813    pThis->svga.u32DeviceCaps |= SVGA_CAP_3D;
    63227814# endif
    63237815
     
    63277819    /* Setup FIFO capabilities. */
    63287820    pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE
    6329                                                 | SVGA_FIFO_CAP_CURSOR_BYPASS_3
    6330                                                 | SVGA_FIFO_CAP_GMR2
    6331                                                 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED
    6332                                                 | SVGA_FIFO_CAP_SCREEN_OBJECT_2
    6333                                                 | SVGA_FIFO_CAP_RESERVE
    6334                                                 | 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;
    63357827
    63367828    /* Valid with SVGA_FIFO_CAP_SCREEN_OBJECT_2 */
     
    64267918    "xSURFACEFMT_ATI1",
    64277919    "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",
    64288080};
    64298081
    64308082/**
    6431  * Initializes the host 3D capabilities in FIFO.
     8083 * Initializes the host 3D capabilities and writes them to FIFO memory.
    64328084 *
    64338085 * @returns VBox status code.
     
    64358087 * @param   pThisCC   The VGA/VMSVGA state for ring-3.
    64368088 */
    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;
     8089static 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);
    64448124
    64458125    /* 3d hardware version; latest and greatest */
     
    64478127    pThisCC->svga.pau32FIFO[SVGA_FIFO_3D_HWVERSION]         = SVGA3D_HWVERSION_CURRENT;
    64488128
     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
    64498137    pCaps = (SVGA3dCapsRecord *)&pThisCC->svga.pau32FIFO[SVGA_FIFO_3D_CAPS];
    64508138    pCaps->header.type   = SVGA3DCAPS_RECORD_DEVCAPS;
    64518139    pData = (SVGA3dCapPair *)&pCaps->data;
    64528140
    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      */
    64588141    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);
    64798148    pCaps = (SVGA3dCapsRecord *)((uint32_t *)pCaps + pCaps->header.length);
    64808149
    6481     /* Mark end of record array. */
     8150    /* Mark end of record array (a zero word). */
    64828151    pCaps->header.length = 0;
    6483 
    6484     RTLogRelSetBuffering(fSavedBuffering);
    64858152}
    64868153
     
    65238190# ifdef VBOX_WITH_VMSVGA3D
    65248191    if (pThis->svga.f3DEnabled)
    6525         vmsvgaR3InitFifo3DCaps(pThisCC);
     8192        vmsvgaR3InitFifo3DCaps(pThis, pThisCC);
    65268193# endif
    65278194
     
    68218488    REG_CNT(&pThis->svga.StatRegUnknownWr,                "VMSVGA/Reg/UnknownWrite",               "Writes to unknown register.");
    68228489    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.");
    68238495
    68248496    REG_CNT(&pThis->svga.StatRegBitsPerPixelRd,           "VMSVGA/Reg/BitsPerPixelRead",           "SVGA_REG_BITS_PER_PIXEL reads.");
     
    68748546    REG_CNT(&pThis->svga.StatRegWidthRd,                  "VMSVGA/Reg/WidthRead",                  "SVGA_REG_WIDTH reads.");
    68758547    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.");
    68768558
    68778559    REG_PRF(&pSVGAState->StatBusyDelayEmts,               "VMSVGA/EmtDelayOnBusyFifo",             "Time we've delayed EMTs because of busy FIFO thread.");
     
    69308612    {
    69318613        int rc = vmsvga3dPowerOn(pDevIns, pThis, pThisCC);
    6932 
    69338614        if (RT_SUCCESS(rc))
    69348615        {
    69358616            /* Initialize FIFO 3D capabilities. */
    6936             vmsvgaR3InitFifo3DCaps(pThisCC);
     8617            vmsvgaR3InitFifo3DCaps(pThis, pThisCC);
    69378618        }
    69388619    }
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h

    r86025 r86193  
    301301    /** Current GMR id. (SVGA_REG_GMR_ID) */
    302302    uint32_t                    u32CurrentGMRId;
    303     /** Register caps. */
    304     uint32_t                    u32RegCaps;
     303    /** SVGA device capabilities. */
     304    uint32_t                    u32DeviceCaps;
    305305    uint32_t                    Padding0; /* Used to be I/O port base address. */
    306306    /** Port io index register. */
     
    367367    uint32_t                    au32ScratchRegion[VMSVGA_SCRATCH_SIZE];
    368368
     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
    369376    STAMCOUNTER                 StatRegBitsPerPixelWr;
    370377    STAMCOUNTER                 StatRegBusyWr;
     
    398405    STAMCOUNTER                 StatRegUnknownWr;
    399406    STAMCOUNTER                 StatRegWidthWr;
     407    STAMCOUNTER                 StatRegCommandLowWr;
     408    STAMCOUNTER                 StatRegCommandHighWr;
     409    STAMCOUNTER                 StatRegDevCapWr;
     410    STAMCOUNTER                 StatRegCmdPrependLowWr;
     411    STAMCOUNTER                 StatRegCmdPrependHighWr;
    400412
    401413    STAMCOUNTER                 StatRegBitsPerPixelRd;
     
    451463    STAMCOUNTER                 StatRegWidthRd;
    452464    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;
    453475} VMSVGAState, VMSVGASTATE;
    454476
Note: See TracChangeset for help on using the changeset viewer.

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