wined3d: Verify we have at least one framebuffer attachment before doing clears or draws.

This commit is contained in:
Henri Verbeet 2011-01-26 19:45:02 +01:00 committed by Alexandre Julliard
parent bea2be5cce
commit 2469597e2a
4 changed files with 44 additions and 6 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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)
{

View File

@ -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,