[PATCH 4/5] wined3d: Introduce a separate function for loading the SFLAG_INTEXTURE and SFLAG_INSRGBTEX surface locations.
Henri Verbeet
hverbeet at codeweavers.com
Mon Jul 4 14:39:38 CDT 2011
---
dlls/wined3d/surface.c | 286 +++++++++++++++++++++++++----------------------
1 files changed, 152 insertions(+), 134 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 113c3de..1cd8da6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -5996,15 +5996,161 @@ static HRESULT surface_load_drawable(struct wined3d_surface *surface,
return WINED3D_OK;
}
-HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const RECT *rect)
+static HRESULT surface_load_texture(struct wined3d_surface *surface,
+ const struct wined3d_gl_info *gl_info, const RECT *rect, BOOL srgb)
{
+ const DWORD attach_flags = WINED3DFMT_FLAG_FBO_ATTACHABLE | WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+ RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
struct wined3d_device *device = surface->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- BOOL drawable_read_ok = surface_is_offscreen(surface);
+ struct wined3d_context *context = NULL;
+ UINT width, src_pitch, dst_pitch;
+ struct wined3d_bo_address data;
struct wined3d_format format;
+ POINT dst_point = {0, 0};
CONVERT_TYPES convert;
- int width, pitch, outpitch;
BYTE *mem;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && surface_is_offscreen(surface)
+ && (surface->flags & SFLAG_INDRAWABLE))
+ {
+ read_from_framebuffer_texture(surface, srgb);
+
+ return WINED3D_OK;
+ }
+
+ if (surface->flags & (SFLAG_INSRGBTEX | SFLAG_INTEXTURE)
+ && (surface->resource.format->flags & attach_flags) == attach_flags
+ && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
+ {
+ if (srgb)
+ surface_blt_fbo(device, WINED3DTEXF_POINT, surface, SFLAG_INTEXTURE,
+ &src_rect, surface, SFLAG_INSRGBTEX, &src_rect);
+ else
+ surface_blt_fbo(device, WINED3DTEXF_POINT, surface, SFLAG_INSRGBTEX,
+ &src_rect, surface, SFLAG_INTEXTURE, &src_rect);
+
+ return WINED3D_OK;
+ }
+
+ /* Upload from system memory */
+
+ d3dfmt_get_conv(surface, TRUE /* We need color keying */,
+ TRUE /* We will use textures */, &format, &convert);
+
+ if (srgb)
+ {
+ if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE)
+ {
+ /* Performance warning... */
+ FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface);
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+ }
+ else
+ {
+ if ((surface->flags & (SFLAG_INSRGBTEX | SFLAG_INSYSMEM)) == SFLAG_INSRGBTEX)
+ {
+ /* Performance warning... */
+ FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface);
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+ }
+
+ if (!(surface->flags & SFLAG_INSYSMEM))
+ {
+ WARN("Trying to load a texture from sysmem, but SFLAG_INSYSMEM is not set.\n");
+ /* Lets hope we get it from somewhere... */
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+
+ if (!device->isInDraw)
+ context = context_acquire(device, NULL);
+
+ surface_prepare_texture(surface, gl_info, srgb);
+ surface_bind_and_dirtify(surface, gl_info, srgb);
+
+ if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
+ {
+ surface->flags |= SFLAG_GLCKEY;
+ surface->glCKey = surface->SrcBltCKey;
+ }
+ else surface->flags &= ~SFLAG_GLCKEY;
+
+ 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 != NO_CONVERSION || 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. */
+ UINT height = surface->resource.height;
+
+ /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
+ dst_pitch = width * format.conv_byte_count;
+ dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+
+ if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
+ {
+ ERR("Out of memory (%u).\n", dst_pitch * height);
+ if (context)
+ context_release(context);
+ return E_OUTOFMEMORY;
+ }
+ format.convert(surface->resource.allocatedMemory, mem, src_pitch, width, height);
+ }
+ else if (convert != NO_CONVERSION && surface->resource.allocatedMemory)
+ {
+ /* This code is only entered for color keying fixups */
+ UINT height = surface->resource.height;
+
+ /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
+ dst_pitch = width * format.conv_byte_count;
+ dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+
+ if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
+ {
+ ERR("Out of memory (%u).\n", dst_pitch * height);
+ if (context)
+ context_release(context);
+ return E_OUTOFMEMORY;
+ }
+ d3dfmt_convert_surface(surface->resource.allocatedMemory, mem, src_pitch,
+ width, height, dst_pitch, convert, surface);
+ }
+ else
+ {
+ mem = surface->resource.allocatedMemory;
+ }
+
+ data.buffer_object = surface->flags & SFLAG_PBO ? surface->pbo : 0;
+ data.addr = mem;
+ surface_upload_data(surface, gl_info, &format, &src_rect, width, &dst_point, srgb, &data);
+
+ if (context)
+ context_release(context);
+
+ /* Don't delete PBO memory. */
+ if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO))
+ HeapFree(GetProcessHeap(), 0, mem);
+
+ return WINED3D_OK;
+}
+
+HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const RECT *rect)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
BOOL in_fbo = FALSE;
HRESULT hr;
@@ -6033,7 +6179,6 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets.
* Prefer SFLAG_INTEXTURE. */
if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE;
- drawable_read_ok = FALSE;
in_fbo = TRUE;
}
else
@@ -6077,135 +6222,8 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const
}
else /* if(flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) */
{
- const DWORD attach_flags = WINED3DFMT_FLAG_FBO_ATTACHABLE | WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
-
- if (drawable_read_ok && (surface->flags & SFLAG_INDRAWABLE))
- {
- read_from_framebuffer_texture(surface, flag == SFLAG_INSRGBTEX);
- }
- else if (surface->flags & (SFLAG_INSRGBTEX | SFLAG_INTEXTURE)
- && (surface->resource.format->flags & attach_flags) == attach_flags
- && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
- NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
- NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
- {
- DWORD src_location = flag == SFLAG_INSRGBTEX ? SFLAG_INTEXTURE : SFLAG_INSRGBTEX;
- RECT rect = {0, 0, surface->resource.width, surface->resource.height};
-
- surface_blt_fbo(surface->resource.device, WINED3DTEXF_POINT,
- surface, src_location, &rect, surface, flag, &rect);
- }
- else
- {
- /* Upload from system memory */
- RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
- BOOL srgb = flag == SFLAG_INSRGBTEX;
- struct wined3d_context *context = NULL;
- struct wined3d_bo_address data;
- POINT dst_point = {0, 0};
-
- d3dfmt_get_conv(surface, TRUE /* We need color keying */,
- TRUE /* We will use textures */, &format, &convert);
-
- if (srgb)
- {
- if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE)
- {
- /* Performance warning... */
- FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface);
- surface_load_location(surface, SFLAG_INSYSMEM, rect);
- }
- }
- else
- {
- if ((surface->flags & (SFLAG_INSRGBTEX | SFLAG_INSYSMEM)) == SFLAG_INSRGBTEX)
- {
- /* Performance warning... */
- FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface);
- surface_load_location(surface, SFLAG_INSYSMEM, rect);
- }
- }
- if (!(surface->flags & SFLAG_INSYSMEM))
- {
- WARN("Trying to load a texture from sysmem, but SFLAG_INSYSMEM is not set.\n");
- /* Lets hope we get it from somewhere... */
- surface_load_location(surface, SFLAG_INSYSMEM, rect);
- }
-
- if (!device->isInDraw) context = context_acquire(device, NULL);
-
- surface_prepare_texture(surface, gl_info, srgb);
- surface_bind_and_dirtify(surface, gl_info, srgb);
-
- if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
- {
- surface->flags |= SFLAG_GLCKEY;
- surface->glCKey = surface->SrcBltCKey;
- }
- else surface->flags &= ~SFLAG_GLCKEY;
-
- /* The width is in 'length' not in bytes */
- width = surface->resource.width;
- 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 != NO_CONVERSION || 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. */
- UINT height = surface->resource.height;
-
- /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
- outpitch = width * format.conv_byte_count;
- outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
-
- mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
- if(!mem) {
- ERR("Out of memory %d, %d!\n", outpitch, height);
- if (context) context_release(context);
- return WINED3DERR_OUTOFVIDEOMEMORY;
- }
- format.convert(surface->resource.allocatedMemory, mem, pitch, width, height);
- }
- else if (convert != NO_CONVERSION && surface->resource.allocatedMemory)
- {
- /* This code is only entered for color keying fixups */
- UINT height = surface->resource.height;
-
- /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
- outpitch = width * format.conv_byte_count;
- outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
-
- mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
- if(!mem) {
- ERR("Out of memory %d, %d!\n", outpitch, height);
- if (context) context_release(context);
- return WINED3DERR_OUTOFVIDEOMEMORY;
- }
- d3dfmt_convert_surface(surface->resource.allocatedMemory, mem, pitch,
- width, height, outpitch, convert, surface);
- }
- else
- {
- mem = surface->resource.allocatedMemory;
- }
-
- data.buffer_object = surface->flags & SFLAG_PBO ? surface->pbo : 0;
- data.addr = mem;
- surface_upload_data(surface, gl_info, &format, &src_rect, width, &dst_point, srgb, &data);
-
- if (context) context_release(context);
-
- /* Don't delete PBO memory */
- if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO))
- HeapFree(GetProcessHeap(), 0, mem);
- }
+ if (FAILED(hr = surface_load_texture(surface, gl_info, rect, flag == SFLAG_INSRGBTEX)))
+ return hr;
}
if (!rect)
--
1.7.3.4
More information about the wine-patches
mailing list