wined3d: Allow textures as swapchain surfaces.

This commit is contained in:
Henri Verbeet 2013-06-03 09:19:35 +02:00 committed by Alexandre Julliard
parent 48d470f60c
commit a3f59cf618
7 changed files with 120 additions and 159 deletions

View File

@ -7245,8 +7245,8 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum textype; GLenum textype;
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
textype = surface->container.u.texture->target; textype = surface->container->target;
else else
textype = surface->texture_target; textype = surface->texture_target;
@ -7429,8 +7429,7 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
arbfp_blit_unset(context->gl_info); arbfp_blit_unset(context->gl_info);
if (wined3d_settings.strict_draw_ordering if (wined3d_settings.strict_draw_ordering
|| (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN || (dst_surface->swapchain && (dst_surface->swapchain->front_buffer == dst_surface)))
&& (dst_surface->container.u.swapchain->front_buffer == dst_surface)))
context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context); context_release(context);

View File

@ -1705,8 +1705,7 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz
{ {
const struct wined3d_surface *rt = context->current_rt; const struct wined3d_surface *rt = context->current_rt;
if (rt->container.type == WINED3D_CONTAINER_SWAPCHAIN if (rt->swapchain && rt->swapchain->front_buffer == rt)
&& rt->container.u.swapchain->front_buffer == rt)
{ {
RECT window_size; RECT window_size;
@ -2086,7 +2085,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
const struct wined3d_surface *depth_stencil) const struct wined3d_surface *depth_stencil)
{ {
/* Onscreen surfaces are always in a swapchain */ /* Onscreen surfaces are always in a swapchain */
struct wined3d_swapchain *swapchain = context->current_rt->container.u.swapchain; struct wined3d_swapchain *swapchain = context->current_rt->swapchain;
if (context->render_offscreen || !depth_stencil) return; if (context->render_offscreen || !depth_stencil) return;
if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format)) return; if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format)) return;
@ -2107,7 +2106,7 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device
{ {
if (!rt || rt->resource.format->id == WINED3DFMT_NULL) if (!rt || rt->resource.format->id == WINED3DFMT_NULL)
return 0; return 0;
else if (rt->container.type == WINED3D_CONTAINER_SWAPCHAIN) else if (rt->swapchain)
return context_generate_rt_mask_from_surface(rt); return context_generate_rt_mask_from_surface(rt);
else else
return context_generate_rt_mask(device->offscreenBuffer); return context_generate_rt_mask(device->offscreenBuffer);
@ -2497,11 +2496,11 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str
{ {
context = current_context; context = current_context;
} }
else if (target->container.type == WINED3D_CONTAINER_SWAPCHAIN) else if (target->swapchain)
{ {
TRACE("Rendering onscreen.\n"); TRACE("Rendering onscreen.\n");
context = swapchain_get_context(target->container.u.swapchain); context = swapchain_get_context(target->swapchain);
} }
else else
{ {

View File

@ -715,8 +715,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
} }
if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
&& target->container.type == WINED3D_CONTAINER_SWAPCHAIN && target->swapchain && target->swapchain->front_buffer == target))
&& target->container.u.swapchain->front_buffer == target))
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context); context_release(context);

View File

@ -124,14 +124,11 @@ void surface_update_draw_binding(struct wined3d_surface *surface)
surface->draw_binding = SFLAG_INTEXTURE; surface->draw_binding = SFLAG_INTEXTURE;
} }
void surface_set_container(struct wined3d_surface *surface, enum wined3d_container_type type, void *container) void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain)
{ {
TRACE("surface %p, container %p.\n", surface, container); TRACE("surface %p, swapchain %p.\n", surface, swapchain);
if (!container && type != WINED3D_CONTAINER_NONE) if (swapchain)
ERR("Setting NULL container of type %#x.\n", type);
if (type == WINED3D_CONTAINER_SWAPCHAIN)
{ {
surface->get_drawable_size = get_drawable_size_swapchain; surface->get_drawable_size = get_drawable_size_swapchain;
} }
@ -153,8 +150,33 @@ void surface_set_container(struct wined3d_surface *surface, enum wined3d_contain
} }
} }
surface->container.type = type; surface->swapchain = swapchain;
surface->container.u.base = container; surface_update_draw_binding(surface);
}
void surface_set_container(struct wined3d_surface *surface, struct wined3d_texture *container)
{
TRACE("surface %p, container %p.\n", surface, container);
if (!surface->swapchain)
{
switch (wined3d_settings.offscreen_rendering_mode)
{
case ORM_FBO:
surface->get_drawable_size = get_drawable_size_fbo;
break;
case ORM_BACKBUFFER:
surface->get_drawable_size = get_drawable_size_backbuffer;
break;
default:
ERR("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode);
return;
}
}
surface->container = container;
surface_update_draw_binding(surface); surface_update_draw_binding(surface);
} }
@ -358,9 +380,9 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3
/* We changed the filtering settings on the texture. Inform the /* We changed the filtering settings on the texture. Inform the
* container about this to get the filters reset properly next draw. */ * container about this to get the filters reset properly next draw. */
if (src_surface->container.type == WINED3D_CONTAINER_TEXTURE) if (src_surface->container)
{ {
struct wined3d_texture *texture = src_surface->container.u.texture; struct wined3d_texture *texture = src_surface->container;
texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT; texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE; texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
@ -597,9 +619,9 @@ static void surface_bind(struct wined3d_surface *surface, struct wined3d_context
{ {
TRACE("surface %p, context %p, srgb %#x.\n", surface, context, srgb); TRACE("surface %p, context %p, srgb %#x.\n", surface, context, srgb);
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
struct wined3d_texture *texture = surface->container.u.texture; struct wined3d_texture *texture = surface->container;
TRACE("Passing to container (%p).\n", texture); TRACE("Passing to container (%p).\n", texture);
texture->texture_ops->texture_bind(texture, context, srgb); texture->texture_ops->texture_bind(texture, context, srgb);
@ -988,8 +1010,7 @@ static void surface_unmap(struct wined3d_surface *surface)
goto done; goto done;
} }
if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN if (surface->swapchain && surface->swapchain->front_buffer == surface)
&& surface->container.u.swapchain->front_buffer == surface)
{ {
if (!surface->dirtyRect.left && !surface->dirtyRect.top if (!surface->dirtyRect.left && !surface->dirtyRect.top
&& surface->dirtyRect.right == surface->resource.width && surface->dirtyRect.right == surface->resource.width
@ -1248,7 +1269,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_te
if (wined3d_settings.strict_draw_ordering if (wined3d_settings.strict_draw_ordering
|| (dst_location == SFLAG_INDRAWABLE || (dst_location == SFLAG_INDRAWABLE
&& dst_surface->container.u.swapchain->front_buffer == dst_surface)) && dst_surface->swapchain->front_buffer == dst_surface))
gl_info->gl_ops.gl.p_glFlush(); gl_info->gl_ops.gl.p_glFlush();
context_release(context); context_release(context);
@ -1563,15 +1584,12 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
goto fallback; goto fallback;
} }
if (src_surface && src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) if (src_surface)
src_swapchain = src_surface->container.u.swapchain; src_swapchain = src_surface->swapchain;
else else
src_swapchain = NULL; src_swapchain = NULL;
if (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) dst_swapchain = dst_surface->swapchain;
dst_swapchain = dst_surface->container.u.swapchain;
else
dst_swapchain = NULL;
/* This isn't strictly needed. FBO blits for example could deal with /* This isn't strictly needed. FBO blits for example could deal with
* cross-swapchain blits by first downloading the source to a texture * cross-swapchain blits by first downloading the source to a texture
@ -1879,7 +1897,7 @@ static void surface_unload(struct wined3d_resource *resource)
/* If we're in a texture, the texture name belongs to the texture. /* If we're in a texture, the texture name belongs to the texture.
* Otherwise, destroy it. */ * Otherwise, destroy it. */
if (surface->container.type != WINED3D_CONTAINER_TEXTURE) if (!surface->container)
{ {
gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name); gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name);
surface->texture_name = 0; surface->texture_name = 0;
@ -1987,14 +2005,8 @@ static void gdi_surface_realize_palette(struct wined3d_surface *surface)
/* Update the image because of the palette change. Some games like e.g. /* Update the image because of the palette change. Some games like e.g.
* Red Alert call SetEntries a lot to implement fading. */ * Red Alert call SetEntries a lot to implement fading. */
/* Tell the swapchain to update the screen. */ /* Tell the swapchain to update the screen. */
if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) if (surface->swapchain && surface == surface->swapchain->front_buffer)
{ x11_copy_to_screen(surface->swapchain, NULL);
struct wined3d_swapchain *swapchain = surface->container.u.swapchain;
if (surface == swapchain->front_buffer)
{
x11_copy_to_screen(swapchain, NULL);
}
}
} }
static void gdi_surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags) static void gdi_surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags)
@ -2024,14 +2036,8 @@ static void gdi_surface_unmap(struct wined3d_surface *surface)
TRACE("surface %p.\n", surface); TRACE("surface %p.\n", surface);
/* Tell the swapchain to update the screen. */ /* Tell the swapchain to update the screen. */
if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) if (surface->swapchain && surface == surface->swapchain->front_buffer)
{ x11_copy_to_screen(surface->swapchain, &surface->lockedRect);
struct wined3d_swapchain *swapchain = surface->container.u.swapchain;
if (surface == swapchain->front_buffer)
{
x11_copy_to_screen(swapchain, &surface->lockedRect);
}
}
memset(&surface->lockedRect, 0, sizeof(RECT)); memset(&surface->lockedRect, 0, sizeof(RECT));
} }
@ -2786,11 +2792,11 @@ void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const
GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) GLenum surface_get_gl_buffer(const struct wined3d_surface *surface)
{ {
const struct wined3d_swapchain *swapchain = surface->container.u.swapchain; const struct wined3d_swapchain *swapchain = surface->swapchain;
TRACE("surface %p.\n", surface); TRACE("surface %p.\n", surface);
if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) if (!swapchain)
{ {
ERR("Surface %p is not on a swapchain.\n", surface); ERR("Surface %p is not on a swapchain.\n", surface);
return GL_NONE; return GL_NONE;
@ -2842,10 +2848,10 @@ void surface_add_dirty_rect(struct wined3d_surface *surface, const struct wined3
} }
/* if the container is a texture then mark it dirty. */ /* if the container is a texture then mark it dirty. */
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
TRACE("Passing to container.\n"); TRACE("Passing to container.\n");
wined3d_texture_set_dirty(surface->container.u.texture, TRUE); wined3d_texture_set_dirty(surface->container, TRUE);
} }
} }
@ -2967,22 +2973,14 @@ ULONG CDECL wined3d_surface_incref(struct wined3d_surface *surface)
{ {
ULONG refcount; ULONG refcount;
TRACE("Surface %p, container %p of type %#x.\n", TRACE("surface %p, swapchain %p, container %p.\n",
surface, surface->container.u.base, surface->container.type); surface, surface->swapchain, surface->container);
switch (surface->container.type) if (surface->swapchain)
{ return wined3d_swapchain_incref(surface->swapchain);
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_incref(surface->container.u.texture);
case WINED3D_CONTAINER_SWAPCHAIN: if (surface->container)
return wined3d_swapchain_incref(surface->container.u.swapchain); return wined3d_texture_incref(surface->container);
default:
ERR("Unhandled container type %#x.\n", surface->container.type);
case WINED3D_CONTAINER_NONE:
break;
}
refcount = InterlockedIncrement(&surface->resource.ref); refcount = InterlockedIncrement(&surface->resource.ref);
TRACE("%p increasing refcount to %u.\n", surface, refcount); TRACE("%p increasing refcount to %u.\n", surface, refcount);
@ -2995,22 +2993,14 @@ ULONG CDECL wined3d_surface_decref(struct wined3d_surface *surface)
{ {
ULONG refcount; ULONG refcount;
TRACE("Surface %p, container %p of type %#x.\n", TRACE("surface %p, swapchain %p, container %p.\n",
surface, surface->container.u.base, surface->container.type); surface, surface->swapchain, surface->container);
switch (surface->container.type) if (surface->swapchain)
{ return wined3d_swapchain_decref(surface->swapchain);
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_decref(surface->container.u.texture);
case WINED3D_CONTAINER_SWAPCHAIN: if (surface->container)
return wined3d_swapchain_decref(surface->container.u.swapchain); return wined3d_texture_decref(surface->container);
default:
ERR("Unhandled container type %#x.\n", surface->container.type);
case WINED3D_CONTAINER_NONE:
break;
}
refcount = InterlockedDecrement(&surface->resource.ref); refcount = InterlockedDecrement(&surface->resource.ref);
TRACE("%p decreasing refcount to %u.\n", surface, refcount); TRACE("%p decreasing refcount to %u.\n", surface, refcount);
@ -4065,7 +4055,7 @@ HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined
WARN("Ignoring flags %#x.\n", flags); WARN("Ignoring flags %#x.\n", flags);
} }
if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) if (surface->swapchain)
{ {
ERR("Not supported on swapchain surfaces.\n"); ERR("Not supported on swapchain surfaces.\n");
return WINEDDERR_NOTFLIPPABLE; return WINEDDERR_NOTFLIPPABLE;
@ -4094,9 +4084,9 @@ void surface_internal_preload(struct wined3d_surface *surface, enum WINED3DSRGB
TRACE("iface %p, srgb %#x.\n", surface, srgb); TRACE("iface %p, srgb %#x.\n", surface, srgb);
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
struct wined3d_texture *texture = surface->container.u.texture; struct wined3d_texture *texture = surface->container;
TRACE("Passing to container (%p).\n", texture); TRACE("Passing to container (%p).\n", texture);
texture->texture_ops->texture_preload(texture, srgb); texture->texture_ops->texture_preload(texture, srgb);
@ -4422,9 +4412,9 @@ static void surface_prepare_texture_internal(struct wined3d_surface *surface,
/* Context activation is done by the caller. */ /* Context activation is done by the caller. */
void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb)
{ {
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
struct wined3d_texture *texture = surface->container.u.texture; struct wined3d_texture *texture = surface->container;
UINT sub_count = texture->level_count * texture->layer_count; UINT sub_count = texture->level_count * texture->layer_count;
UINT i; UINT i;
@ -4532,8 +4522,7 @@ static void flush_to_framebuffer_drawpixels(struct wined3d_surface *surface,
checkGLcall("glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)"); checkGLcall("glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)");
if (wined3d_settings.strict_draw_ordering if (wined3d_settings.strict_draw_ordering
|| (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN || (surface->swapchain && surface->swapchain->front_buffer == surface))
&& surface->container.u.swapchain->front_buffer == surface))
gl_info->gl_ops.gl.p_glFlush(); gl_info->gl_ops.gl.p_glFlush();
context_release(context); context_release(context);
@ -4849,8 +4838,8 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc
RECT dst_rect = *dst_rect_in; RECT dst_rect = *dst_rect_in;
GLenum dst_target; GLenum dst_target;
if (dst_surface->container.type == WINED3D_CONTAINER_TEXTURE) if (dst_surface->container)
dst_target = dst_surface->container.u.texture->target; dst_target = dst_surface->container->target;
else else
dst_target = dst_surface->texture_target; dst_target = dst_surface->texture_target;
@ -4957,7 +4946,6 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
{ {
struct wined3d_device *device = dst_surface->resource.device; struct wined3d_device *device = dst_surface->resource.device;
struct wined3d_swapchain *src_swapchain = NULL;
GLuint src, backup = 0; GLuint src, backup = 0;
float left, right, top, bottom; /* Texture coordinates */ float left, right, top, bottom; /* Texture coordinates */
UINT fbwidth = src_surface->resource.width; UINT fbwidth = src_surface->resource.width;
@ -5055,9 +5043,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE)); wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE));
checkGLcall("glTexParameteri"); checkGLcall("glTexParameteri");
if (src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) if (!src_surface->swapchain || src_surface == src_surface->swapchain->back_buffers[0])
src_swapchain = src_surface->container.u.swapchain;
if (!src_swapchain || src_surface == src_swapchain->back_buffers[0])
{ {
src = backup ? backup : src_surface->texture_name; src = backup ? backup : src_surface->texture_name;
} }
@ -5236,8 +5222,7 @@ void surface_translate_drawable_coords(const struct wined3d_surface *surface, HW
{ {
UINT drawable_height; UINT drawable_height;
if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN if (surface->swapchain && surface == surface->swapchain->front_buffer)
&& surface == surface->container.u.swapchain->front_buffer)
{ {
POINT offset = {0, 0}; POINT offset = {0, 0};
RECT windowsize; RECT windowsize;
@ -5318,8 +5303,7 @@ static void surface_blt_to_drawable(const struct wined3d_device *device,
device->blitter->unset_shader(context->gl_info); device->blitter->unset_shader(context->gl_info);
if (wined3d_settings.strict_draw_ordering if (wined3d_settings.strict_draw_ordering
|| (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN || (dst_surface->swapchain && dst_surface->swapchain->front_buffer == dst_surface))
&& (dst_surface->container.u.swapchain->front_buffer == dst_surface)))
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context); context_release(context);
@ -5349,7 +5333,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa
{ {
struct wined3d_device *device = dst_surface->resource.device; struct wined3d_device *device = dst_surface->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_swapchain *srcSwapchain = NULL, *dstSwapchain = NULL; struct wined3d_swapchain *src_swapchain, *dst_swapchain;
TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n",
dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
@ -5362,8 +5346,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) dst_swapchain = dst_surface->swapchain;
dstSwapchain = dst_surface->container.u.swapchain;
if (src_surface) if (src_surface)
{ {
@ -5373,12 +5356,15 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) src_swapchain = src_surface->swapchain;
srcSwapchain = src_surface->container.u.swapchain; }
else
{
src_swapchain = NULL;
} }
/* Early sort out of cases where no render target is used */ /* Early sort out of cases where no render target is used */
if (!dstSwapchain && !srcSwapchain if (!dst_swapchain && !src_swapchain
&& src_surface != device->fb.render_targets[0] && src_surface != device->fb.render_targets[0]
&& dst_surface != device->fb.render_targets[0]) && dst_surface != device->fb.render_targets[0])
{ {
@ -5394,31 +5380,31 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surfa
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (dstSwapchain && dstSwapchain == srcSwapchain) if (dst_swapchain && dst_swapchain == src_swapchain)
{ {
FIXME("Implement hardware blit between two surfaces on the same swapchain\n"); FIXME("Implement hardware blit between two surfaces on the same swapchain\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (dstSwapchain && srcSwapchain) if (dst_swapchain && src_swapchain)
{ {
FIXME("Implement hardware blit between two different swapchains\n"); FIXME("Implement hardware blit between two different swapchains\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (dstSwapchain) if (dst_swapchain)
{ {
/* Handled with regular texture -> swapchain blit */ /* Handled with regular texture -> swapchain blit */
if (src_surface == device->fb.render_targets[0]) if (src_surface == device->fb.render_targets[0])
TRACE("Blit from active render target to a swapchain\n"); TRACE("Blit from active render target to a swapchain\n");
} }
else if (srcSwapchain && dst_surface == device->fb.render_targets[0]) else if (src_swapchain && dst_surface == device->fb.render_targets[0])
{ {
FIXME("Implement blit from a swapchain to the active render target\n"); FIXME("Implement blit from a swapchain to the active render target\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if ((srcSwapchain || src_surface == device->fb.render_targets[0]) && !dstSwapchain) if ((src_swapchain || src_surface == device->fb.render_targets[0]) && !dst_swapchain)
{ {
/* Blit from render target to texture */ /* Blit from render target to texture */
BOOL stretchx; BOOL stretchx;
@ -5605,10 +5591,10 @@ void surface_modify_ds_location(struct wined3d_surface *surface,
if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE)) if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
|| (!(surface->flags & SFLAG_INTEXTURE) && (location & SFLAG_INTEXTURE))) || (!(surface->flags & SFLAG_INTEXTURE) && (location & SFLAG_INTEXTURE)))
{ {
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
TRACE("Passing to container.\n"); TRACE("Passing to container.\n");
wined3d_texture_set_dirty(surface->container.u.texture, TRUE); wined3d_texture_set_dirty(surface->container, TRUE);
} }
} }
@ -5797,10 +5783,10 @@ void surface_modify_location(struct wined3d_surface *surface, DWORD location, BO
if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE)) if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
|| ((surface->flags & SFLAG_INSRGBTEX) && !(location & SFLAG_INSRGBTEX))) || ((surface->flags & SFLAG_INSRGBTEX) && !(location & SFLAG_INSRGBTEX)))
{ {
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
TRACE("Passing to container.\n"); TRACE("Passing to container.\n");
wined3d_texture_set_dirty(surface->container.u.texture, TRUE); wined3d_texture_set_dirty(surface->container, TRUE);
} }
} }
surface->flags &= ~SFLAG_LOCATIONS; surface->flags &= ~SFLAG_LOCATIONS;
@ -5819,10 +5805,10 @@ void surface_modify_location(struct wined3d_surface *surface, DWORD location, BO
{ {
if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX))) if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)))
{ {
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
{ {
TRACE("Passing to container\n"); TRACE("Passing to container\n");
wined3d_texture_set_dirty(surface->container.u.texture, TRUE); wined3d_texture_set_dirty(surface->container, TRUE);
} }
} }
surface->flags &= ~location; surface->flags &= ~location;
@ -6267,10 +6253,11 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, c
BOOL surface_is_offscreen(const struct wined3d_surface *surface) BOOL surface_is_offscreen(const struct wined3d_surface *surface)
{ {
struct wined3d_swapchain *swapchain = surface->container.u.swapchain; struct wined3d_swapchain *swapchain;
/* Not on a swapchain - must be offscreen */ /* Not on a swapchain - must be offscreen */
if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) return TRUE; if (!(swapchain = surface->swapchain))
return TRUE;
/* The front buffer is always onscreen */ /* The front buffer is always onscreen */
if (surface == swapchain->front_buffer) return FALSE; if (surface == swapchain->front_buffer) return FALSE;
@ -6292,8 +6279,8 @@ static void ffp_blit_p8_upload_palette(const struct wined3d_surface *surface, co
BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) != 0; BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) != 0;
GLenum target; GLenum target;
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
target = surface->container.u.texture->target; target = surface->container->target;
else else
target = surface->texture_target; target = surface->texture_target;
@ -6310,8 +6297,8 @@ static HRESULT ffp_blit_set(void *blit_priv, struct wined3d_context *context, co
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum target; GLenum target;
if (surface->container.type == WINED3D_CONTAINER_TEXTURE) if (surface->container)
target = surface->container.u.texture->target; target = surface->container->target;
else else
target = surface->texture_target; target = surface->texture_target;
@ -7190,7 +7177,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, UINT alignment, UIN
} }
/* "Standalone" surface. */ /* "Standalone" surface. */
surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); surface_set_container(surface, NULL);
list_init(&surface->overlays); list_init(&surface->overlays);

View File

@ -42,8 +42,7 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
* is the last buffer to be destroyed, FindContext() depends on that. */ * is the last buffer to be destroyed, FindContext() depends on that. */
if (swapchain->front_buffer) if (swapchain->front_buffer)
{ {
if (swapchain->front_buffer->container.type == WINED3D_CONTAINER_SWAPCHAIN) surface_set_swapchain(swapchain->front_buffer, NULL);
surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL);
if (wined3d_surface_decref(swapchain->front_buffer)) if (wined3d_surface_decref(swapchain->front_buffer))
WARN("Something's still holding the front buffer (%p).\n", swapchain->front_buffer); WARN("Something's still holding the front buffer (%p).\n", swapchain->front_buffer);
swapchain->front_buffer = NULL; swapchain->front_buffer = NULL;
@ -55,8 +54,7 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
while (i--) while (i--)
{ {
if (swapchain->back_buffers[i]->container.type == WINED3D_CONTAINER_SWAPCHAIN) surface_set_swapchain(swapchain->back_buffers[i], NULL);
surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
if (wined3d_surface_decref(swapchain->back_buffers[i])) if (wined3d_surface_decref(swapchain->back_buffers[i]))
WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]); WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
} }
@ -898,8 +896,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
goto err; goto err;
} }
if (swapchain->front_buffer->container.type == WINED3D_CONTAINER_NONE) surface_set_swapchain(swapchain->front_buffer, swapchain);
surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_SWAPCHAIN, swapchain);
if (!(device->wined3d->flags & WINED3D_NO3D)) if (!(device->wined3d->flags & WINED3D_NO3D))
surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE); surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
@ -1007,8 +1004,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
goto err; goto err;
} }
if (swapchain->back_buffers[i]->container.type == WINED3D_CONTAINER_NONE) surface_set_swapchain(swapchain->back_buffers[i], swapchain);
surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_SWAPCHAIN, swapchain);
} }
} }
@ -1027,8 +1023,6 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); WARN("Failed to create the auto depth stencil, hr %#x.\n", hr);
goto err; goto err;
} }
surface_set_container(device->auto_depth_stencil, WINED3D_CONTAINER_NONE, NULL);
} }
} }
@ -1059,7 +1053,7 @@ err:
{ {
if (swapchain->back_buffers[i]) if (swapchain->back_buffers[i])
{ {
surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL); surface_set_swapchain(swapchain->back_buffers[i], NULL);
wined3d_surface_decref(swapchain->back_buffers[i]); wined3d_surface_decref(swapchain->back_buffers[i]);
} }
} }
@ -1079,7 +1073,7 @@ err:
if (swapchain->front_buffer) if (swapchain->front_buffer)
{ {
surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL); surface_set_swapchain(swapchain->front_buffer, NULL);
wined3d_surface_decref(swapchain->front_buffer); wined3d_surface_decref(swapchain->front_buffer);
} }

View File

@ -715,7 +715,7 @@ static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource
surface_set_texture_name(surface, 0, TRUE); surface_set_texture_name(surface, 0, TRUE);
surface_set_texture_name(surface, 0, FALSE); surface_set_texture_name(surface, 0, FALSE);
surface_set_texture_target(surface, 0, 0); surface_set_texture_target(surface, 0, 0);
surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); surface_set_container(surface, NULL);
wined3d_surface_decref(surface); wined3d_surface_decref(surface);
} }
@ -864,7 +864,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, UINT edge_lengt
return hr; return hr;
} }
surface_set_container(surface, WINED3D_CONTAINER_TEXTURE, texture); surface_set_container(surface, texture);
surface_set_texture_target(surface, cube_targets[j], i); surface_set_texture_target(surface, cube_targets[j], i);
texture->sub_resources[idx] = &surface->resource; texture->sub_resources[idx] = &surface->resource;
TRACE("Created surface level %u @ %p.\n", i, surface); TRACE("Created surface level %u @ %p.\n", i, surface);
@ -1024,7 +1024,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, UINT width, UINT he
return hr; return hr;
} }
surface_set_container(surface, WINED3D_CONTAINER_TEXTURE, texture); surface_set_container(surface, texture);
surface_set_texture_target(surface, texture->target, i); surface_set_texture_target(surface, texture->target, i);
texture->sub_resources[i] = &surface->resource; texture->sub_resources[i] = &surface->resource;
TRACE("Created surface level %u @ %p.\n", i, surface); TRACE("Created surface level %u @ %p.\n", i, surface);

View File

@ -2076,24 +2076,6 @@ struct fbo_entry
GLuint id; GLuint id;
}; };
enum wined3d_container_type
{
WINED3D_CONTAINER_NONE = 0,
WINED3D_CONTAINER_SWAPCHAIN,
WINED3D_CONTAINER_TEXTURE,
};
struct wined3d_subresource_container
{
enum wined3d_container_type type;
union
{
struct wined3d_swapchain *swapchain;
struct wined3d_texture *texture;
void *base;
} u;
};
struct wined3d_surface_ops struct wined3d_surface_ops
{ {
HRESULT (*surface_private_setup)(struct wined3d_surface *surface); HRESULT (*surface_private_setup)(struct wined3d_surface *surface);
@ -2106,7 +2088,8 @@ struct wined3d_surface
{ {
struct wined3d_resource resource; struct wined3d_resource resource;
const struct wined3d_surface_ops *surface_ops; const struct wined3d_surface_ops *surface_ops;
struct wined3d_subresource_container container; struct wined3d_texture *container;
struct wined3d_swapchain *swapchain;
struct wined3d_palette *palette; /* D3D7 style palette handling */ struct wined3d_palette *palette; /* D3D7 style palette handling */
DWORD draw_binding; DWORD draw_binding;
@ -2188,8 +2171,8 @@ void surface_prepare_texture(struct wined3d_surface *surface,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
const struct wined3d_surface *rt) DECLSPEC_HIDDEN; const struct wined3d_surface *rt) DECLSPEC_HIDDEN;
void surface_set_container(struct wined3d_surface *surface, void surface_set_container(struct wined3d_surface *surface, struct wined3d_texture *container) DECLSPEC_HIDDEN;
enum wined3d_container_type type, void *container) DECLSPEC_HIDDEN; void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN; void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN;
void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;