[PATCH 4/5] wined3d: Decide about PBO use at surface creation time.

Stefan Dösinger stefan at codeweavers.com
Wed Jan 15 07:54:11 CST 2014


This code uses PBOs for mappable dynamic surfaces, which in practise
means dynamic textures and mappable render targets. We may want to mark
mappable render targets dynamic, but that's a different issue.

The only exception to the static PBO decision is that we drop the PBO
when a color key is used. When the surface has been loaded with a color
key once, we never use a PBO for it again. This is fairly academic right
now due to SFLAG_PIN_SYSMEM being always set for ddraw.

This patch temporarily re-adds SFLAG_PBO with a different meaning. The
next patch will replace it with setting map_binding to SFLAG_INBUFFER.
---
 dlls/wined3d/surface.c         | 41 ++++++++++++++++++++++++-----------------
 dlls/wined3d/wined3d_private.h |  1 +
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 0d8de0f..ab7bbd6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -538,20 +538,6 @@ static void surface_get_memory(const struct wined3d_surface *surface, struct win
     data->buffer_object = 0;
 }
 
-static BOOL surface_need_pbo(const struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
-{
-    if (surface->resource.pool == WINED3D_POOL_SYSTEM_MEM)
-        return FALSE;
-    if (!(surface->flags & SFLAG_DYNLOCK))
-        return FALSE;
-    if (surface->flags & (SFLAG_CONVERTED | SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM))
-        return FALSE;
-    if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT])
-        return FALSE;
-
-    return TRUE;
-}
-
 static void surface_create_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
 {
     struct wined3d_context *context;
@@ -591,7 +577,7 @@ static void surface_prepare_system_memory(struct wined3d_surface *surface)
 
     TRACE("surface %p.\n", surface);
 
-    if (!surface->pbo && surface_need_pbo(surface, gl_info))
+    if (!surface->pbo && surface->flags & SFLAG_PBO)
         surface_create_pbo(surface, gl_info);
     else if (!(surface->resource.heap_memory || surface->pbo))
     {
@@ -666,6 +652,17 @@ static void surface_release_client_storage(struct wined3d_surface *surface)
     surface_force_reload(surface);
 }
 
+static BOOL surface_use_pbo(const struct wined3d_surface *surface)
+{
+    const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+
+    return surface->resource.pool == WINED3D_POOL_DEFAULT
+                && surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU
+                && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]
+                && !surface->resource.format->convert
+                && !(surface->flags & (SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM));
+}
+
 static HRESULT surface_private_setup(struct wined3d_surface *surface)
 {
     /* TODO: Check against the maximum texture sizes supported by the video card. */
@@ -753,6 +750,9 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
     if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
         surface->flags |= SFLAG_DISCARDED;
 
+    if (surface_use_pbo(surface))
+        surface->flags |= SFLAG_PBO;
+
     return WINED3D_OK;
 }
 
@@ -2791,6 +2791,13 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
     else
         surface->resource.size = resource_size;
 
+    /* The format might be changed to a format that needs conversion.
+     * If the surface didn't use PBOs previously but could now, don't
+     * change it - whatever made us not use PBOs might come back, e.g.
+     * color keys. */
+    if (!surface_use_pbo(surface))
+        surface->flags &= ~SFLAG_PBO;
+
     if (create_dib)
     {
         if (FAILED(hr = surface_create_dib_section(surface)))
@@ -5109,6 +5116,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     {
         TRACE("Removing the pbo attached to surface %p.\n", surface);
         surface_remove_pbo(surface, gl_info);
+        surface->flags &= ~SFLAG_PBO;
     }
 
     surface_get_memory(surface, &data, surface->flags);
@@ -5209,8 +5217,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location)
     {
         TRACE("Location already up to date.\n");
 
-        if (location == SFLAG_INSYSMEM && !surface->pbo
-                && surface_need_pbo(surface, gl_info))
+        if (location == SFLAG_INSYSMEM && !surface->pbo && surface->flags & SFLAG_PBO)
             surface_create_pbo(surface, gl_info);
 
         return WINED3D_OK;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d8bdc9c..9d4c39c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2305,6 +2305,7 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
 #define SFLAG_INRB_MULTISAMPLE  0x00080000 /* The multisample renderbuffer is current. */
 #define SFLAG_INRB_RESOLVED     0x00100000 /* The resolved renderbuffer is current. */
 #define SFLAG_DISCARDED         0x00200000 /* Surface was discarded, allocating new location is enough. */
+#define SFLAG_PBO               0x00400000 /* Use a PBO for mapping. */
 
 /* In some conditions the surface memory must not be freed:
  * SFLAG_CONVERTED: Converting the data back would take too long
-- 
1.8.3.2




More information about the wine-patches mailing list