Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/context.c | 36 ++++++++++++++++++------------------ dlls/wined3d/device.c | 20 ++++++++------------ dlls/wined3d/wined3d_private.h | 20 ++++++-------------- 3 files changed, 32 insertions(+), 44 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 53d44d994e9..2509d90fd4d 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1647,18 +1647,14 @@ void context_invalidate_compute_state(struct wined3d_context *context, DWORD sta context->dirty_compute_states[index] |= (1u << shift); }
-void context_invalidate_state(struct wined3d_context *context, DWORD state) +void context_invalidate_state(struct wined3d_context *context, unsigned int state_id) { - DWORD rep = context->state_table[state].representative; - DWORD idx; - BYTE shift; - - if (isStateDirty(context, rep)) return; + unsigned int representative = context->state_table[state_id].representative; + unsigned int index, shift;
- context->dirtyArray[context->numDirtyEntries++] = rep; - idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] |= (1u << shift); + index = representative / (sizeof(*context->dirty_graphics_states) * CHAR_BIT); + shift = representative & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1); + context->dirty_graphics_states[index] |= (1u << shift); }
/* This function takes care of wined3d pixel format selection. */ @@ -3911,7 +3907,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_context_gl *context_gl = wined3d_context_gl(context); const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_fb_state *fb = state->fb; - unsigned int i; + unsigned int i, base; WORD map;
if (!have_framebuffer_attachment(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil)) @@ -3963,13 +3959,18 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, wined3d_buffer_load_sysmem(state->index_buffer, context); }
- for (i = 0; i < context->numDirtyEntries; ++i) + for (i = 0, base = 0; i < ARRAY_SIZE(context->dirty_graphics_states); ++i) { - DWORD rep = context->dirtyArray[i]; - DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] &= ~(1u << shift); - state_table[rep].apply(context, state, rep); + uint32_t dirty_mask = context->dirty_graphics_states[i]; + + while (dirty_mask) + { + unsigned int state_id = base + wined3d_bit_scan(&dirty_mask); + + state_table[state_id].apply(context, state, state_id); + context->dirty_graphics_states[i] &= ~(1u << (state_id - base)); + } + base += sizeof(dirty_mask) * CHAR_BIT; }
if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) @@ -4005,7 +4006,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) wined3d_context_gl_check_fbo_status(context_gl, GL_FRAMEBUFFER);
- context->numDirtyEntries = 0; /* This makes the whole list clean */ context->last_was_blit = FALSE; context->last_was_ffp_blit = FALSE;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a28dd6c3e1f..c37f386f99a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5866,30 +5866,26 @@ err: return hr; }
-void device_invalidate_state(const struct wined3d_device *device, DWORD state) +void device_invalidate_state(const struct wined3d_device *device, unsigned int state_id) { - DWORD rep = device->state_table[state].representative; + unsigned int representative, i, idx, shift; struct wined3d_context *context; - unsigned int i, idx, shift;
wined3d_from_cs(device->cs);
- if (STATE_IS_COMPUTE(state)) + if (STATE_IS_COMPUTE(state_id)) { for (i = 0; i < device->context_count; ++i) - context_invalidate_compute_state(device->contexts[i], state); + context_invalidate_compute_state(device->contexts[i], state_id); return; }
+ representative = device->state_table[state_id].representative; + idx = representative / (sizeof(*context->dirty_graphics_states) * CHAR_BIT); + shift = representative & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1); for (i = 0; i < device->context_count; ++i) { - context = device->contexts[i]; - if (isStateDirty(context, rep)) continue; - - context->dirtyArray[context->numDirtyEntries++] = rep; - idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] |= (1u << shift); + device->contexts[i]->dirty_graphics_states[idx] |= (1u << shift); } }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e6f93405177..1048d19c65b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1891,16 +1891,8 @@ struct wined3d_context { const struct wined3d_d3d_info *d3d_info; const struct wined3d_state_entry *state_table; - /* State dirtification - * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices - * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed, - * but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states - * only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states. - */ - DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ - DWORD numDirtyEntries; - DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ - unsigned int dirty_compute_states[STATE_COMPUTE_COUNT / (sizeof(unsigned int) * CHAR_BIT) + 1]; + uint32_t dirty_graphics_states[STATE_HIGHEST / (sizeof(uint32_t) * CHAR_BIT) + 1]; + uint32_t dirty_compute_states[STATE_COMPUTE_COUNT / (sizeof(uint32_t) * CHAR_BIT) + 1];
struct wined3d_device *device; struct wined3d_swapchain *swapchain; @@ -3291,11 +3283,11 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device return CONTAINING_RECORD(device, struct wined3d_device_gl, d); }
-static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) +static inline BOOL isStateDirty(const struct wined3d_context *context, unsigned int state_id) { - DWORD idx = state / (sizeof(*context->isStateDirty) * CHAR_BIT); - BYTE shift = state & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - return context->isStateDirty[idx] & (1u << shift); + unsigned int idx = state_id / (sizeof(*context->dirty_graphics_states) * CHAR_BIT); + unsigned int shift = state_id & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1); + return context->dirty_graphics_states[idx] & (1u << shift); }
static inline float wined3d_alpha_ref(const struct wined3d_state *state)