[3/6] WineD3D: Use the source surface's texture for writing the backup

Stefan Dösinger stefan at codeweavers.com
Wed Feb 28 18:50:23 CST 2007


In case of an fbo offscreen target a temporary texture is used again - But in 
the long run we won't need that function if fbos and framebuffer_blit are 
supported

The fbo handling is untested because I have no application that works with 
fbos and blits from offscreen targets
-------------- next part --------------
From 41c766ba4073a02cca7514f489a14cfce8d7bd5a Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Thu, 1 Mar 2007 01:42:50 +0100
Subject: [PATCH] WineD3D: Use the source surface's texture for writing the backup

The hwstretch blit code creates a new texture each time it is called to back up the back buffer and releases it afterwards. It is more
efficient to keep the texture and release it with the surface. This patch uses the source surface's texture to do the job. Because the
source surface is an active render target its texture is either only needed for blitting(onscreen target) or will be completely
overwritten on the next render target change(offscreen target).

In case of FBOs the texture can't be used, so hwstretch blit still creates a temporary backup texture. However, with fbos support for
EXT_framebuffer_blit is likely to be there so in the long run hwstretch should not be needed then. (But for now it is)

The surface destroy code will release the opengl texture
---
 dlls/wined3d/surface.c |   46 +++++++++++++++++++++++++++-------------------
 1 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 8e5bd88..95b7cc7 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2251,7 +2251,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
 
 /* Uses the hardware to stretch and flip the image */
 static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, IWineD3DSwapChainImpl *swapchain, WINED3DRECT *srect, WINED3DRECT *drect, BOOL upsidedown) {
-    GLuint backup, src;
+    GLuint src, backup = 0;
     IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
     IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
     float left, right, top, bottom; /* Texture coordinates */
@@ -2263,22 +2263,27 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     ENTER_GL();
     ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
 
-    /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
-     * we are reading from the back buffer, the backup can be used as source texture
-     */
-    glGenTextures(1, &backup);
-    checkGLcall("glGenTextures(1, &backup)");
-    glBindTexture(GL_TEXTURE_2D, backup);
-    checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
+    if(!swapchain && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
+        glGenTextures(1, &backup);
+        checkGLcall("glGenTextures\n");
+        glBindTexture(GL_TEXTURE_2D, backup);
+        checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
+    } else {
+        /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
+         * we are reading from the back buffer, the backup can be used as source texture
+         */
+        if(Src->glDescription.textureName == 0) {
+            /* Get it a description */
+            IWineD3DSurface_PreLoad(SrcSurface);
+        }
+        glBindTexture(GL_TEXTURE_2D, Src->glDescription.textureName);
+        checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
+    }
 
     glReadBuffer(GL_BACK);
     checkGLcall("glReadBuffer(GL_BACK)");
 
     /* TODO: Only back up the part that will be overwritten */
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Src->pow2Width, Src->pow2Height, 0,
-                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-    checkGLcall("glTexImage2D");
-
     glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
                         0, 0 /* read offsets */,
                         0, 0,
@@ -2287,13 +2292,14 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
 
     checkGLcall("glCopyTexSubImage2D");
 
+    /* No issue with overriding these - the sampler is dirty due to blit usage */
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     checkGLcall("glTexParameteri");
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     checkGLcall("glTexParameteri");
 
-    if(!swapchain || (IWineD3DSurface *) This == swapchain->backBuffer[0]) {
-        src = backup;
+    if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
+        src = backup ? backup : Src->glDescription.textureName;
     } else {
         glReadBuffer(GL_FRONT);
         checkGLcall("glReadBuffer(GL_FRONT)");
@@ -2370,8 +2376,8 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     checkGLcall("glCopyTexSubImage2D");
 
     /* Write the back buffer backup back */
-    glBindTexture(GL_TEXTURE_2D, backup);
-    checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
+    glBindTexture(GL_TEXTURE_2D, backup ? backup : Src->glDescription.textureName);
+    checkGLcall("glBindTexture(GL_TEXTURE_2D, Src->glDescription.textureName)");
 
     glBegin(GL_QUADS);
         /* top left */
@@ -2392,12 +2398,14 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     glEnd();
 
     /* Cleanup */
-    if(src != backup) {
+    if(src != Src->glDescription.textureName && src != backup) {
         glDeleteTextures(1, &src);
         checkGLcall("glDeleteTextures(1, &src)");
     }
-    glDeleteTextures(1, &backup);
-    checkGLcall("glDeleteTextures(1, &backup)");
+    if(backup) {
+        glDeleteTextures(1, &backup);
+        checkGLcall("glDeleteTextures(1, &backup)");
+    }
     LEAVE_GL();
 }
 
-- 
1.4.4.3



More information about the wine-patches mailing list