From ed75f5ca7aae3de6afeca5dc97be9f54a140104d Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 4 May 2010 20:39:52 +0200 Subject: [PATCH] wined3d: Setup the FBO for the correct target in context_apply_clear_state(). --- dlls/wined3d/context.c | 61 +++++++++++++++++++++++++++------- dlls/wined3d/device.c | 24 +------------ dlls/wined3d/wined3d_private.h | 4 ++- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e205b7afa1b..9815ce34bd1 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -455,7 +455,7 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ context->rebind_fbo = FALSE; } - if (context->render_offscreen) + if (render_targets) { context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil); context_apply_fbo_entry(context, target, context->current_fbo); @@ -469,6 +469,21 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ context_check_fbo_status(context, target); } +/* GL locking is done by the caller */ +static void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) +{ + if (surface_is_offscreen(render_target)) + { + context->blit_targets[0] = render_target; + context_apply_fbo_state(context, target, context->blit_targets, depth_stencil); + } + else + { + context_apply_fbo_state(context, target, NULL, NULL); + } +} + /* Context activation is done by the caller. */ void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) { @@ -1357,6 +1372,10 @@ struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3 sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF); } + ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + gl_info->limits.buffers * sizeof(*ret->blit_targets)); + if (!ret->blit_targets) goto out; + ret->free_occlusion_query_size = 4; ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0, ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries)); @@ -1490,6 +1509,7 @@ struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3 out: HeapFree(GetProcessHeap(), 0, ret->free_event_queries); HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); + HeapFree(GetProcessHeap(), 0, ret->blit_targets); HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty); HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty); HeapFree(GetProcessHeap(), 0, ret); @@ -1524,6 +1544,7 @@ void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) destroy = FALSE; } + HeapFree(GetProcessHeap(), 0, context->blit_targets); HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty); HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty); device_context_remove(This, context); @@ -2010,23 +2031,30 @@ void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImp } /* Context activation is done by the caller. */ -void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) +void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) { const struct StateEntry *state_table = device->StateTable; + GLenum buffer; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { if (!context->render_offscreen) context_validate_onscreen_formats(device, context); ENTER_GL(); - context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil); + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, render_target, depth_stencil); LEAVE_GL(); } - if (context->draw_buffer_dirty) - { - context_apply_draw_buffer(context, FALSE); - context->draw_buffer_dirty = FALSE; - } + if (!surface_is_offscreen(render_target)) + buffer = surface_get_gl_buffer(render_target); + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + buffer = GL_COLOR_ATTACHMENT0; + else + buffer = device->offscreenBuffer; + + ENTER_GL(); + context_set_draw_buffer(context, buffer); + LEAVE_GL(); if (context->last_was_blit) { @@ -2056,10 +2084,19 @@ void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImp if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (!context->render_offscreen) context_validate_onscreen_formats(device, context); - ENTER_GL(); - context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil); - LEAVE_GL(); + if (!context->render_offscreen) + { + context_validate_onscreen_formats(device, context); + ENTER_GL(); + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL); + LEAVE_GL(); + } + else + { + ENTER_GL(); + context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil); + LEAVE_GL(); + } } if (context->draw_buffer_dirty) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 585edd5d5b8..3472d04714f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4455,29 +4455,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac return WINED3D_OK; } - context_apply_clear_state(context, This); - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - if (!surface_is_offscreen(target)) - { - TRACE("Surface %p is onscreen\n", target); - - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - context_set_draw_buffer(context, surface_get_gl_buffer(target)); - LEAVE_GL(); - } - else - { - TRACE("Surface %p is offscreen\n", target); - - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, target); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, depth_stencil, TRUE); - LEAVE_GL(); - } - } + context_apply_clear_state(context, This, target, depth_stencil); target->get_drawable_size(context, &drawable_width, &drawable_height); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fabf22a0b94..cad88b9e9ea 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1092,6 +1092,7 @@ struct wined3d_context GLuint fbo_read_binding; GLuint fbo_draw_binding; BOOL rebind_fbo; + IWineD3DSurfaceImpl **blit_targets; /* Queries */ GLuint *free_occlusion_queries; @@ -1192,7 +1193,8 @@ void context_alloc_event_query(struct wined3d_context *context, void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; -void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; void context_attach_depth_stencil_fbo(struct wined3d_context *context, GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN;