st/nine: Improve pDestRect handling
authorAxel Davy <davyaxel0@gmail.com>
Sat, 9 May 2020 11:17:17 +0000 (13:17 +0200)
committerMarge Bot <eric+marge@anholt.net>
Fri, 15 May 2020 15:43:57 +0000 (15:43 +0000)
pSourceRect and pDestRect allows to:
A) display a crop of the backbuffer
B) display the content in a subregion (after an offset)
C) resize the content before displaying

Before this patch, only features A and B were supported.
This patch adds C, but breaks A, which current support
relied on C not being implemented.

I think C is more important than A, and A can be added later.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5015>

src/gallium/frontends/nine/swapchain9.c

index 8fb20082f919eec8fe66137c6e1c7490ac0a661b..b9578b54600ec5cb05ab982dcae73d41b4f408e9 100644 (file)
@@ -724,6 +724,8 @@ present( struct NineSwapChain9 *This,
     HRESULT hr;
     struct pipe_blit_info blit;
     int target_width, target_height, target_depth, i;
+    RECT source_rect;
+    RECT dest_rect;
 
     DBG("present: This=%p pSourceRect=%p pDestRect=%p "
         "pDirtyRegion=%p hDestWindowOverride=%p"
@@ -731,14 +733,18 @@ present( struct NineSwapChain9 *This,
         This, pSourceRect, pDestRect, pDirtyRegion,
         hDestWindowOverride, (int)dwFlags, This->buffers[0]->base.resource);
 
-    if (pSourceRect)
+    if (pSourceRect) {
         DBG("pSourceRect = (%u..%u)x(%u..%u)\n",
             pSourceRect->left, pSourceRect->right,
             pSourceRect->top, pSourceRect->bottom);
-    if (pDestRect)
+        source_rect = *pSourceRect;
+    }
+    if (pDestRect) {
         DBG("pDestRect = (%u..%u)x(%u..%u)\n",
             pDestRect->left, pDestRect->right,
             pDestRect->top, pDestRect->bottom);
+        dest_rect = *pDestRect;
+    }
 
     /* TODO: in the case the source and destination rect have different size:
      * We need to allocate a new buffer, and do a blit to it to resize.
@@ -771,6 +777,15 @@ present( struct NineSwapChain9 *This,
         target_height = resource->height0;
     }
 
+    if (pDestRect) {
+        dest_rect.top = MAX2(0, dest_rect.top);
+        dest_rect.left = MAX2(0, dest_rect.left);
+        dest_rect.bottom = MIN2(target_height, dest_rect.bottom);
+        dest_rect.right = MIN2(target_width, dest_rect.right);
+        target_height = dest_rect.bottom - dest_rect.top;
+        target_width = dest_rect.right - dest_rect.left;
+    }
+
     /* Switch to using presentation buffers on window resize.
      * Note: Most apps should resize the d3d back buffers when
      * a window resize is detected, which will result in a call to
@@ -906,7 +921,7 @@ bypass_rendering:
     if (!This->enable_threadpool) {
         This->tasks[0]=NULL;
 
-        hr = ID3DPresent_PresentBuffer(This->present, This->present_handles[0], hDestWindowOverride, pSourceRect, pDestRect, pDirtyRegion, dwFlags);
+        hr = ID3DPresent_PresentBuffer(This->present, This->present_handles[0], hDestWindowOverride, pSourceRect, pDestRect ? &dest_rect : NULL, pDirtyRegion, dwFlags);
 
         if (FAILED(hr)) { UNTESTED(3);return hr; }
     }