[PATCH 3/5] wined3d: Temporarily remove surface PBO support.
Stefan Dösinger
stefan at codeweavers.com
Sat Nov 23 17:18:58 CST 2013
The implementation is strange and fairly ineffective in doing what PBOs
are supposed to do - avoiding pipeline stalls and redundant copying.
Removing it will make restructuring surfaces easier and avoid temporary
regressions. It will be re-added later.
---
dlls/wined3d/surface.c | 266 +++--------------------------------------
dlls/wined3d/wined3d_private.h | 19 ++-
2 files changed, 25 insertions(+), 260 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index f456bb9..f6aa7ee 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -42,8 +42,7 @@ static void surface_cleanup(struct wined3d_surface *surface)
TRACE("surface %p.\n", surface);
- if ((surface->flags & SFLAG_PBO) || surface->rb_multisample
- || surface->rb_resolved || !list_empty(&surface->renderbuffers))
+ if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers))
{
struct wined3d_renderbuffer_entry *entry, *entry2;
const struct wined3d_gl_info *gl_info;
@@ -52,12 +51,6 @@ static void surface_cleanup(struct wined3d_surface *surface)
context = context_acquire(surface->resource.device, NULL);
gl_info = context->gl_info;
- if (surface->flags & SFLAG_PBO)
- {
- TRACE("Deleting PBO %u.\n", surface->pbo);
- GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
- }
-
if (surface->rb_multisample)
{
TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample);
@@ -517,70 +510,20 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
return WINED3D_OK;
}
-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_load_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
-{
- struct wined3d_context *context;
- GLenum error;
-
- context = context_acquire(surface->resource.device, NULL);
-
- GL_EXTCALL(glGenBuffersARB(1, &surface->pbo));
- error = gl_info->gl_ops.gl.p_glGetError();
- if (!surface->pbo || error != GL_NO_ERROR)
- ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error);
-
- TRACE("Binding PBO %u.\n", surface->pbo);
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
-
- GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->resource.size + 4,
- surface->resource.allocatedMemory, GL_STREAM_DRAW_ARB));
- checkGLcall("glBufferDataARB");
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
- checkGLcall("glBindBufferARB");
-
- /* We don't need the system memory anymore and we can't even use it for PBOs. */
- if (!(surface->flags & SFLAG_CLIENT))
- wined3d_resource_free_sysmem(&surface->resource);
- surface->resource.allocatedMemory = NULL;
- surface->flags |= SFLAG_PBO;
- context_release(context);
-}
-
static void surface_prepare_system_memory(struct wined3d_surface *surface)
{
- const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
-
TRACE("surface %p.\n", surface);
- if (!(surface->flags & SFLAG_PBO) && surface_need_pbo(surface, gl_info))
- surface_load_pbo(surface, gl_info);
- else if (!(surface->resource.allocatedMemory || surface->flags & SFLAG_PBO))
+ if (!surface->resource.allocatedMemory)
{
/* Whatever surface we have, make sure that there is memory allocated
- * for the downloaded copy, or a PBO to map. */
+ * for the downloaded copy. */
if (!surface->resource.heap_memory && !wined3d_resource_allocate_sysmem(&surface->resource))
ERR("Failed to allocate system memory.\n");
surface->resource.allocatedMemory = surface->resource.heap_memory;
if (surface->flags & SFLAG_INSYSMEM)
- ERR("Surface without memory or PBO has SFLAG_INSYSMEM set.\n");
+ ERR("Surface without memory has SFLAG_INSYSMEM set.\n");
}
}
@@ -769,8 +712,6 @@ static void surface_realize_palette(struct wined3d_surface *surface)
static void surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags)
{
- struct wined3d_device *device = surface->resource.device;
-
TRACE("surface %p, rect %s, flags %#x.\n",
surface, wine_dbgstr_rect(rect), flags);
@@ -789,64 +730,16 @@ static void surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD
surface_load_location(surface, SFLAG_INSYSMEM);
}
- if (surface->flags & SFLAG_PBO)
- {
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
-
- context = context_acquire(device, NULL);
- gl_info = context->gl_info;
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
-
- /* This shouldn't happen but could occur if some other function
- * didn't handle the PBO properly. */
- if (surface->resource.allocatedMemory)
- ERR("The surface already has PBO memory allocated.\n");
-
- surface->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
- checkGLcall("glMapBufferARB");
-
- /* Make sure the PBO isn't set anymore in order not to break non-PBO
- * calls. */
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
- checkGLcall("glBindBufferARB");
-
- context_release(context);
- }
-
if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
surface_set_dirty(surface);
}
static void surface_unmap(struct wined3d_surface *surface)
{
- struct wined3d_device *device = surface->resource.device;
-
TRACE("surface %p.\n", surface);
memset(&surface->lockedRect, 0, sizeof(surface->lockedRect));
- if (surface->flags & SFLAG_PBO)
- {
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
-
- TRACE("Freeing PBO memory.\n");
-
- context = context_acquire(device, NULL);
- gl_info = context->gl_info;
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
- GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
- checkGLcall("glUnmapBufferARB");
- context_release(context);
-
- surface->resource.allocatedMemory = NULL;
- }
-
TRACE("dirtyfied %u.\n", surface->flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
if (surface->flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE))
@@ -1252,36 +1145,6 @@ HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *sur
return wined3d_surface_blt(surface, NULL, render_target, NULL, 0, NULL, WINED3D_TEXF_POINT);
}
-/* Context activation is done by the caller. */
-static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
-{
- if (surface->flags & SFLAG_DIBSECTION)
- {
- surface->resource.allocatedMemory = surface->dib.bitmap_data;
- }
- else
- {
- if (!surface->resource.heap_memory)
- wined3d_resource_allocate_sysmem(&surface->resource);
- else if (!(surface->flags & SFLAG_CLIENT))
- ERR("Surface %p has heap_memory %p and flags %#x.\n",
- surface, surface->resource.heap_memory, surface->flags);
-
- surface->resource.allocatedMemory = surface->resource.heap_memory;
- }
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, surface->pbo)");
- GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0,
- surface->resource.size, surface->resource.allocatedMemory));
- checkGLcall("glGetBufferSubDataARB");
- GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
- checkGLcall("glDeleteBuffersARB");
-
- surface->pbo = 0;
- surface->flags &= ~SFLAG_PBO;
-}
-
static BOOL surface_init_sysmem(struct wined3d_surface *surface)
{
if (!surface->resource.allocatedMemory)
@@ -1335,8 +1198,8 @@ static void surface_unload(struct wined3d_resource *resource)
* or the depth stencil into an FBO the texture or render buffer will be removed
* and all flags get lost
*/
- if (!(surface->flags & SFLAG_PBO))
- surface_init_sysmem(surface);
+ surface_init_sysmem(surface);
+
/* We also get here when the ddraw swapchain is destroyed, for example
* for a mode switch. In this case this surface won't necessarily be
* an implicit surface. We have to mark it lost so that the
@@ -1355,10 +1218,6 @@ static void surface_unload(struct wined3d_resource *resource)
context = context_acquire(device, NULL);
gl_info = context->gl_info;
- /* Destroy PBOs, but load them into real sysmem before */
- if (surface->flags & SFLAG_PBO)
- surface_remove_pbo(surface, gl_info);
-
/* Destroy fbo render buffers. This is needed for implicit render targets, for
* all application-created targets the application has to release the surface
* before calling _Reset
@@ -1541,21 +1400,9 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
surface, surface->texture_level, format->glFormat, format->glType,
surface->resource.allocatedMemory);
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
- GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, surface->texture_level, NULL));
- checkGLcall("glGetCompressedTexImageARB");
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
- checkGLcall("glBindBufferARB");
- }
- else
- {
- GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target,
- surface->texture_level, surface->resource.allocatedMemory));
- checkGLcall("glGetCompressedTexImageARB");
- }
+ GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target,
+ surface->texture_level, surface->resource.allocatedMemory));
+ checkGLcall("glGetCompressedTexImageARB");
}
else
{
@@ -1588,24 +1435,9 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n",
surface, surface->texture_level, gl_format, gl_type, mem);
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
-
- gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
- gl_format, gl_type, NULL);
- checkGLcall("glGetTexImage");
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
- checkGLcall("glBindBufferARB");
- }
- else
- {
- gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
- gl_format, gl_type, mem);
- checkGLcall("glGetTexImage");
- }
+ gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
+ gl_format, gl_type, mem);
+ checkGLcall("glGetTexImage");
if (surface->flags & SFLAG_NONPOW2)
{
@@ -2040,7 +1872,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
surface_load_location(dst_surface, SFLAG_INTEXTURE);
wined3d_texture_bind(dst_surface->container, context, FALSE);
- data.buffer_object = src_surface->pbo;
+ data.buffer_object = 0;
data.addr = src_surface->resource.allocatedMemory;
src_pitch = wined3d_surface_get_pitch(src_surface);
@@ -3329,8 +3161,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
if (FAILED(hr))
return WINED3DERR_INVALIDCALL;
- /* Use the DIB section from now on if we are not using a PBO. */
- if (!(surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)))
+ if (!(surface->flags & SFLAG_PIN_SYSMEM))
{
wined3d_resource_free_sysmem(&surface->resource);
surface->resource.allocatedMemory = surface->dib.bitmap_data;
@@ -3345,9 +3176,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
return hr;
}
- /* Sync the DIB with the PBO. This can't be done earlier because Map()
- * activates the allocatedMemory. */
- if (surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM))
+ if (surface->flags & SFLAG_PIN_SYSMEM)
memcpy(surface->dib.bitmap_data, surface->resource.allocatedMemory, surface->resource.size);
if (surface->resource.format->id == WINED3DFMT_P8_UINT
@@ -3409,8 +3238,7 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
return WINEDDERR_NODC;
}
- /* Copy the contents of the DIB over to the PBO. */
- if ((surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)) && surface->resource.allocatedMemory)
+ if ((surface->flags & SFLAG_PIN_SYSMEM) && surface->resource.allocatedMemory)
memcpy(surface->resource.allocatedMemory, surface->dib.bitmap_data, surface->resource.size);
/* We locked first, so unlock now. */
@@ -3531,17 +3359,6 @@ static void read_from_framebuffer(struct wined3d_surface *surface, void *dest, U
bpp = surface->resource.format->byte_count;
}
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
- if (mem)
- {
- ERR("mem not null for pbo -- unexpected\n");
- mem = NULL;
- }
- }
-
/* Save old pixel store pack state */
gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen);
checkGLcall("glGetIntegerv");
@@ -3571,25 +3388,6 @@ static void read_from_framebuffer(struct wined3d_surface *surface, void *dest, U
gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_ROWS, skipRow);
checkGLcall("glPixelStorei");
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
- checkGLcall("glBindBufferARB");
-
- /* Check if we need to flip the image. If we need to flip use glMapBufferARB
- * to get a pointer to it and perform the flipping in software. This is a lot
- * faster than calling glReadPixels for each line. In case we want more speed
- * we should rerender it flipped in a FBO and read the data back from the FBO. */
- if (!srcIsUpsideDown)
- {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
- checkGLcall("glBindBufferARB");
-
- mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
- checkGLcall("glMapBufferARB");
- }
- }
-
/* TODO: Merge this with the palettization loop below for P8 targets */
if (!srcIsUpsideDown)
{
@@ -3618,13 +3416,6 @@ static void read_from_framebuffer(struct wined3d_surface *surface, void *dest, U
bottom -= pitch;
}
HeapFree(GetProcessHeap(), 0, row);
-
- /* Unmap the temp PBO buffer */
- if (surface->flags & SFLAG_PBO)
- {
- GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
- }
}
/* For P8 textures we need to perform an inverse palette lookup. This is
@@ -4034,13 +3825,6 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back)
back->resource.heap_memory = tmp;
}
- /* Flip the PBO */
- {
- GLuint tmp_pbo = front->pbo;
- front->pbo = back->pbo;
- back->pbo = tmp_pbo;
- }
-
/* Flip the opengl texture */
{
GLuint tmp;
@@ -5182,15 +4966,6 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
width = surface->resource.width;
src_pitch = wined3d_surface_get_pitch(surface);
- /* Don't use PBOs for converted surfaces. During PBO conversion we look at
- * SFLAG_CONVERTED but it isn't set (yet) in all cases it is getting
- * called. */
- if ((convert != WINED3D_CT_NONE || format.convert) && (surface->flags & SFLAG_PBO))
- {
- TRACE("Removing the pbo attached to surface %p.\n", surface);
- surface_remove_pbo(surface, gl_info);
- }
-
if (format.convert)
{
/* This code is entered for texture formats which need a fixup. */
@@ -5236,14 +5011,14 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
mem = surface->resource.allocatedMemory;
}
- data.buffer_object = surface->pbo;
+ data.buffer_object = 0;
data.addr = mem;
surface_upload_data(surface, gl_info, &format, &src_rect, src_pitch, &dst_point, srgb, &data);
context_release(context);
/* Don't delete PBO memory. */
- if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO))
+ if (mem != surface->resource.allocatedMemory)
HeapFree(GetProcessHeap(), 0, mem);
return WINED3D_OK;
@@ -5293,11 +5068,6 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location)
if (surface->flags & location)
{
TRACE("Location already up to date.\n");
-
- if (location == SFLAG_INSYSMEM && !(surface->flags & SFLAG_PBO)
- && surface_need_pbo(surface, gl_info))
- surface_load_pbo(surface, gl_info);
-
return WINED3D_OK;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d7e1c5f..7feb777 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2191,8 +2191,6 @@ struct wined3d_surface
/* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
void (*get_drawable_size)(const struct wined3d_context *context, UINT *width, UINT *height);
- /* PBO */
- GLuint pbo;
GLuint rb_multisample;
GLuint rb_resolved;
GLint texture_level;
@@ -2290,20 +2288,18 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
#define SFLAG_USERPTR 0x00000800 /* The application allocated the memory for this surface. */
#define SFLAG_ALLOCATED 0x00001000 /* A GL texture is allocated for this surface. */
#define SFLAG_SRGBALLOCATED 0x00002000 /* A sRGB GL texture is allocated for this surface. */
-#define SFLAG_PBO 0x00004000 /* The surface has a PBO. */
-#define SFLAG_INSYSMEM 0x00008000 /* The system memory copy is current. */
-#define SFLAG_INTEXTURE 0x00010000 /* The GL texture is current. */
-#define SFLAG_INSRGBTEX 0x00020000 /* The GL sRGB texture is current. */
-#define SFLAG_INDRAWABLE 0x00040000 /* The GL drawable is current. */
-#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_INSYSMEM 0x00004000 /* The system memory copy is current. */
+#define SFLAG_INTEXTURE 0x00008000 /* The GL texture is current. */
+#define SFLAG_INSRGBTEX 0x00010000 /* The GL sRGB texture is current. */
+#define SFLAG_INDRAWABLE 0x00020000 /* The GL drawable is current. */
+#define SFLAG_INRB_MULTISAMPLE 0x00040000 /* The multisample renderbuffer is current. */
+#define SFLAG_INRB_RESOLVED 0x00080000 /* The resolved renderbuffer is current. */
+#define SFLAG_DISCARDED 0x00100000 /* Surface was discarded, allocating new location is enough. */
/* In some conditions the surface memory must not be freed:
* SFLAG_CONVERTED: Converting the data back would take too long
* SFLAG_DIBSECTION: The dib code manages the memory
* SFLAG_DYNLOCK: Avoid freeing the data for performance
- * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
* SFLAG_CLIENT: OpenGL uses our memory as backup
*/
#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \
@@ -2311,7 +2307,6 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
SFLAG_CLIENT | \
SFLAG_DIBSECTION | \
SFLAG_USERPTR | \
- SFLAG_PBO | \
SFLAG_PIN_SYSMEM)
#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \
--
1.8.3.2
More information about the wine-patches
mailing list