Commit d6e2f650 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Store the context's current rendertarget as a texture and sub-resource index.

parent 5f05acfc
...@@ -852,22 +852,26 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context, ...@@ -852,22 +852,26 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context,
void context_resource_released(const struct wined3d_device *device, void context_resource_released(const struct wined3d_device *device,
struct wined3d_resource *resource, enum wined3d_resource_type type) struct wined3d_resource *resource, enum wined3d_resource_type type)
{ {
struct wined3d_texture *texture;
UINT i; UINT i;
struct wined3d_surface *surface;
if (!device->d3d_initialized) if (!device->d3d_initialized)
return; return;
switch (type) switch (type)
{ {
case WINED3D_RTYPE_SURFACE: case WINED3D_RTYPE_TEXTURE_2D:
surface = surface_from_resource(resource); case WINED3D_RTYPE_TEXTURE_3D:
texture = wined3d_texture_from_resource(resource);
for (i = 0; i < device->context_count; ++i) for (i = 0; i < device->context_count; ++i)
{ {
struct wined3d_context *context = device->contexts[i]; struct wined3d_context *context = device->contexts[i];
if (context->current_rt == surface) if (context->current_rt.texture == texture)
context->current_rt = NULL; {
context->current_rt.texture = NULL;
context->current_rt.sub_resource_idx = 0;
}
} }
break; break;
...@@ -1318,7 +1322,8 @@ void context_release(struct wined3d_context *context) ...@@ -1318,7 +1322,8 @@ void context_release(struct wined3d_context *context)
* A to avoid breaking caller code. */ * A to avoid breaking caller code. */
void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) void context_restore(struct wined3d_context *context, struct wined3d_surface *restore)
{ {
if (context->current_rt != restore) if (context->current_rt.texture != restore->container
|| context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore))
{ {
context_release(context); context_release(context);
context = context_acquire(restore->container->resource.device, restore); context = context_acquire(restore->container->resource.device, restore);
...@@ -1777,7 +1782,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, ...@@ -1777,7 +1782,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
} }
ret->swapchain = swapchain; ret->swapchain = swapchain;
ret->current_rt = target->sub_resources[0].u.surface; ret->current_rt.texture = target;
ret->current_rt.sub_resource_idx = 0;
ret->tid = GetCurrentThreadId(); ret->tid = GetCurrentThreadId();
ret->render_offscreen = wined3d_resource_is_offscreen(&target->resource); ret->render_offscreen = wined3d_resource_is_offscreen(&target->resource);
...@@ -2032,9 +2038,10 @@ static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width ...@@ -2032,9 +2038,10 @@ static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width
static void context_get_rt_size(const struct wined3d_context *context, SIZE *size) static void context_get_rt_size(const struct wined3d_context *context, SIZE *size)
{ {
const struct wined3d_surface *rt = context->current_rt; const struct wined3d_texture *rt = context->current_rt.texture;
unsigned int level;
if (rt->container->swapchain && rt->container->swapchain->front_buffer == rt->container) if (rt->swapchain && rt->swapchain->front_buffer == rt)
{ {
RECT window_size; RECT window_size;
...@@ -2045,8 +2052,9 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz ...@@ -2045,8 +2052,9 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz
return; return;
} }
size->cx = rt->resource.width; level = context->current_rt.sub_resource_idx % rt->level_count;
size->cy = rt->resource.height; size->cx = wined3d_texture_get_level_width(rt, level);
size->cy = wined3d_texture_get_level_height(rt, level);
} }
/***************************************************************************** /*****************************************************************************
...@@ -2413,7 +2421,8 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, ...@@ -2413,7 +2421,8 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
const struct wined3d_rendertarget_view *depth_stencil) const struct wined3d_rendertarget_view *depth_stencil)
{ {
/* Onscreen surfaces are always in a swapchain */ /* Onscreen surfaces are always in a swapchain */
struct wined3d_swapchain *swapchain = context->current_rt->container->swapchain; struct wined3d_swapchain *swapchain = context->current_rt.texture->swapchain;
struct wined3d_surface *surface;
if (context->render_offscreen || !depth_stencil) return; if (context->render_offscreen || !depth_stencil) return;
if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->format)) return; if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->format)) return;
...@@ -2424,7 +2433,8 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, ...@@ -2424,7 +2433,8 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n");
/* The currently active context is the necessary context to access the swapchain's onscreen buffers */ /* The currently active context is the necessary context to access the swapchain's onscreen buffers */
surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB); surface = context->current_rt.texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
swapchain->render_to_fbo = TRUE; swapchain->render_to_fbo = TRUE;
swapchain_update_draw_bindings(swapchain); swapchain_update_draw_bindings(swapchain);
context_set_render_offscreen(context, TRUE); context_set_render_offscreen(context, TRUE);
...@@ -2459,7 +2469,8 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *conte ...@@ -2459,7 +2469,8 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *conte
/* Context activation is done by the caller. */ /* Context activation is done by the caller. */
void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
{ {
struct wined3d_surface *rt = context->current_rt; struct wined3d_texture *rt = context->current_rt.texture;
struct wined3d_surface *surface;
DWORD rt_mask, *cur_mask; DWORD rt_mask, *cur_mask;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
...@@ -2468,10 +2479,11 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine ...@@ -2468,10 +2479,11 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
if (context->render_offscreen) if (context->render_offscreen)
{ {
wined3d_texture_load(rt->container, context, FALSE); wined3d_texture_load(rt, context, FALSE);
context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, rt, NULL, rt->container->resource.draw_binding); surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface;
if (rt->container->resource.format->id != WINED3DFMT_NULL) context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding);
if (rt->resource.format->id != WINED3DFMT_NULL)
rt_mask = 1; rt_mask = 1;
else else
rt_mask = 0; rt_mask = 0;
...@@ -2480,12 +2492,12 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine ...@@ -2480,12 +2492,12 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
{ {
context->current_fbo = NULL; context->current_fbo = NULL;
context_bind_fbo(context, GL_FRAMEBUFFER, 0); context_bind_fbo(context, GL_FRAMEBUFFER, 0);
rt_mask = context_generate_rt_mask_from_resource(&rt->container->resource); rt_mask = context_generate_rt_mask_from_resource(&rt->resource);
} }
} }
else else
{ {
rt_mask = context_generate_rt_mask_no_fbo(context, rt->container); rt_mask = context_generate_rt_mask_no_fbo(context, rt);
} }
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
...@@ -3419,34 +3431,38 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de ...@@ -3419,34 +3431,38 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
return TRUE; return TRUE;
} }
static void context_setup_target(struct wined3d_context *context, struct wined3d_surface *target) static void context_setup_target(struct wined3d_context *context,
struct wined3d_texture *texture, unsigned int sub_resource_idx)
{ {
BOOL old_render_offscreen = context->render_offscreen, render_offscreen; BOOL old_render_offscreen = context->render_offscreen, render_offscreen;
render_offscreen = wined3d_resource_is_offscreen(&target->container->resource); render_offscreen = wined3d_resource_is_offscreen(&texture->resource);
if (context->current_rt == target && render_offscreen == old_render_offscreen) return; if (context->current_rt.texture == texture
&& context->current_rt.sub_resource_idx == sub_resource_idx
&& render_offscreen == old_render_offscreen)
return;
/* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
* the alpha blend state changes with different render target formats. */ * the alpha blend state changes with different render target formats. */
if (!context->current_rt) if (!context->current_rt.texture)
{ {
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
} }
else else
{ {
const struct wined3d_format *old = context->current_rt->container->resource.format; const struct wined3d_format *old = context->current_rt.texture->resource.format;
const struct wined3d_format *new = target->container->resource.format; const struct wined3d_format *new = texture->resource.format;
if (old->id != new->id) if (old->id != new->id)
{ {
/* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
if ((old->alpha_size && !new->alpha_size) || (!old->alpha_size && new->alpha_size) if ((old->alpha_size && !new->alpha_size) || (!old->alpha_size && new->alpha_size)
|| !(target->container->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) || !(texture->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
/* Update sRGB writing when switching between formats that do/do not support sRGB writing */ /* Update sRGB writing when switching between formats that do/do not support sRGB writing */
if ((context->current_rt->container->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE) if ((context->current_rt.texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)
!= (target->container->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)) != (texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE))
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
} }
...@@ -3458,25 +3474,32 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d ...@@ -3458,25 +3474,32 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d
* has to be called with the old rendertarget active, otherwise a * has to be called with the old rendertarget active, otherwise a
* wrong drawable is read. */ * wrong drawable is read. */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
&& old_render_offscreen && context->current_rt != target) && old_render_offscreen && (context->current_rt.texture != texture
|| context->current_rt.sub_resource_idx != sub_resource_idx))
{ {
struct wined3d_texture *texture = context->current_rt->container; unsigned int prev_sub_resource_idx = context->current_rt.sub_resource_idx;
struct wined3d_texture *prev_texture = context->current_rt.texture;
struct wined3d_surface *prev_surface;
/* Read the back buffer of the old drawable into the destination texture. */ /* Read the back buffer of the old drawable into the destination texture. */
if (texture->texture_srgb.name) if (prev_texture->texture_srgb.name)
wined3d_texture_load(texture, context, TRUE); wined3d_texture_load(prev_texture, context, TRUE);
wined3d_texture_load(texture, context, FALSE); wined3d_texture_load(prev_texture, context, FALSE);
surface_invalidate_location(context->current_rt, WINED3D_LOCATION_DRAWABLE); prev_surface = prev_texture->sub_resources[prev_sub_resource_idx].u.surface;
surface_invalidate_location(prev_surface, WINED3D_LOCATION_DRAWABLE);
} }
} }
context->current_rt = target; context->current_rt.texture = texture;
context->current_rt.sub_resource_idx = sub_resource_idx;
context_set_render_offscreen(context, render_offscreen); context_set_render_offscreen(context, render_offscreen);
} }
struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target) struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target)
{ {
struct wined3d_context *current_context = context_get_current(); struct wined3d_context *current_context = context_get_current();
struct wined3d_texture *target_texture;
unsigned int target_sub_resource_idx;
struct wined3d_context *context; struct wined3d_context *context;
TRACE("device %p, target %p.\n", device, target); TRACE("device %p, target %p.\n", device, target);
...@@ -3484,33 +3507,41 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str ...@@ -3484,33 +3507,41 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str
if (current_context && current_context->destroyed) if (current_context && current_context->destroyed)
current_context = NULL; current_context = NULL;
if (!target) if (target)
{
target_texture = target->container;
target_sub_resource_idx = surface_get_sub_resource_idx(target);
}
else
{ {
if (current_context if (current_context
&& current_context->current_rt && current_context->current_rt.texture
&& current_context->swapchain->device == device) && current_context->swapchain->device == device)
{ {
target = current_context->current_rt; target_texture = current_context->current_rt.texture;
target_sub_resource_idx = current_context->current_rt.sub_resource_idx;
} }
else else
{ {
struct wined3d_swapchain *swapchain = device->swapchains[0]; struct wined3d_swapchain *swapchain = device->swapchains[0];
if (swapchain->back_buffers) if (swapchain->back_buffers)
target = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); target_texture = swapchain->back_buffers[0];
else else
target = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); target_texture = swapchain->front_buffer;
target_sub_resource_idx = 0;
} }
} }
if (current_context && current_context->current_rt == target) if (current_context && current_context->current_rt.texture == target_texture)
{ {
context = current_context; context = current_context;
} }
else if (target->container->swapchain) else if (target_texture->swapchain)
{ {
TRACE("Rendering onscreen.\n"); TRACE("Rendering onscreen.\n");
context = swapchain_get_context(target->container->swapchain); context = swapchain_get_context(target_texture->swapchain);
} }
else else
{ {
...@@ -3526,7 +3557,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str ...@@ -3526,7 +3557,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str
context_enter(context); context_enter(context);
context_update_window(context); context_update_window(context);
context_setup_target(context, target); context_setup_target(context, target_texture, target_sub_resource_idx);
if (!context->valid) return context; if (!context->valid) return context;
if (context != current_context) if (context != current_context)
......
...@@ -58,7 +58,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win ...@@ -58,7 +58,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win
return WINED3D_EVENT_QUERY_WRONG_THREAD; return WINED3D_EVENT_QUERY_WRONG_THREAD;
} }
context = context_acquire(device, query->context->current_rt); context = context_acquire(device, context_get_rt_surface(query->context));
gl_info = context->gl_info; gl_info = context->gl_info;
if (gl_info->supported[ARB_SYNC]) if (gl_info->supported[ARB_SYNC])
...@@ -132,7 +132,7 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_ ...@@ -132,7 +132,7 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_
return WINED3D_EVENT_QUERY_WRONG_THREAD; return WINED3D_EVENT_QUERY_WRONG_THREAD;
} }
context = context_acquire(device, query->context->current_rt); context = context_acquire(device, context_get_rt_surface(query->context));
if (gl_info->supported[ARB_SYNC]) if (gl_info->supported[ARB_SYNC])
{ {
...@@ -192,7 +192,7 @@ void wined3d_event_query_issue(struct wined3d_event_query *query, const struct w ...@@ -192,7 +192,7 @@ void wined3d_event_query_issue(struct wined3d_event_query *query, const struct w
} }
else else
{ {
context = context_acquire(device, query->context->current_rt); context = context_acquire(device, context_get_rt_surface(query->context));
} }
} }
else else
...@@ -348,7 +348,7 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, ...@@ -348,7 +348,7 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
return S_OK; return S_OK;
} }
context = context_acquire(query->device, oq->context->current_rt); context = context_acquire(device, context_get_rt_surface(oq->context));
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available)); GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
...@@ -490,7 +490,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW ...@@ -490,7 +490,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
} }
else else
{ {
context = context_acquire(query->device, oq->context->current_rt); context = context_acquire(device, context_get_rt_surface(oq->context));
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
checkGLcall("glEndQuery()"); checkGLcall("glEndQuery()");
...@@ -522,7 +522,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW ...@@ -522,7 +522,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
} }
else else
{ {
context = context_acquire(query->device, oq->context->current_rt); context = context_acquire(device, context_get_rt_surface(oq->context));
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
checkGLcall("glEndQuery()"); checkGLcall("glEndQuery()");
...@@ -578,7 +578,7 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, ...@@ -578,7 +578,7 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
return S_OK; return S_OK;
} }
context = context_acquire(query->device, tq->context->current_rt); context = context_acquire(device, context_get_rt_surface(tq->context));
GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
......
...@@ -108,8 +108,8 @@ void surface_get_drawable_size(const struct wined3d_surface *surface, const stru ...@@ -108,8 +108,8 @@ void surface_get_drawable_size(const struct wined3d_surface *surface, const stru
/* The drawable size of an onscreen drawable is the surface size. /* The drawable size of an onscreen drawable is the surface size.
* (Actually: The window size, but the surface is created in window * (Actually: The window size, but the surface is created in window
* size.) */ * size.) */
*width = context->current_rt->resource.width; *width = context->current_rt.texture->resource.width;
*height = context->current_rt->resource.height; *height = context->current_rt.texture->resource.height;
} }
else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
{ {
...@@ -123,10 +123,13 @@ void surface_get_drawable_size(const struct wined3d_surface *surface, const stru ...@@ -123,10 +123,13 @@ void surface_get_drawable_size(const struct wined3d_surface *surface, const stru
} }
else else
{ {
struct wined3d_surface *rt;
/* The drawable size of an FBO target is the OpenGL texture size, /* The drawable size of an FBO target is the OpenGL texture size,
* which is the power of two size. */ * which is the power of two size. */
*width = context->current_rt->pow2Width; rt = context->current_rt.texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
*height = context->current_rt->pow2Height; *width = rt->pow2Width;
*height = rt->pow2Height;
} }
} }
...@@ -675,11 +678,11 @@ static void surface_blt_fbo(const struct wined3d_device *device, ...@@ -675,11 +678,11 @@ static void surface_blt_fbo(const struct wined3d_device *device,
else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface; else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface;
else required_rt = NULL; else required_rt = NULL;
if (required_rt && required_rt != old_ctx->current_rt) restore_rt = context_get_rt_surface(old_ctx);
{ if (restore_rt != required_rt)
restore_rt = old_ctx->current_rt;
context = context_acquire(device, required_rt); context = context_acquire(device, required_rt);
} else
restore_rt = NULL;
if (!context->valid) if (!context->valid)
{ {
...@@ -1852,11 +1855,11 @@ static void read_from_framebuffer(struct wined3d_surface *surface, ...@@ -1852,11 +1855,11 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
surface_get_memory(surface, &data, dst_location); surface_get_memory(surface, &data, dst_location);
if (surface != old_ctx->current_rt) restore_rt = context_get_rt_surface(old_ctx);
{ if (restore_rt != surface)
restore_rt = old_ctx->current_rt;
context = context_acquire(device, surface); context = context_acquire(device, surface);
} else
restore_rt = NULL;
context_apply_blit_state(context, device); context_apply_blit_state(context, device);
gl_info = context->gl_info; gl_info = context->gl_info;
...@@ -1962,11 +1965,11 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct ...@@ -1962,11 +1965,11 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct
struct wined3d_context *context = old_ctx; struct wined3d_context *context = old_ctx;
struct wined3d_surface *restore_rt = NULL; struct wined3d_surface *restore_rt = NULL;
if (old_ctx->current_rt != surface) restore_rt = context_get_rt_surface(old_ctx);
{ if (restore_rt != surface)
restore_rt = old_ctx->current_rt;
context = context_acquire(device, surface); context = context_acquire(device, surface);
} else
restore_rt = NULL;
gl_info = context->gl_info; gl_info = context->gl_info;
device_invalidate_state(device, STATE_FRAMEBUFFER); device_invalidate_state(device, STATE_FRAMEBUFFER);
...@@ -2485,12 +2488,11 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, ...@@ -2485,12 +2488,11 @@ static void surface_blt_to_drawable(const struct wined3d_device *device,
src_rect = *src_rect_in; src_rect = *src_rect_in;
dst_rect = *dst_rect_in; dst_rect = *dst_rect_in;
restore_rt = context_get_rt_surface(old_ctx);
if (old_ctx->current_rt != dst_surface) if (restore_rt != dst_surface)
{
restore_rt = old_ctx->current_rt;
context = context_acquire(device, dst_surface); context = context_acquire(device, dst_surface);
} else
restore_rt = NULL;
gl_info = context->gl_info; gl_info = context->gl_info;
......
...@@ -1282,7 +1282,11 @@ struct wined3d_context ...@@ -1282,7 +1282,11 @@ struct wined3d_context
DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */
struct wined3d_swapchain *swapchain; struct wined3d_swapchain *swapchain;
struct wined3d_surface *current_rt; struct
{
struct wined3d_texture *texture;
unsigned int sub_resource_idx;
} current_rt;
DWORD tid; /* Thread ID which owns this context at the moment */ DWORD tid; /* Thread ID which owns this context at the moment */
/* Stores some information about the context state for optimization */ /* Stores some information about the context state for optimization */
...@@ -3473,6 +3477,15 @@ static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info ...@@ -3473,6 +3477,15 @@ static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info
&& !is_scaling_fixup(format->color_fixup); && !is_scaling_fixup(format->color_fixup);
} }
static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context)
{
struct wined3d_texture *texture = context->current_rt.texture;
if (!texture)
return NULL;
return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
}
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */ /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL" #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
......
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