Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/VBox/Devices/Graphics/DevVGA-SVGA-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ typedef struct VMSVGAR3STATE
STAMPROFILE StatR3Cmd3dDrawPrimitivesProf;
STAMPROFILE StatR3Cmd3dSurfaceDmaProf;
STAMPROFILE StatR3Cmd3dBlitSurfaceToScreenProf;
STAMPROFILE StatR3DxStartScreenReadbackProf;
STAMPROFILE StatR3DxProcessPendingUpdatesProf;
STAMPROFILE StatR3DxOutputTargetConvertProf;
STAMPROFILE StatR3DxOutputTargetReadbackProf;
STAMCOUNTER StatR3CmdDefineGmr2;
STAMCOUNTER StatR3CmdDefineGmr2Free;
STAMCOUNTER StatR3CmdDefineGmr2Modify;
Expand Down Expand Up @@ -271,6 +275,16 @@ typedef struct VMSVGAR3STATE
STAMCOUNTER StatR3Cmd3dGenerateMipmaps;
STAMCOUNTER StatR3Cmd3dActivateSurface;
STAMCOUNTER StatR3Cmd3dDeactivateSurface;
STAMCOUNTER StatR3DxStartScreenReadback;
STAMCOUNTER StatR3DxReadbackPoll;
STAMCOUNTER StatR3DxReadbackReady;
STAMCOUNTER StatR3DxReadbackUpdateRects;
STAMCOUNTER StatR3DxReadbackUpdateMerge;
STAMCOUNTER StatR3DxReadbackRestart;
STAMCOUNTER StatR3DxReadbackChanged;
STAMCOUNTER StatR3DxReadbackUnchanged;
STAMCOUNTER StatR3DxOutputTargetConvert;
STAMCOUNTER StatR3DxOutputTargetReadback;

STAMCOUNTER StatR3RegConfigDoneWr;
STAMCOUNTER StatR3RegGmrDescriptorWr;
Expand Down
14 changes: 14 additions & 0 deletions src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8684,6 +8684,10 @@ int vmsvgaR3Init(PPDMDEVINS pDevIns)
REG_PRF(&pSVGAState->StatR3Cmd3dSurfaceDmaProf, "VMSVGA/Cmd/3dSurfaceDmaProf", "Profiling of SVGA_3D_CMD_SURFACE_DMA.");
# endif
REG_PRF(&pSVGAState->StatR3Cmd3dBlitSurfaceToScreenProf, "VMSVGA/Cmd/3dBlitSurfaceToScreenProf", "Profiling of SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN.");
REG_PRF(&pSVGAState->StatR3DxStartScreenReadbackProf, "VMSVGA/DX/StartScreenReadbackProf", "Profiling of DX screen readback submission.");
REG_PRF(&pSVGAState->StatR3DxProcessPendingUpdatesProf, "VMSVGA/DX/ProcessPendingUpdatesProf", "Profiling of DX pending screen update processing.");
REG_PRF(&pSVGAState->StatR3DxOutputTargetConvertProf, "VMSVGA/DX/OutputTargetConvertProf", "Profiling of DX output target conversion.");
REG_PRF(&pSVGAState->StatR3DxOutputTargetReadbackProf, "VMSVGA/DX/OutputTargetReadbackProf", "Profiling of DX output target readback.");
REG_CNT(&pSVGAState->StatR3Cmd3dActivateSurface, "VMSVGA/Cmd/3dActivateSurface", "SVGA_3D_CMD_ACTIVATE_SURFACE");
REG_CNT(&pSVGAState->StatR3Cmd3dBeginQuery, "VMSVGA/Cmd/3dBeginQuery", "SVGA_3D_CMD_BEGIN_QUERY");
REG_CNT(&pSVGAState->StatR3Cmd3dClear, "VMSVGA/Cmd/3dClear", "SVGA_3D_CMD_CLEAR");
Expand Down Expand Up @@ -8718,6 +8722,16 @@ int vmsvgaR3Init(PPDMDEVINS pDevIns)
REG_CNT(&pSVGAState->StatR3Cmd3dSurfaceScreen, "VMSVGA/Cmd/3dSurfaceScreen", "SVGA_3D_CMD_SURFACE_SCREEN");
REG_CNT(&pSVGAState->StatR3Cmd3dSurfaceStretchBlt, "VMSVGA/Cmd/3dSurfaceStretchBlt", "SVGA_3D_CMD_SURFACE_STRETCHBLT");
REG_CNT(&pSVGAState->StatR3Cmd3dWaitForQuery, "VMSVGA/Cmd/3dWaitForQuery", "SVGA_3D_CMD_WAIT_FOR_QUERY");
REG_CNT(&pSVGAState->StatR3DxStartScreenReadback, "VMSVGA/DX/StartScreenReadback", "DX screen readback submissions.");
REG_CNT(&pSVGAState->StatR3DxReadbackPoll, "VMSVGA/DX/ReadbackPoll", "DX screen readback query polls.");
REG_CNT(&pSVGAState->StatR3DxReadbackReady, "VMSVGA/DX/ReadbackReady", "DX screen readback query completions.");
REG_CNT(&pSVGAState->StatR3DxReadbackUpdateRects, "VMSVGA/DX/ReadbackUpdateRects", "DX screen update rectangles processed after readback.");
REG_CNT(&pSVGAState->StatR3DxReadbackUpdateMerge, "VMSVGA/DX/ReadbackUpdateMerge", "DX pending screen update rectangles merged before readback.");
REG_CNT(&pSVGAState->StatR3DxReadbackRestart, "VMSVGA/DX/ReadbackRestart", "DX readbacks restarted due to queued updates.");
REG_CNT(&pSVGAState->StatR3DxReadbackChanged, "VMSVGA/DX/ReadbackChanged", "DX output target readbacks that changed host-visible pixels.");
REG_CNT(&pSVGAState->StatR3DxReadbackUnchanged, "VMSVGA/DX/ReadbackUnchanged", "DX output target readbacks that did not change host-visible pixels.");
REG_CNT(&pSVGAState->StatR3DxOutputTargetConvert, "VMSVGA/DX/OutputTargetConvert", "DX output target conversions.");
REG_CNT(&pSVGAState->StatR3DxOutputTargetReadback, "VMSVGA/DX/OutputTargetReadback", "DX output target readbacks.");
REG_CNT(&pSVGAState->StatR3CmdAnnotationCopy, "VMSVGA/Cmd/AnnotationCopy", "SVGA_CMD_ANNOTATION_COPY");
REG_CNT(&pSVGAState->StatR3CmdAnnotationFill, "VMSVGA/Cmd/AnnotationFill", "SVGA_CMD_ANNOTATION_FILL");
REG_CNT(&pSVGAState->StatR3CmdBlitGmrFbToScreen, "VMSVGA/Cmd/BlitGmrFbToScreen", "SVGA_CMD_BLIT_GMRFB_TO_SCREEN");
Expand Down
69 changes: 54 additions & 15 deletions src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11-output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <VBox/log.h>

#include <iprt/mem.h>
#include <iprt/string.h>

#ifdef RT_OS_WINDOWS
# include <iprt/win/windows.h>
Expand All @@ -53,10 +54,12 @@ typedef struct DXOUTPUTTARGETMETHODS
DECLR3CALLBACKMEMBER(int, pfnDXOutputTargetConvert,(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
ID3D11ShaderResourceView *pSrcSrv,
UINT srcW, UINT srcH));
UINT srcW, UINT srcH,
SVGASignedRect const &dirtyRect));
DECLR3CALLBACKMEMBER(int, pfnDXOutputTargetReadback,(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
SVGASignedRect const &updateRect));
SVGASignedRect const &updateRect,
bool *pfChanged));
} DXOUTPUTTARGETMETHODS;

/* Generic OT object with target specific data and virtual methods. */
Expand Down Expand Up @@ -134,15 +137,30 @@ static DECLCALLBACK(void) dxOutputTargetDestroy_B8G8R8X8_I(VMSVGAOUTPUTTARGET *p
static DECLCALLBACK(int) dxOutputTargetConvert_B8G8R8X8_I(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
ID3D11ShaderResourceView *pSrcSrv,
UINT srcW, UINT srcH)
UINT srcW, UINT srcH,
SVGASignedRect const &dirtyRect)
{
RT_NOREF(srcW, srcH);

DXOUTPUTTARGET_B8G8R8X8_I *pThis = (DXOUTPUTTARGET_B8G8R8X8_I *)pOutputTarget->pHwOutputTarget;

SVGASignedRect clipRect = dirtyRect;
SVGASignedRect const boundRect = { 0, 0, (int32_t)srcW, (int32_t)srcH };
vmsvgaR3ClipRect(&boundRect, &clipRect);
if (clipRect.left >= clipRect.right || clipRect.top >= clipRect.bottom)
return VINF_SUCCESS;

D3D11_BOX srcBox;
srcBox.left = (UINT)clipRect.left;
srcBox.top = (UINT)clipRect.top;
srcBox.front = 0;
srcBox.right = (UINT)clipRect.right;
srcBox.bottom = (UINT)clipRect.bottom;
srcBox.back = 1;

ID3D11Resource *pSrcResource = NULL;
pSrcSrv->GetResource(&pSrcResource);
pDeviceContext->CopySubresourceRegion(pThis->pStagingTexture, 0, 0, 0, 0, pSrcResource, 0, NULL);
pDeviceContext->CopySubresourceRegion(pThis->pStagingTexture, 0,
(UINT)clipRect.left, (UINT)clipRect.top, 0,
pSrcResource, 0, &srcBox);
D3D_RELEASE(pSrcResource);

return VINF_SUCCESS;
Expand All @@ -151,9 +169,11 @@ static DECLCALLBACK(int) dxOutputTargetConvert_B8G8R8X8_I(VMSVGAOUTPUTTARGET *pO

static DECLCALLBACK(int) dxOutputTargetReadback_B8G8R8X8_I(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
SVGASignedRect const &updateRect)
SVGASignedRect const &updateRect,
bool *pfChanged)
{
DXOUTPUTTARGET_B8G8R8X8_I *pThis = (DXOUTPUTTARGET_B8G8R8X8_I *)pOutputTarget->pHwOutputTarget;
*pfChanged = false;

/* Copy data from staging resource to the system memory. */
D3D11_MAPPED_SUBRESOURCE map;
Expand All @@ -175,7 +195,12 @@ static DECLCALLBACK(int) dxOutputTargetReadback_B8G8R8X8_I(VMSVGAOUTPUTTARGET *p
&& updateRect.bottom == (int32_t)cHeight
&& cWidth * cbPixel == map.RowPitch)
{
memcpy(pu8Dst, pu8Src, map.RowPitch * cHeight);
size_t const cb = (size_t)map.RowPitch * cHeight;
if (memcmp(pu8Dst, pu8Src, cb) != 0)
{
memcpy(pu8Dst, pu8Src, cb);
*pfChanged = true;
}
}
else
{
Expand All @@ -189,7 +214,11 @@ static DECLCALLBACK(int) dxOutputTargetReadback_B8G8R8X8_I(VMSVGAOUTPUTTARGET *p
uint32_t const cbRowWidth = cbPixel * (updateRect.right - updateRect.left);
for (int32_t iRow = 0; iRow < updateRect.bottom - updateRect.top; ++iRow)
{
memcpy(pu8DstBox, pu8SrcBox, cbRowWidth);
if (memcmp(pu8DstBox, pu8SrcBox, cbRowWidth) != 0)
{
memcpy(pu8DstBox, pu8SrcBox, cbRowWidth);
*pfChanged = true;
}

pu8SrcBox += map.RowPitch;
pu8DstBox += cbPixel * cWidth;
Expand Down Expand Up @@ -404,8 +433,11 @@ static DECLCALLBACK(void) dxOutputTargetDestroy_I420(VMSVGAOUTPUTTARGET *pOutput
static DECLCALLBACK(int) dxOutputTargetConvert_I420(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
ID3D11ShaderResourceView *pSrcSrv,
UINT srcW, UINT srcH)
UINT srcW, UINT srcH,
SVGASignedRect const &dirtyRect)
{
RT_NOREF(dirtyRect);

DXOUTPUTTARGET_I420 *pHwOutputTarget = (DXOUTPUTTARGET_I420 *)pOutputTarget->pHwOutputTarget;

/* Save/restore pipeline state.
Expand Down Expand Up @@ -537,9 +569,11 @@ static int dxCopyPlane(ID3D11DeviceContext1 *pDeviceContext,

static DECLCALLBACK(int) dxOutputTargetReadback_I420(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
SVGASignedRect const &updateRect)
SVGASignedRect const &updateRect,
bool *pfChanged)
{
RT_NOREF(updateRect);
*pfChanged = true;

DXOUTPUTTARGET_I420 *pHwOutputTarget = (DXOUTPUTTARGET_I420 *)pOutputTarget->pHwOutputTarget;

Expand Down Expand Up @@ -663,19 +697,24 @@ void dxHwOutputTargetDestroy(VMSVGAOUTPUTTARGET *pOutputTarget)
int dxHwOutputTargetConvert(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
ID3D11ShaderResourceView *pSrcSrv,
UINT srcW, UINT srcH)
UINT srcW, UINT srcH,
SVGASignedRect const &dirtyRect)
{
VMSVGAHWOUTPUTTARGET *pHwOutputTarget = pOutputTarget->pHwOutputTarget;
if (pHwOutputTarget->methods.pfnDXOutputTargetConvert)
return pHwOutputTarget->methods.pfnDXOutputTargetConvert(pOutputTarget, pDeviceContext, pSrcSrv, srcW, srcH);
return pHwOutputTarget->methods.pfnDXOutputTargetConvert(pOutputTarget, pDeviceContext, pSrcSrv,
srcW, srcH, dirtyRect);
return VINF_SUCCESS;
}


int dxHwOutputTargetReadback(VMSVGAOUTPUTTARGET *pOutputTarget,
ID3D11DeviceContext1 *pDeviceContext,
SVGASignedRect const &updateRect)
SVGASignedRect const &updateRect,
bool *pfChanged)
{
*pfChanged = false;

SVGASignedRect clipRect = updateRect;
SVGASignedRect const boundRect = { 0 , 0, (int32_t)pOutputTarget->desc.cWidth, (int32_t)pOutputTarget->desc.cHeight };
vmsvgaR3ClipRect(&boundRect, &clipRect);
Expand All @@ -684,6 +723,6 @@ int dxHwOutputTargetReadback(VMSVGAOUTPUTTARGET *pOutputTarget,

VMSVGAHWOUTPUTTARGET *pHwOutputTarget = pOutputTarget->pHwOutputTarget;
if (pHwOutputTarget->methods.pfnDXOutputTargetReadback)
return pHwOutputTarget->methods.pfnDXOutputTargetReadback(pOutputTarget, pDeviceContext, clipRect);
return pHwOutputTarget->methods.pfnDXOutputTargetReadback(pOutputTarget, pDeviceContext, clipRect, pfChanged);
return VINF_SUCCESS;
}
Loading