diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c
index 36a8c346228d1527eb13aba67734b9d5db5262c1..4de426e501b378ffb85bdf5f78dc9d852434e0a2 100644
--- a/dlls/ddraw/d3ddevice/main.c
+++ b/dlls/ddraw/d3ddevice/main.c
@@ -1100,15 +1100,24 @@ Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface,
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
 
+    /* Do nothing if the specified viewport is the same as the current one */
+    if (This->current_viewport == ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3))
+      return DD_OK;
+    
     /* Should check if the viewport was added or not */
 
+    /* Release previous viewport and AddRef the new one */
+    if (This->current_viewport)
+      IDirect3DViewport3_Release(ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
+    IDirect3DViewport3_AddRef(lpDirect3DViewport3);
+    
     /* Set this viewport as the current viewport */
     This->current_viewport = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
 
     /* Activate this viewport */
     This->current_viewport->active_device = This;
     This->current_viewport->activate(This->current_viewport);
-    
+
     return DD_OK;
 }
 
@@ -1120,6 +1129,10 @@ Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface,
     TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3DViewport3);
 
     *lplpDirect3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
+
+    /* AddRef the returned viewport */
+    IDirect3DViewport3_AddRef(*lplpDirect3DViewport3);
+    
     TRACE(" returning interface %p\n", *lplpDirect3DViewport3);
     
     return DD_OK;
diff --git a/dlls/ddraw/d3dviewport.c b/dlls/ddraw/d3dviewport.c
index b0d324271af3818365135d9efc54161ca87adde5..8309bc3328f692da8c3de64c4478321981395a2a 100644
--- a/dlls/ddraw/d3dviewport.c
+++ b/dlls/ddraw/d3dviewport.c
@@ -180,6 +180,7 @@ Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
                                              LPD3DVIEWPORT lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    LPDIRECT3DVIEWPORT3 current_viewport;
     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
 
     if (TRACE_ON(ddraw)) {
@@ -196,7 +197,14 @@ Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
     */
     This->viewports.vp1.dvMinZ = 0.0;
     This->viewports.vp1.dvMaxZ = 1.0;
-    
+
+    if (This->active_device) {
+      IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
+      if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
+          This->activate(This);
+      IDirect3DViewport3_Release(current_viewport);
+    }
+
     return DD_OK;
 }
 
@@ -402,6 +410,7 @@ Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
                                             LPD3DVIEWPORT2 lpData)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    LPDIRECT3DVIEWPORT3 current_viewport;
     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
 
     if (TRACE_ON(ddraw)) {
@@ -412,6 +421,14 @@ Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
     This->use_vp2 = 1;
     memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
     memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
+
+    if (This->active_device) {
+      IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
+      if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
+        This->activate(This);
+      IDirect3DViewport3_Release(current_viewport);
+    }
+
     return DD_OK;
 }