Module: wine Branch: master Commit: 2469597e2a9b3ea2072fa5964a44d255c77e47e4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2469597e2a9b3ea2072fa5964a...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Wed Jan 26 19:45:02 2011 +0100
wined3d: Verify we have at least one framebuffer attachment before doing clears or draws.
---
dlls/wined3d/context.c | 32 ++++++++++++++++++++++++++++++-- dlls/wined3d/device.c | 7 ++++++- dlls/wined3d/drawprim.c | 7 ++++++- dlls/wined3d/wined3d_private.h | 4 ++-- 4 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 5ecd748..d9bb5d8 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -2053,13 +2053,33 @@ void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImp SetupForBlit(device, context); }
+static BOOL context_validate_rt_config(UINT rt_count, + IWineD3DSurfaceImpl **rts, IWineD3DSurfaceImpl *ds) +{ + unsigned int i; + + if (ds) return TRUE; + + for (i = 0; i < rt_count; ++i) + { + if (rts[i]) return TRUE; + } + + WARN("Invalid render target config, need at least one attachment.\n"); + return FALSE; +} + /* Context activation is done by the caller. */ -void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, +BOOL context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts, IWineD3DSurfaceImpl *depth_stencil) { const struct StateEntry *state_table = device->StateTable; UINT i;
+ if (!context_validate_rt_config(rt_count, rts, depth_stencil)) + return FALSE; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { context_validate_onscreen_formats(device, context, depth_stencil); @@ -2108,14 +2128,20 @@ void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceIm Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); + + return TRUE; }
/* Context activation is done by the caller. */ -void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) +BOOL context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) { const struct StateEntry *state_table = device->StateTable; unsigned int i;
+ if (!context_validate_rt_config(context->gl_info->limits.buffers, + device->render_targets, device->depth_stencil)) + return FALSE; + /* Preload resources before FBO setup. Texture preload in particular may * result in changes to the current FBO, due to using e.g. FBO blits for * updating a resource location. */ @@ -2166,6 +2192,8 @@ void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImp LEAVE_GL(); context->numDirtyEntries = 0; /* This makes the whole list clean */ context->last_was_blit = FALSE; + + return TRUE; }
static void context_setup_target(IWineD3DDeviceImpl *device, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 71c63b2..92bc151 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -686,7 +686,12 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I return WINED3D_OK; }
- context_apply_clear_state(context, device, rt_count, rts, depth_stencil); + if (!context_apply_clear_state(context, device, rt_count, rts, depth_stencil)) + { + context_release(context); + WARN("Failed to apply clear state, skipping clear.\n"); + return WINED3D_OK; + }
target->get_drawable_size(context, &drawable_width, &drawable_height);
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index a3b0053..e476d64 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -591,7 +591,12 @@ void drawPrimitive(IWineD3DDeviceImpl *device, UINT index_count, UINT StartIdx, return; }
- context_apply_draw_state(context, device); + if (!context_apply_draw_state(context, device)) + { + context_release(context); + WARN("Unable to apply draw state, skipping draw.\n"); + return; + }
if (device->depth_stencil) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 96b845f..2ec621a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1212,9 +1212,9 @@ 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, +BOOL context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; -void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +BOOL context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil, DWORD location) DECLSPEC_HIDDEN; void context_attach_depth_stencil_fbo(struct wined3d_context *context,