VirtualBox

Changeset 73736 in vbox for trunk


Ignore:
Timestamp:
Aug 17, 2018 1:51:09 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124417
Message:

DevVGA-SVGA: simplified creation of per context device windows; implement SVGA_3D_CMD_PRESENT using SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN.

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

Legend:

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

    r73633 r73736  
    28022802}
    28032803
    2804 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
    2805 {
    2806     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    2807     PVMSVGA3DSURFACE    pSurface;
    2808     PVMSVGA3DCONTEXT    pContext;
    2809     uint32_t            cid;
    2810 
    2811     AssertReturn(pState, VERR_NO_MEMORY);
    2812     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
    2813     AssertReturn(sid < pState->cSurfaces && pState->papSurfaces[sid]->id == sid, VERR_INVALID_PARAMETER);
    2814 
    2815     pSurface = pState->papSurfaces[sid];
    2816 
    2817     Log(("vmsvga3dCommandPresent: sid=%x cRects=%d\n", sid, cRects));
    2818     for (uint32_t i=0; i < cRects; i++)
    2819         Log(("vmsvga3dCommandPresent: rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
    2820 
    2821     pContext = &pState->SharedCtx;
    2822     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    2823     cid = pContext->id;
    2824     VMSVGA3D_CLEAR_GL_ERRORS();
    2825 
    2826 #if 0 /* Can't make sense of this. SVGA3dCopyRect doesn't allow scaling.  non-blit-cube path change to not use it. */
    2827     /*
    2828      * Source surface different size?
    2829      */
    2830     RTRECT2 srcViewPort;
    2831     if (   pSurface->pMipmapLevels[0].size.width  != pThis->svga.uWidth
    2832         || pSurface->pMipmapLevels[0].size.height != pThis->svga.uHeight)
    2833     {
    2834         float xMultiplier = (float)pSurface->pMipmapLevels[0].size.width  / (float)pThis->svga.uWidth;
    2835         float yMultiplier = (float)pSurface->pMipmapLevels[0].size.height / (float)pThis->svga.uHeight;
    2836 
    2837         LogFlow(("size (%d vs %d, %d vs %d) multiplier (" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
    2838                  pSurface->pMipmapLevels[0].size.width, pThis->svga.uWidth,
    2839                  pSurface->pMipmapLevels[0].size.height, pThis->svga.uHeight,
    2840                  FLOAT_FMT_ARGS(xMultiplier), FLOAT_FMT_ARGS(yMultiplier) ));
    2841 
    2842         srcViewPort.x  = (uint32_t)((float)pThis->svga.viewport.x  * xMultiplier);
    2843         srcViewPort.y  = (uint32_t)((float)pThis->svga.viewport.y  * yMultiplier);
    2844         srcViewPort.cx = (uint32_t)((float)pThis->svga.viewport.cx * xMultiplier);
    2845         srcViewPort.cy = (uint32_t)((float)pThis->svga.viewport.cy * yMultiplier);
    2846     }
    2847     else
    2848     {
    2849         srcViewPort.x  = pThis->svga.viewport.x;
    2850         srcViewPort.y  = pThis->svga.viewport.y;
    2851         srcViewPort.cx = pThis->svga.viewport.cx;
    2852         srcViewPort.cy = pThis->svga.viewport.cy;
    2853     }
    2854     RTRECT SrcViewPortRect;
    2855     SrcViewPortRect.xLeft   = srcViewPort.x;
    2856     SrcViewPortRect.xRight  = srcViewPort.x + srcViewPort.cx;
    2857     SrcViewPortRect.yBottom = srcViewPort.y;
    2858     SrcViewPortRect.yTop    = srcViewPort.y + srcViewPort.cy;
    2859 #endif
    2860 
    2861 
    2862 #if 0//ndef RT_OS_DARWIN /* blit-cube fails in this path... */
    2863     /*
    2864      * Note! this path is slightly faster than the glBlitFrameBuffer path below.
    2865      */
    2866     SVGA3dCopyRect rect;
    2867     uint32_t oldVShader, oldPShader;
    2868     GLint oldTextureId;
    2869 
    2870     if (cRects == 0)
    2871     {
    2872         rect.x = rect.y = rect.srcx = rect.srcy = 0;
    2873         rect.w = pSurface->pMipmapLevels[0].size.width;
    2874         rect.h = pSurface->pMipmapLevels[0].size.height;
    2875         pRect  = &rect;
    2876         cRects = 1;
    2877     }
    2878 
    2879     //glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
    2880 
    2881 #if 0
    2882     glDisable(GL_CULL_FACE);
    2883     glDisable(GL_BLEND);
    2884     glDisable(GL_ALPHA_TEST);
    2885     glDisable(GL_SCISSOR_TEST);
    2886     glDisable(GL_STENCIL_TEST);
    2887     glEnable(GL_DEPTH_TEST);
    2888     glDepthFunc(GL_ALWAYS);
    2889     glDepthMask(GL_TRUE);
    2890     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    2891     glViewport(0, 0, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height);
    2892 #endif
    2893 
    2894     VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureId), pState, pContext);
    2895 
    2896     oldVShader = pContext->state.shidVertex;
    2897     oldPShader = pContext->state.shidPixel;
    2898     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, SVGA_ID_INVALID);
    2899     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, SVGA_ID_INVALID);
    2900 
    2901     /* Flush shader changes. */
    2902     if (pContext->pShaderContext)
    2903         ShaderUpdateState(pContext->pShaderContext, 0);
    2904 
    2905     /* Activate the read and draw framebuffer objects. */
    2906     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer), pState, pContext);
    2907     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 /* back buffer */), pState, pContext);
    2908 
    2909     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glActiveTexture(GL_TEXTURE0), pState, pContext);
    2910     VMSVGA3D_ASSERT_GL_CALL(glEnable(GL_TEXTURE_2D), pState, pContext);;
    2911     VMSVGA3D_ASSERT_GL_CALL(glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture), pState, pContext);
    2912 
    2913     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR), pState, pContext);
    2914     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR), pState, pContext);;
    2915 
    2916 #if 0
    2917     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP), pState, pContext);;
    2918     VMSVGA3D_ASSERT_GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP), pState, pContext);;
    2919 #endif
    2920 
    2921     /* Reset the transformation matrices. */
    2922     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_MODELVIEW), pState, pContext);
    2923     VMSVGA3D_ASSERT_GL_CALL(glPushMatrix(), pState, pContext);
    2924     VMSVGA3D_ASSERT_GL_CALL(glLoadIdentity(), pState, pContext);
    2925     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_PROJECTION), pState, pContext);
    2926     VMSVGA3D_ASSERT_GL_CALL(glPushMatrix(), pState, pContext);
    2927     VMSVGA3D_ASSERT_GL_CALL(glLoadIdentity(), pState, pContext);
    2928     VMSVGA3D_ASSERT_GL_CALL(glScalef(1.0f, -1.0f, 1.0f), pState, pContext);
    2929     VMSVGA3D_ASSERT_GL_CALL(glOrtho(0, pThis->svga.uWidth, pThis->svga.uHeight, 0, 0.0, -1.0), pState, pContext);
    2930 
    2931     for (uint32_t i = 0; i < cRects; i++)
    2932     {
    2933         float left, right, top, bottom; /* Texture coordinates */
    2934         int   vertexLeft, vertexRight, vertexTop, vertexBottom;
    2935 
    2936         pRect[i].srcx = RT_MAX(pRect[i].srcx, (uint32_t)RT_MAX(srcViewPort.x, 0));
    2937         pRect[i].srcy = RT_MAX(pRect[i].srcy, (uint32_t)RT_MAX(srcViewPort.y, 0));
    2938         pRect[i].x    = RT_MAX(pRect[i].x, pThis->svga.viewport.x) - pThis->svga.viewport.x;
    2939         pRect[i].y    = RT_MAX(pRect[i].y, pThis->svga.viewport.y) - pThis->svga.viewport.y;
    2940         pRect[i].w    = pThis->svga.viewport.cx;
    2941         pRect[i].h    = pThis->svga.viewport.cy;
    2942 
    2943         if (    pRect[i].x + pRect[i].w <= pThis->svga.viewport.x
    2944             ||  pThis->svga.viewport.x + pThis->svga.viewport.cx <= pRect[i].x
    2945             ||  pRect[i].y + pRect[i].h <= pThis->svga.viewport.y
    2946             ||  pThis->svga.viewport.y + pThis->svga.viewport.cy <= pRect[i].y)
    2947         {
    2948             /* Intersection is empty; skip */
    2949             continue;
    2950         }
    2951 
    2952         left   = pRect[i].srcx;
    2953         right  = pRect[i].srcx + pRect[i].w;
    2954         top    = pRect[i].srcy + pRect[i].h;
    2955         bottom = pRect[i].srcy;
    2956 
    2957         left   /= pSurface->pMipmapLevels[0].size.width;
    2958         right  /= pSurface->pMipmapLevels[0].size.width;
    2959         top    /= pSurface->pMipmapLevels[0].size.height;
    2960         bottom /= pSurface->pMipmapLevels[0].size.height;
    2961 
    2962         vertexLeft   = pRect[i].x;
    2963         vertexRight  = pRect[i].x + pRect[i].w;
    2964         vertexTop    = ((uint32_t)pThis->svga.uHeight >= pRect[i].y + pRect[i].h) ? pThis->svga.uHeight - pRect[i].y - pRect[i].h : 0;
    2965         vertexBottom = pThis->svga.uHeight - pRect[i].y;
    2966 
    2967         Log(("view port (%d,%d)(%d,%d)\n", srcViewPort.x, srcViewPort.y, srcViewPort.cx, srcViewPort.cy));
    2968         Log(("vertex (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", vertexLeft, vertexBottom, vertexLeft, vertexTop, vertexRight, vertexTop, vertexRight, vertexBottom));
    2969         Log(("texture (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h), pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h)));
    2970 
    2971         glBegin(GL_QUADS);
    2972 
    2973         /* bottom left */
    2974         glTexCoord2f(left, bottom);
    2975         glVertex2i(vertexLeft, vertexBottom);
    2976 
    2977         /* top left */
    2978         glTexCoord2f(left, top);
    2979         glVertex2i(vertexLeft, vertexTop);
    2980 
    2981         /* top right */
    2982         glTexCoord2f(right, top);
    2983         glVertex2i(vertexRight, vertexTop);
    2984 
    2985         /* bottom right */
    2986         glTexCoord2f(right, bottom);
    2987         glVertex2i(vertexRight, vertexBottom);
    2988 
    2989         VMSVGA3D_ASSERT_GL_CALL(glEnd(), pState, pContext);
    2990     }
    2991 
    2992     /* Restore old settings. */
    2993     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_PROJECTION), pState, pContext);
    2994     VMSVGA3D_ASSERT_GL_CALL(glPopMatrix(), pState, pContext);
    2995     VMSVGA3D_ASSERT_GL_CALL(glMatrixMode(GL_MODELVIEW), pState, pContext);
    2996     VMSVGA3D_ASSERT_GL_CALL(glPopMatrix(), pState, pContext);
    2997 
    2998     //VMSVGA3D_ASSERT_GL_CALL(glPopAttrib(), pState, pContext);
    2999 
    3000     VMSVGA3D_ASSERT_GL_CALL(glBindTexture(GL_TEXTURE_2D, oldTextureId), pState, pContext);
    3001     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, oldVShader);
    3002     vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, oldPShader);
    3003 
    3004 #else
    3005     /*
    3006      * glBlitFramebuffer variant.
    3007      */
    3008     /* Activate the read and draw framebuffer objects. */
    3009     pState->ext.glBindFramebuffer(GL_READ_FRAMEBUFFER, pContext->idReadFramebuffer);
    3010     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3011     pState->ext.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 /* back buffer */);
    3012     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3013 
    3014     /* Bind the source objects to the right place. */
    3015     Assert(pSurface->targetGL == GL_TEXTURE_2D);
    3016     pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurface->oglId.texture, 0 /* level 0 */);
    3017     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
    3018 
    3019 
    3020     /* Read the destination viewport specs in one go to try avoid some unnecessary update races. */
    3021     VMSVGAVIEWPORT const DstViewport   = pThis->svga.viewport;
    3022     ASMCompilerBarrier(); /* paranoia */
    3023     Assert(DstViewport.yHighWC >= DstViewport.yLowWC);
    3024 
    3025     /* If there are no recangles specified, just grab a screenful. */
    3026     SVGA3dCopyRect DummyRect;
    3027     if (cRects != 0)
    3028     { /* likely */ }
    3029     else
    3030     {
    3031         /** @todo Find the usecase for this or check what the original device does.
    3032          *        The original code was doing some scaling based on the surface
    3033          *        size... */
    3034 # ifdef DEBUG_bird
    3035         AssertMsgFailed(("No rects to present. Who is doing that and what do they actually expect?\n"));
    3036 # endif
    3037         DummyRect.x = DummyRect.srcx = 0;
    3038         DummyRect.y = DummyRect.srcy = 0;
    3039         DummyRect.w = pThis->svga.uWidth;
    3040         DummyRect.h = pThis->svga.uHeight;
    3041         cRects = 1;
    3042         pRect  = &DummyRect;
    3043     }
    3044 
    3045     /*
    3046      * Blit the surface rectangle(s) to the back buffer.
    3047      */
    3048     uint32_t const cxSurface = pSurface->pMipmapLevels[0].mipmapSize.width;
    3049     uint32_t const cySurface = pSurface->pMipmapLevels[0].mipmapSize.height;
    3050     for (uint32_t i = 0; i < cRects; i++)
    3051     {
    3052         SVGA3dCopyRect ClippedRect = pRect[i];
    3053 
    3054         /*
    3055          * Do some sanity checking and limit width and height, all so we
    3056          * don't need to think about wrap-arounds below.
    3057          */
    3058         if (RT_LIKELY(   ClippedRect.w
    3059                       && ClippedRect.x    < VMSVGA_MAX_X
    3060                       && ClippedRect.srcx < VMSVGA_MAX_X
    3061                       && ClippedRect.h
    3062                       && ClippedRect.y    < VMSVGA_MAX_Y
    3063                       && ClippedRect.srcy < VMSVGA_MAX_Y
    3064                          ))
    3065         { /* likely */ }
    3066         else
    3067             continue;
    3068 
    3069         if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_X))
    3070         { /* likely */ }
    3071         else
    3072             ClippedRect.w = VMSVGA_MAX_X;
    3073         if (RT_LIKELY(ClippedRect.h < VMSVGA_MAX_Y))
    3074         { /* likely */ }
    3075         else
    3076             ClippedRect.h = VMSVGA_MAX_Y;
    3077 
    3078 
    3079         /*
    3080          * Source surface clipping (paranoia). Straight forward.
    3081          */
    3082         if (RT_LIKELY(ClippedRect.srcx < cxSurface))
    3083         { /* likely */ }
    3084         else
    3085             continue;
    3086         if (RT_LIKELY(ClippedRect.srcx + ClippedRect.w <= cxSurface))
    3087         { /* likely */ }
    3088         else
    3089         {
    3090             AssertFailed(); /* remove if annoying. */
    3091             ClippedRect.w = cxSurface - ClippedRect.srcx;
    3092         }
    3093 
    3094         if (RT_LIKELY(ClippedRect.srcy < cySurface))
    3095         { /* likely */ }
    3096         else
    3097             continue;
    3098         if (RT_LIKELY(ClippedRect.srcy + ClippedRect.h <= cySurface))
    3099         { /* likely */ }
    3100         else
    3101         {
    3102             AssertFailed(); /* remove if annoying. */
    3103             ClippedRect.h = cySurface - ClippedRect.srcy;
    3104         }
    3105 
    3106         /*
    3107          * Destination viewport clipping - real PITA.
    3108          *
    3109          * We have to take the following into account here:
    3110          *  - The source image is Y inverted.
    3111          *  - The destination framebuffer is in world and not window coordinates,
    3112          *    just like the source surface.  This means working in the first quadrant.
    3113          *  - The viewport is in window coordinate, that is fourth quadrant and
    3114          *    negated Y values.
    3115          *  - The destination framebuffer is not scrolled, so we have to blit
    3116          *    what's visible into the top of the framebuffer.
    3117          *
    3118          *
    3119          *  To illustrate:
    3120          *
    3121          *        source              destination        0123456789
    3122          *     8 ^----------       8 ^----------       0 ----------->
    3123          *     7 |         |       7 |         |       1 |         |
    3124          *     6 |         |       6 | ******* |       2 | ******* |
    3125          *     5 |   ***   |       5 |    *    |       3 |    *    |
    3126          *     4 |    *    |  =>   4 |    *    |  =>   4 |    *    |
    3127          *     3 |    *    |       3 |   ***   |       5 |   ***   |
    3128          *     2 | ******* |       2 |         |       6 |         |
    3129          *     1 |         |       1 |         |       7 |         |
    3130          *     0 ----------->      0 ----------->      8 v----------
    3131          *       0123456789          0123456789          Destination window
    3132          *
    3133          * From the above, it follows that a destination viewport given in
    3134          * window coordinates matches the source exactly when srcy = srcx = 0.
    3135          *
    3136          * Example (Y only):
    3137          *  ySrc        =  0
    3138          *  yDst         =  0
    3139          *  cyCopy      =  9
    3140          *  cyScreen    =  cyCopy
    3141          *  cySurface  >=  cyCopy
    3142          *  yViewport   = 5
    3143          *  cyViewport  = 2  (i.e. '|   ***   |'
    3144          *                         '|         |' )
    3145          *  yWCViewportHi  = cxScreen - yViewport              = 9 - 5 = 4
    3146          *  yWCViewportLow = cxScreen - yViewport - cyViewport = 4 - 2 = 2
    3147          *
    3148          * We can see from the illustration that the final result should be:
    3149          *  SrcRect = (0,7) (11, 5)  (cy=2 from y=5)
    3150          *  DstRect = (0,2) (11, 4)
    3151          *
    3152          * Let's postpone the switching of SrcRect.yBottom/yTop to make it
    3153          * easier to follow:
    3154          *  SrcRect = (0,5) (11, 7)
    3155          *
    3156          * From the top, Y values only:
    3157          *  0. Copy = { .yDst = 0, .ySrc = 0, .cy = 9 }
    3158          *
    3159          *  1. CopyRect.yDst (=0) is lower than yWCViewportLow:
    3160          *      cyAdjust = yWCViewportLow - CopyRect.yDst = 2;
    3161          *      Copy.yDst += cyAdjust = 2;
    3162          *      Copy.ySrc  = unchanged;
    3163          *      Copy.cx   -= cyAdjust = 7;
    3164          *   => Copy = { .yDst = 2, .ySrc = 0, .cy = 7 }
    3165          *
    3166          *  2. CopyRect.yDst + CopyRect.cx (=9) is higher than yWCViewportHi:
    3167          *      cyAdjust = CopyRect.yDst + CopyRect.cx - yWCViewportHi = 9 - 4 = 5
    3168          *      Copy.yDst  = unchanged;
    3169          *      Copy.ySrc += cyAdjust = 5;
    3170          *      Copy.cx   -= cyAdjust = 2;
    3171          *   => Copy = { .yDst = 2, .ySrc = 5, .cy = 2 }
    3172          *
    3173          * Update: On darwin, it turns out that when we call [NSOpenGLContext updates]
    3174          *         when the view is resized, moved and otherwise messed with,
    3175          *         the visible part of the framebuffer is actually the bottom
    3176          *         one.  It's easy to adjust for this, just have to adjust the
    3177          *         destination rectangle such that yBottom is zero.
    3178          */
    3179         /* X - no inversion, so kind of simple. */
    3180         if (ClippedRect.x >= DstViewport.x)
    3181         {
    3182             if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)
    3183             { /* typical */ }
    3184             else if (ClippedRect.x < DstViewport.xRight)
    3185                 ClippedRect.w = DstViewport.xRight - ClippedRect.x;
    3186             else
    3187                 continue;
    3188         }
    3189         else
    3190         {
    3191             uint32_t cxAdjust = DstViewport.x - ClippedRect.x;
    3192             if (cxAdjust < ClippedRect.w)
    3193             {
    3194                 ClippedRect.w    -= cxAdjust;
    3195                 ClippedRect.x    += cxAdjust;
    3196                 ClippedRect.srcx += cxAdjust;
    3197             }
    3198             else
    3199                 continue;
    3200 
    3201             if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)
    3202             { /* typical */ }
    3203             else
    3204                 ClippedRect.w = DstViewport.xRight - ClippedRect.x;
    3205         }
    3206 
    3207         /* Y - complicated, see above. */
    3208         if (ClippedRect.y >= DstViewport.yLowWC)
    3209         {
    3210             if (ClippedRect.y + ClippedRect.h <= DstViewport.yHighWC)
    3211             { /* typical */ }
    3212             else if (ClippedRect.y < DstViewport.yHighWC)
    3213             {
    3214                 /* adjustment #2 */
    3215                 uint32_t cyAdjust = ClippedRect.y + ClippedRect.h - DstViewport.yHighWC;
    3216                 ClippedRect.srcy += cyAdjust;
    3217                 ClippedRect.h    -= cyAdjust;
    3218             }
    3219             else
    3220                 continue;
    3221         }
    3222         else
    3223         {
    3224             /* adjustment #1 */
    3225             uint32_t cyAdjust = DstViewport.yLowWC - ClippedRect.y;
    3226             if (cyAdjust < ClippedRect.h)
    3227             {
    3228                 ClippedRect.y    += cyAdjust;
    3229                 ClippedRect.h    -= cyAdjust;
    3230             }
    3231             else
    3232                 continue;
    3233 
    3234             if (ClippedRect.y + ClippedRect.h <= DstViewport.yHighWC)
    3235             { /* typical */ }
    3236             else
    3237             {
    3238                 /* adjustment #2 */
    3239                 cyAdjust = ClippedRect.y + ClippedRect.h - DstViewport.yHighWC;
    3240                 ClippedRect.srcy += cyAdjust;
    3241                 ClippedRect.h    -= cyAdjust;
    3242             }
    3243         }
    3244 
    3245         /* Calc source rectangle with y flipping wrt destination. */
    3246         RTRECT SrcRect;
    3247         SrcRect.xLeft   = ClippedRect.srcx;
    3248         SrcRect.xRight  = ClippedRect.srcx + ClippedRect.w;
    3249         SrcRect.yBottom = ClippedRect.srcy + ClippedRect.h;
    3250         SrcRect.yTop    = ClippedRect.srcy;
    3251 
    3252         /* Calc destination rectangle. */
    3253         RTRECT DstRect;
    3254         DstRect.xLeft   = ClippedRect.x;
    3255         DstRect.xRight  = ClippedRect.x + ClippedRect.w;
    3256         DstRect.yBottom = ClippedRect.y;
    3257         DstRect.yTop    = ClippedRect.y + ClippedRect.h;
    3258 
    3259         /* Adjust for viewport. */
    3260         DstRect.xLeft   -= DstViewport.x;
    3261         DstRect.xRight  -= DstViewport.x;
    3262 # ifdef RT_OS_DARWIN /* We actually seeing the bottom of the FB, not the top as on windows and X11. */
    3263         DstRect.yTop    -= DstRect.yBottom;
    3264         DstRect.yBottom  = 0;
    3265 # else
    3266         DstRect.yBottom += DstViewport.y;
    3267         DstRect.yTop    += DstViewport.y;
    3268 # endif
    3269 
    3270         Log(("SrcRect: (%d,%d)(%d,%d) DstRect: (%d,%d)(%d,%d)\n",
    3271              SrcRect.xLeft, SrcRect.yBottom, SrcRect.xRight, SrcRect.yTop,
    3272              DstRect.xLeft, DstRect.yBottom, DstRect.xRight, DstRect.yTop));
    3273         pState->ext.glBlitFramebuffer(SrcRect.xLeft, SrcRect.yBottom, SrcRect.xRight, SrcRect.yTop,
    3274                                       DstRect.xLeft, DstRect.yBottom, DstRect.xRight, DstRect.yTop,
    3275                                       GL_COLOR_BUFFER_BIT, GL_LINEAR);
    3276     }
    3277 
    3278 #endif
    3279 
    3280     /*
    3281      * Flip the front and back buffers.
    3282      */
    3283 #ifdef RT_OS_WINDOWS
    3284     BOOL fRef = SwapBuffers(pContext->hdc);
    3285     AssertMsg(fRef, ("SwapBuffers failed with %d\n", GetLastError())); NOREF(fRef);
    3286 #elif defined(RT_OS_DARWIN)
    3287     vmsvga3dCocoaSwapBuffers(pContext->cocoaView, pContext->cocoaContext);
    3288 #else
    3289     /* show the window if not already done */
    3290     if (!pContext->fMapped)
    3291     {
    3292         XMapWindow(pState->display, pContext->window);
    3293         pContext->fMapped = true;
    3294     }
    3295     /* now swap the buffers, i.e. display the rendering result */
    3296     glXSwapBuffers(pState->display, pContext->window);
    3297 #endif
    3298 
    3299     /*
    3300      * Now we can reset the frame buffer association.  Doing it earlier means no
    3301      * output on darwin.
    3302      */
    3303     VMSVGA3D_ASSERT_GL_CALL(pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, pContext->idFramebuffer), pState, pContext);
    3304     return VINF_SUCCESS;
    3305 }
    33062804
    33072805#ifdef RT_OS_LINUX
     
    34322930
    34332931#ifdef RT_OS_WINDOWS
    3434     /* Create a context window. */
     2932    /* Create a context window with minimal 4x4 size. We will never use the swapchain
     2933     * to present the rendered image. Rendered images from the guest will be copied to
     2934     * the VMSVGA SCREEN object, which can be either an offscreen render target or
     2935     * system memory in the guest VRAM.
     2936     */
    34352937    CREATESTRUCT cs;
    34362938    cs.lpCreateParams   = NULL;
    3437     cs.dwExStyle        = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT;
     2939    cs.dwExStyle        = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY;
    34382940# ifdef DEBUG_GFX_WINDOW
    34392941    cs.lpszName         = (char *)RTMemAllocZ(256);
     
    34462948    cs.style            = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_CAPTION;
    34472949# else
    3448     cs.style            = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED | WS_CHILD | WS_VISIBLE;
     2950    cs.style            = WS_DISABLED | WS_CHILD;
    34492951# endif
    34502952    cs.x                = 0;
    34512953    cs.y                = 0;
    3452     cs.cx               = pThis->svga.uWidth;
    3453     cs.cy               = pThis->svga.uHeight;
     2954    cs.cx               = 4;
     2955    cs.cy               = 4;
    34542956    cs.hwndParent       = (HWND)pThis->svga.u64HostWindowId;
    34552957    cs.hMenu            = NULL;
     
    34662968        1,                              /* version number */
    34672969        PFD_DRAW_TO_WINDOW |            /* support window */
    3468         PFD_DOUBLEBUFFER   |            /* support double buffering */
    34692970        PFD_SUPPORT_OPENGL,             /* support OpenGL */
    34702971        PFD_TYPE_RGBA,                  /* RGBA type */
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp

    r73297 r73736  
    24602460}
    24612461
    2462 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
    2463 {
    2464     PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
    2465     PVMSVGA3DSURFACE    pSurface;
    2466     PVMSVGA3DCONTEXT    pContext;
    2467     HRESULT             hr;
    2468     int                 rc;
    2469     IDirect3DSurface9  *pBackBuffer;
    2470     IDirect3DSurface9  *pSurfaceD3D;
    2471 
    2472     AssertReturn(pState, VERR_NO_MEMORY);
    2473 
    2474     rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
    2475     AssertRCReturn(rc, rc);
    2476 
    2477     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
    2478 
    2479     LogFunc(("sid=%x cRects=%d cid=%x\n", sid, cRects, pSurface->idAssociatedContext));
    2480     for (uint32_t i = 0; i < cRects; ++i)
    2481     {
    2482         LogFunc(("rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
    2483     }
    2484 
    2485     rc = vmsvga3dContextFromCid(pState, pSurface->idAssociatedContext, &pContext);
    2486     AssertRCReturn(rc, rc);
    2487 
    2488     hr = pContext->pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    2489     AssertMsgReturn(hr == D3D_OK, ("GetBackBuffer failed with %x\n", hr), VERR_INTERNAL_ERROR);
    2490 
    2491     rc = vmsvga3dGetD3DSurface(pState, pContext, pSurface, 0, 0, false, &pSurfaceD3D);
    2492     AssertRCReturn(rc, rc);
    2493 
    2494     /* Read the destination viewport specs in one go to try avoid some unnecessary update races. */
    2495     VMSVGAVIEWPORT const DstViewport = pThis->svga.viewport;
    2496     ASMCompilerBarrier(); /* paranoia */
    2497     Assert(DstViewport.yHighWC >= DstViewport.yLowWC);
    2498 
    2499     /* If there are no recangles specified, just grab a screenful. */
    2500     SVGA3dCopyRect DummyRect;
    2501     if (cRects != 0)
    2502     { /* likely */ }
    2503     else
    2504     {
    2505         /** @todo Find the usecase for this or check what the original device does.
    2506          *        The original code was doing some scaling based on the surface
    2507          *        size... */
    2508 # ifdef DEBUG_bird
    2509         AssertMsgFailed(("No rects to present. Who is doing that and what do they actually expect?\n"));
    2510 # endif
    2511         DummyRect.x = DummyRect.srcx = 0;
    2512         DummyRect.y = DummyRect.srcy = 0;
    2513         DummyRect.w = pThis->svga.uWidth;
    2514         DummyRect.h = pThis->svga.uHeight;
    2515         cRects = 1;
    2516         pRect  = &DummyRect;
    2517     }
    2518 
    2519     /*
    2520      * Blit the surface rectangle(s) to the back buffer.
    2521      */
    2522     Assert(pSurface->cxBlock == 1 && pSurface->cyBlock == 1);
    2523     uint32_t const cxSurface = pSurface->pMipmapLevels[0].mipmapSize.width;
    2524     uint32_t const cySurface = pSurface->pMipmapLevels[0].mipmapSize.height;
    2525     for (uint32_t i = 0; i < cRects; i++)
    2526     {
    2527         SVGA3dCopyRect ClippedRect = pRect[i];
    2528 
    2529         /*
    2530          * Do some sanity checking and limit width and height, all so we
    2531          * don't need to think about wrap-arounds below.
    2532          */
    2533         if (RT_LIKELY(   ClippedRect.w
    2534                       && ClippedRect.x    < VMSVGA_MAX_X
    2535                       && ClippedRect.srcx < VMSVGA_MAX_X
    2536                       && ClippedRect.h
    2537                       && ClippedRect.y    < VMSVGA_MAX_Y
    2538                       && ClippedRect.srcy < VMSVGA_MAX_Y
    2539                          ))
    2540         { /* likely */ }
    2541         else
    2542             continue;
    2543 
    2544         if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_Y))
    2545         { /* likely */ }
    2546         else
    2547             ClippedRect.w = VMSVGA_MAX_Y;
    2548         if (RT_LIKELY(ClippedRect.w < VMSVGA_MAX_Y))
    2549         { /* likely */ }
    2550         else
    2551             ClippedRect.w = VMSVGA_MAX_Y;
    2552 
    2553         /*
    2554          * Source surface clipping (paranoia). Straight forward.
    2555          */
    2556         if (RT_LIKELY(ClippedRect.srcx < cxSurface))
    2557         { /* likely */ }
    2558         else
    2559             continue;
    2560         if (RT_LIKELY(ClippedRect.srcx + ClippedRect.w <= cxSurface))
    2561         { /* likely */ }
    2562         else
    2563         {
    2564             AssertFailed(); /* remove if annoying. */
    2565             ClippedRect.w = cxSurface - ClippedRect.srcx;
    2566         }
    2567 
    2568         if (RT_LIKELY(ClippedRect.srcy < cySurface))
    2569         { /* likely */ }
    2570         else
    2571             continue;
    2572         if (RT_LIKELY(ClippedRect.srcy + ClippedRect.h <= cySurface))
    2573         { /* likely */ }
    2574         else
    2575         {
    2576             AssertFailed(); /* remove if annoying. */
    2577             ClippedRect.h = cySurface - ClippedRect.srcy;
    2578         }
    2579 
    2580         /*
    2581          * Destination viewport clipping.
    2582          *
    2583          * This is very straight forward compared to OpenGL.  There is no Y
    2584          * inversion anywhere and all the coordinate systems are the same.
    2585          */
    2586         /* X */
    2587         if (ClippedRect.x >= DstViewport.x)
    2588         {
    2589             if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)
    2590             { /* typical */ }
    2591             else if (ClippedRect.x < DstViewport.xRight)
    2592                 ClippedRect.w = DstViewport.xRight - ClippedRect.x;
    2593             else
    2594                 continue;
    2595         }
    2596         else
    2597         {
    2598             uint32_t cxAdjust = DstViewport.x - ClippedRect.x;
    2599             if (cxAdjust < ClippedRect.w)
    2600             {
    2601                 ClippedRect.w    -= cxAdjust;
    2602                 ClippedRect.x    += cxAdjust;
    2603                 ClippedRect.srcx += cxAdjust;
    2604             }
    2605             else
    2606                 continue;
    2607 
    2608             if (ClippedRect.x + ClippedRect.w <= DstViewport.xRight)
    2609             { /* typical */ }
    2610             else
    2611                 ClippedRect.w = DstViewport.xRight - ClippedRect.x;
    2612         }
    2613 
    2614         /* Y */
    2615         if (ClippedRect.y >= DstViewport.y)
    2616         {
    2617             if (ClippedRect.y + ClippedRect.h <= DstViewport.y + DstViewport.cy)
    2618             { /* typical */ }
    2619             else if (ClippedRect.x < DstViewport.y + DstViewport.cy)
    2620                 ClippedRect.h = DstViewport.y + DstViewport.cy - ClippedRect.y;
    2621             else
    2622                 continue;
    2623         }
    2624         else
    2625         {
    2626             uint32_t cyAdjust = DstViewport.y - ClippedRect.y;
    2627             if (cyAdjust < ClippedRect.h)
    2628             {
    2629                 ClippedRect.h    -= cyAdjust;
    2630                 ClippedRect.y    += cyAdjust;
    2631                 ClippedRect.srcy += cyAdjust;
    2632             }
    2633             else
    2634                 continue;
    2635 
    2636             if (ClippedRect.y + ClippedRect.h <= DstViewport.y + DstViewport.cy)
    2637             { /* typical */ }
    2638             else
    2639                 ClippedRect.h = DstViewport.y + DstViewport.cy - ClippedRect.y;
    2640         }
    2641 
    2642         /* Calc source rectangle. */
    2643         RECT SrcRect;
    2644         SrcRect.left   = ClippedRect.srcx;
    2645         SrcRect.right  = ClippedRect.srcx + ClippedRect.w;
    2646         SrcRect.top    = ClippedRect.srcy;
    2647         SrcRect.bottom = ClippedRect.srcy + ClippedRect.h;
    2648 
    2649         /* Calc destination rectangle. */
    2650         RECT DstRect;
    2651         DstRect.left   = ClippedRect.x;
    2652         DstRect.right  = ClippedRect.x + ClippedRect.w;
    2653         DstRect.top    = ClippedRect.y;
    2654         DstRect.bottom = ClippedRect.y + ClippedRect.h;
    2655 
    2656         /* Adjust for viewport. */
    2657         DstRect.left   -= DstViewport.x;
    2658         DstRect.right  -= DstViewport.x;
    2659         DstRect.bottom -= DstViewport.y;
    2660         DstRect.top    -= DstViewport.y;
    2661 
    2662         Log(("SrcRect: (%d,%d)(%d,%d) DstRect: (%d,%d)(%d,%d)\n",
    2663              SrcRect.left, SrcRect.bottom, SrcRect.right, SrcRect.top,
    2664              DstRect.left, DstRect.bottom, DstRect.right, DstRect.top));
    2665         hr = pContext->pDevice->StretchRect(pSurfaceD3D, &SrcRect, pBackBuffer, &DstRect, D3DTEXF_NONE);
    2666         AssertBreak(hr == D3D_OK);
    2667     }
    2668 
    2669     D3D_RELEASE(pSurfaceD3D);
    2670     D3D_RELEASE(pBackBuffer);
    2671 
    2672     AssertMsgReturn(hr == D3D_OK, ("StretchRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
    2673 
    2674     hr = pContext->pDevice->Present(NULL, NULL, NULL, NULL);
    2675     AssertMsgReturn(hr == D3D_OK, ("Present failed with %x\n", hr), VERR_INTERNAL_ERROR);
    2676 
    2677     return VINF_SUCCESS;
    2678 }
    2679 
    26802462
    26812463/**
     
    27292511        pContext->state.aRenderTargets[i] = SVGA3D_INVALID_ID;
    27302512
    2731     /* Create a context window. */
     2513    /* Create a context window with minimal 4x4 size. We will never use the swapchain
     2514     * to present the rendered image. Rendered images from the guest will be copied to
     2515     * the VMSVGA SCREEN object, which can be either an offscreen render target or
     2516     * system memory in the guest VRAM.
     2517     */
    27322518    CREATESTRUCT cs;
    27332519
     
    27352521
    27362522    cs.lpCreateParams   = NULL;
    2737     cs.dwExStyle        = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT;
     2523    cs.dwExStyle        = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY;
    27382524#ifdef DEBUG_GFX_WINDOW
    27392525    cs.lpszName         = (char *)RTMemAllocZ(256);
     
    27462532    cs.style            = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_CAPTION;
    27472533#else
    2748     cs.style            = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED | WS_CHILD | WS_VISIBLE;
     2534    cs.style            = WS_DISABLED | WS_CHILD;
    27492535#endif
    27502536    cs.x                = 0;
    27512537    cs.y                = 0;
    2752     cs.cx               = pThis->svga.uWidth;
    2753     cs.cy               = pThis->svga.uHeight;
     2538    cs.cx               = 4;
     2539    cs.cy               = 4;
    27542540    cs.hwndParent       = (HWND)pThis->svga.u64HostWindowId;
    27552541    cs.hMenu            = NULL;
     
    27672553    PresParam.MultiSampleType               = D3DMULTISAMPLE_NONE;
    27682554    PresParam.MultiSampleQuality            = 0;
    2769     PresParam.SwapEffect                    = D3DSWAPEFFECT_FLIP;
     2555    PresParam.SwapEffect                    = D3DSWAPEFFECT_DISCARD;
    27702556    PresParam.hDeviceWindow                 = pContext->hwnd;
    27712557    PresParam.Windowed                      = TRUE;     /** @todo */
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp

    r73297 r73736  
    886886    return VINF_SUCCESS;
    887887}
     888
     889int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
     890{
     891    /* Deprecated according to svga3d_reg.h. */
     892    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     893    AssertReturn(pState, VERR_NO_MEMORY);
     894
     895    PVMSVGA3DSURFACE pSurface;
     896    int rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
     897    AssertRCReturn(rc, rc);
     898
     899    /* If there are no recangles specified, just grab a screenful. */
     900    SVGA3dCopyRect DummyRect;
     901    if (cRects != 0)
     902    { /* likely */ }
     903    else
     904    {
     905        /** @todo Find the usecase for this or check what the original device does.
     906         *        The original code was doing some scaling based on the surface
     907         *        size... */
     908        AssertMsgFailed(("No rects to present. Who is doing that and what do they actually expect?\n"));
     909        DummyRect.x = DummyRect.srcx = 0;
     910        DummyRect.y = DummyRect.srcy = 0;
     911        DummyRect.w = pThis->svga.uWidth;
     912        DummyRect.h = pThis->svga.uHeight;
     913        cRects = 1;
     914        pRect  = &DummyRect;
     915    }
     916
     917    uint32_t i;
     918    for (i = 0; i < cRects; ++i)
     919    {
     920        uint32_t idDstScreen = 0; /** @todo Use virtual coords: SVGA_ID_INVALID. */
     921        SVGASignedRect destRect;
     922        destRect.left   = pRect[i].x;
     923        destRect.top    = pRect[i].y;
     924        destRect.right  = pRect[i].x + pRect[i].w;
     925        destRect.bottom = pRect[i].y + pRect[i].h;
     926
     927        SVGA3dSurfaceImageId src;
     928        src.sid = sid;
     929        src.face = 0;
     930        src.mipmap = 0;
     931
     932        SVGASignedRect srcRect;
     933        srcRect.left   = pRect[i].srcx;
     934        srcRect.top    = pRect[i].srcy;
     935        srcRect.right  = pRect[i].srcx + pRect[i].w;
     936        srcRect.bottom = pRect[i].srcy + pRect[i].h;
     937
     938        /* Entire rect. */
     939        uint32_t cRects = 0;
     940        SVGASignedRect *pRect = NULL;
     941
     942        rc = vmsvga3dSurfaceBlitToScreen(pThis, idDstScreen, destRect, src, srcRect, cRects, pRect);
     943        AssertRCReturn(rc, rc);
     944    }
     945
     946    return VINF_SUCCESS;
     947}
Note: See TracChangeset for help on using the changeset viewer.

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