diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 5ecd748c4e7..d9bb5d81d41 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 71c63b23c82..92bc151f383 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 a3b0053ceea..e476d646734 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 96b845fbb84..2ec621adb54 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,