Commit 1ca9dfc8 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Prepare GL resources before calling context_apply_fbo_state.

parent 436eb363
...@@ -141,8 +141,6 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, ...@@ -141,8 +141,6 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
{ {
case WINED3D_LOCATION_TEXTURE_RGB: case WINED3D_LOCATION_TEXTURE_RGB:
case WINED3D_LOCATION_TEXTURE_SRGB: case WINED3D_LOCATION_TEXTURE_SRGB:
wined3d_texture_prepare_texture(depth_stencil->container, context, FALSE);
if (format_flags & WINED3DFMT_FLAG_DEPTH) if (format_flags & WINED3DFMT_FLAG_DEPTH)
{ {
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
...@@ -161,13 +159,11 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, ...@@ -161,13 +159,11 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
break; break;
case WINED3D_LOCATION_RB_MULTISAMPLE: case WINED3D_LOCATION_RB_MULTISAMPLE:
surface_prepare_rb(depth_stencil, gl_info, TRUE);
context_attach_depth_stencil_rb(gl_info, fbo_target, context_attach_depth_stencil_rb(gl_info, fbo_target,
format_flags, depth_stencil->rb_multisample); format_flags, depth_stencil->rb_multisample);
break; break;
case WINED3D_LOCATION_RB_RESOLVED: case WINED3D_LOCATION_RB_RESOLVED:
surface_prepare_rb(depth_stencil, gl_info, FALSE);
context_attach_depth_stencil_rb(gl_info, fbo_target, context_attach_depth_stencil_rb(gl_info, fbo_target,
format_flags, depth_stencil->rb_resolved); format_flags, depth_stencil->rb_resolved);
break; break;
...@@ -217,7 +213,6 @@ static void context_attach_surface_fbo(struct wined3d_context *context, ...@@ -217,7 +213,6 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
case WINED3D_LOCATION_TEXTURE_RGB: case WINED3D_LOCATION_TEXTURE_RGB:
case WINED3D_LOCATION_TEXTURE_SRGB: case WINED3D_LOCATION_TEXTURE_SRGB:
srgb = location == WINED3D_LOCATION_TEXTURE_SRGB; srgb = location == WINED3D_LOCATION_TEXTURE_SRGB;
wined3d_texture_prepare_texture(surface->container, context, srgb);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
surface->texture_target, surface_get_texture_name(surface, gl_info, srgb), surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
surface->texture_level); surface->texture_level);
...@@ -225,14 +220,12 @@ static void context_attach_surface_fbo(struct wined3d_context *context, ...@@ -225,14 +220,12 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
break; break;
case WINED3D_LOCATION_RB_MULTISAMPLE: case WINED3D_LOCATION_RB_MULTISAMPLE:
surface_prepare_rb(surface, gl_info, TRUE);
gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
GL_RENDERBUFFER, surface->rb_multisample); GL_RENDERBUFFER, surface->rb_multisample);
checkGLcall("glFramebufferRenderbuffer()"); checkGLcall("glFramebufferRenderbuffer()");
break; break;
case WINED3D_LOCATION_RB_RESOLVED: case WINED3D_LOCATION_RB_RESOLVED:
surface_prepare_rb(surface, gl_info, FALSE);
gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
GL_RENDERBUFFER, surface->rb_resolved); GL_RENDERBUFFER, surface->rb_resolved);
checkGLcall("glFramebufferRenderbuffer()"); checkGLcall("glFramebufferRenderbuffer()");
......
...@@ -317,13 +317,15 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c ...@@ -317,13 +317,15 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
* anyway. If we're not clearing the color buffer we don't have to copy either since we're not going to set * anyway. If we're not clearing the color buffer we don't have to copy either since we're not going to set
* the drawable up to date. We have to check all settings that limit the clear area though. Do not bother * the drawable up to date. We have to check all settings that limit the clear area though. Do not bother
* checking all this if the dest surface is in the drawable anyway. */ * checking all this if the dest surface is in the drawable anyway. */
if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect)) for (i = 0; i < rt_count; ++i)
{ {
for (i = 0; i < rt_count; ++i) struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]);
if (rt && rt->resource.format->id != WINED3DFMT_NULL)
{ {
struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]); if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect))
if (rt)
surface_load_location(rt, context, rt->container->resource.draw_binding); surface_load_location(rt, context, rt->container->resource.draw_binding);
else
wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding);
} }
} }
...@@ -339,6 +341,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c ...@@ -339,6 +341,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
drawable_height = depth_stencil->pow2Height; drawable_height = depth_stencil->pow2Height;
} }
if (depth_stencil && render_offscreen)
wined3d_surface_prepare(depth_stencil, context, depth_stencil->container->resource.draw_binding);
if (flags & WINED3DCLEAR_ZBUFFER) if (flags & WINED3DCLEAR_ZBUFFER)
{ {
DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
......
...@@ -620,17 +620,20 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co ...@@ -620,17 +620,20 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
} }
gl_info = context->gl_info; gl_info = context->gl_info;
if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
{ {
/* Invalidate the back buffer memory so LockRect will read it the next time */ struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]);
for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) if (target && target->resource.format->id != WINED3DFMT_NULL)
{ {
struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]); if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
if (target)
{ {
surface_load_location(target, context, target->container->resource.draw_binding); surface_load_location(target, context, target->container->resource.draw_binding);
surface_invalidate_location(target, ~target->container->resource.draw_binding); surface_invalidate_location(target, ~target->container->resource.draw_binding);
} }
else
{
wined3d_surface_prepare(target, context, target->container->resource.draw_binding);
}
} }
} }
...@@ -643,9 +646,10 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co ...@@ -643,9 +646,10 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
* that we never copy the stencil data.*/ * that we never copy the stencil data.*/
DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding
: WINED3D_LOCATION_DRAWABLE; : WINED3D_LOCATION_DRAWABLE;
struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil);
if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE])
{ {
struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil);
RECT current_rect, draw_rect, r; RECT current_rect, draw_rect, r;
if (!context->render_offscreen && ds != device->onscreen_depth_stencil) if (!context->render_offscreen && ds != device->onscreen_depth_stencil)
...@@ -661,7 +665,11 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co ...@@ -661,7 +665,11 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
IntersectRect(&r, &draw_rect, &current_rect); IntersectRect(&r, &draw_rect, &current_rect);
if (!EqualRect(&r, &draw_rect)) if (!EqualRect(&r, &draw_rect))
surface_load_ds_location(ds, context, location); surface_load_ds_location(ds, context, location);
else
wined3d_surface_prepare(ds, context, location);
} }
else
wined3d_surface_prepare(ds, context, location);
} }
if (!context_apply_draw_state(context, device)) if (!context_apply_draw_state(context, device))
......
...@@ -821,6 +821,8 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, ...@@ -821,6 +821,8 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device,
surface_load_location(src_surface, context, src_location); surface_load_location(src_surface, context, src_location);
if (!surface_is_full_rect(dst_surface, dst_rect)) if (!surface_is_full_rect(dst_surface, dst_rect))
surface_load_location(dst_surface, context, dst_location); surface_load_location(dst_surface, context, dst_location);
else
wined3d_surface_prepare(dst_surface, context, dst_location);
gl_info = context->gl_info; gl_info = context->gl_info;
...@@ -912,6 +914,9 @@ static void surface_blt_fbo(const struct wined3d_device *device, ...@@ -912,6 +914,9 @@ static void surface_blt_fbo(const struct wined3d_device *device,
surface_load_location(src_surface, old_ctx, src_location); surface_load_location(src_surface, old_ctx, src_location);
if (!surface_is_full_rect(dst_surface, &dst_rect)) if (!surface_is_full_rect(dst_surface, &dst_rect))
surface_load_location(dst_surface, old_ctx, dst_location); surface_load_location(dst_surface, old_ctx, dst_location);
else
wined3d_surface_prepare(dst_surface, old_ctx, dst_location);
if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface; if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface;
else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface; else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface;
...@@ -3658,23 +3663,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co ...@@ -3658,23 +3663,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co
if (surface->locations & WINED3D_LOCATION_DISCARDED) if (surface->locations & WINED3D_LOCATION_DISCARDED)
{ {
TRACE("Surface was discarded, no need copy data.\n"); TRACE("Surface was discarded, no need copy data.\n");
switch (location) wined3d_surface_prepare(surface, context, location);
{
case WINED3D_LOCATION_TEXTURE_RGB:
wined3d_texture_prepare_texture(surface->container, context, FALSE);
break;
case WINED3D_LOCATION_RB_MULTISAMPLE:
surface_prepare_rb(surface, gl_info, TRUE);
break;
case WINED3D_LOCATION_RB_RESOLVED:
surface_prepare_rb(surface, gl_info, FALSE);
break;
case WINED3D_LOCATION_DRAWABLE:
/* Nothing to do */
break;
default:
FIXME("Unhandled location %#x\n", location);
}
surface->locations &= ~WINED3D_LOCATION_DISCARDED; surface->locations &= ~WINED3D_LOCATION_DISCARDED;
surface->locations |= location; surface->locations |= location;
surface->ds_current_size.cx = surface->resource.width; surface->ds_current_size.cx = surface->resource.width;
...@@ -5497,3 +5486,26 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w ...@@ -5497,3 +5486,26 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w
return hr; return hr;
} }
/* Context activation is done by the caller. */
void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location)
{
switch (location)
{
case WINED3D_LOCATION_TEXTURE_RGB:
wined3d_texture_prepare_texture(surface->container, context, FALSE);
break;
case WINED3D_LOCATION_TEXTURE_SRGB:
wined3d_texture_prepare_texture(surface->container, context, TRUE);
break;
case WINED3D_LOCATION_RB_MULTISAMPLE:
surface_prepare_rb(surface, context->gl_info, TRUE);
break;
case WINED3D_LOCATION_RB_RESOLVED:
surface_prepare_rb(surface, context->gl_info, FALSE);
break;
}
}
...@@ -2459,6 +2459,8 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, ...@@ -2459,6 +2459,8 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
HRESULT surface_load_location(struct wined3d_surface *surface, HRESULT surface_load_location(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context,
DWORD location) DECLSPEC_HIDDEN;
void surface_prepare_rb(struct wined3d_surface *surface, void surface_prepare_rb(struct wined3d_surface *surface,
const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN; const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN;
void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
......
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