[PATCH 1/4] wined3d: Verify we have at least one framebuffer attachment before doing clears or draws.
Henri Verbeet
hverbeet at codeweavers.com
Wed Jan 26 12:45:02 CST 2011
---
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,
--
1.7.3.4
More information about the wine-patches
mailing list