Commit 3bfecd58 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Avoid a drawable -> texture transfer through sysmem in…

wined3d: Avoid a drawable -> texture transfer through sysmem in arbfp_blit_surface() with backbuffer ORM.
parent c872590a
......@@ -7270,13 +7270,28 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum win
}
HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
struct wined3d_surface *src_surface, const RECT *src_rect,
struct wined3d_surface *src_surface, const RECT *src_rect_in,
struct wined3d_surface *dst_surface, const RECT *dst_rect_in)
{
struct wined3d_context *context;
RECT src_rect = *src_rect_in;
RECT dst_rect = *dst_rect_in;
/* Now load the surface */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
&& (src_surface->flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) == SFLAG_INDRAWABLE)
{
/* Without FBO blits transfering from the drawable to the texture is
* expensive, because we have to flip the data in sysmem. Since we can
* flip in the blitter, we don't actually need that flip anyway. So we
* use the surface's texture as scratch texture, and flip the source
* rectangle instead. */
surface_load_fb_texture(src_surface, FALSE);
src_rect.top = src_surface->resource.height - src_rect.top;
src_rect.bottom = src_surface->resource.height - src_rect.bottom;
}
else
surface_internal_preload(src_surface, SRGB_RGB);
/* Activate the destination context, set it up for blitting */
......@@ -7291,7 +7306,7 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
ENTER_GL();
/* Draw a textured quad */
draw_textured_quad(src_surface, context, src_rect, &dst_rect, filter);
draw_textured_quad(src_surface, context, &src_rect, &dst_rect, filter);
LEAVE_GL();
......
......@@ -4310,25 +4310,14 @@ static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *r
}
}
/* Read the framebuffer contents into a texture */
static void read_from_framebuffer_texture(struct wined3d_surface *surface, BOOL srgb)
/* Read the framebuffer contents into a texture. Note that this function
* doesn't do any kind of flipping. Using this on an onscreen surface will
* result in a flipped D3D texture. */
void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb)
{
struct wined3d_device *device = surface->resource.device;
struct wined3d_context *context;
if (!surface_is_offscreen(surface))
{
/* We would need to flip onscreen surfaces, but there's no efficient
* way to do that here. It makes more sense for the caller to
* explicitly go through sysmem. */
ERR("Not supported for onscreen targets.\n");
return;
}
/* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer
* locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any
* states in the stateblock, and no driver was found yet that had bugs in that regard.
*/
context = context_acquire(device, surface);
device_invalidate_state(device, STATE_FRAMEBUFFER);
......@@ -4339,7 +4328,10 @@ static void read_from_framebuffer_texture(struct wined3d_surface *surface, BOOL
ENTER_GL();
if (surface_is_offscreen(surface))
glReadBuffer(device->offscreenBuffer);
else
glReadBuffer(surface_get_gl_buffer(surface));
checkGLcall("glReadBuffer");
glCopyTexSubImage2D(surface->texture_target, surface->texture_level,
......@@ -6037,7 +6029,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
&& surface_is_offscreen(surface)
&& (surface->flags & SFLAG_INDRAWABLE))
{
read_from_framebuffer_texture(surface, srgb);
surface_load_fb_texture(surface, srgb);
return WINED3D_OK;
}
......
......@@ -2088,6 +2088,7 @@ BOOL surface_is_offscreen(const struct wined3d_surface *surface) DECLSPEC_HIDDEN
HRESULT surface_load(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
void surface_load_ds_location(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, const RECT *rect) DECLSPEC_HIDDEN;
void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
void surface_modify_location(struct wined3d_surface *surface, DWORD location, BOOL persistent) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment