Signed-off-by: Zebediah Figura z.figura12@gmail.com --- This is a proposed approach at implementing deferred contexts. The idea is to create a wined3d_cs object per ID3D11DeviceContext. Deferred contexts will have their own wined3d_cs_ops structure, and some operations (i.e. maps and queries) will be partially split to wined3d_cs_ops methods.
The point of this patch is to avoid allocating space for unused wined3d_state objects. Presumably other fields could also be moved to the wined3d_cs_state structure as well.
dlls/wined3d/cs.c | 115 +++++++++++++++++---------------- dlls/wined3d/texture.c | 2 +- dlls/wined3d/wined3d_private.h | 8 ++- 3 files changed, 66 insertions(+), 59 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 4ee3d97b7fc..9e3ea4c8086 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -532,7 +532,7 @@ static void wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) { struct wined3d_texture *logo_texture, *cursor_texture, *back_buffer; - struct wined3d_rendertarget_view *dsv = cs->state.fb.depth_stencil; + struct wined3d_rendertarget_view *dsv = cs->cs_state->state.fb.depth_stencil; const struct wined3d_cs_present *op = data; const struct wined3d_swapchain_desc *desc; struct wined3d_swapchain *swapchain; @@ -690,7 +690,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * op->opcode = WINED3D_CS_OP_CLEAR; op->flags = flags & (WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); op->rt_count = rt_count; - op->fb = &cs->state.fb; + op->fb = &cs->cs_state->state.fb; SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height); if (state->rasterizer_state && state->rasterizer_state->desc.scissor) IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rects[0]); @@ -861,7 +861,7 @@ static void release_unordered_access_resources(const struct wined3d_shader *shad static void wined3d_cs_exec_dispatch(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_dispatch *op = data; - struct wined3d_state *state = &cs->state; + struct wined3d_state *state = &cs->cs_state->state;
if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE]) WARN("No compute shader bound, skipping dispatch.\n"); @@ -925,7 +925,7 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) const struct wined3d_shader *geometry_shader; struct wined3d_device *device = cs->device; int base_vertex_idx, load_base_vertex_idx; - struct wined3d_state *state = &cs->state; + struct wined3d_state *state = &cs->cs_state->state; const struct wined3d_cs_draw *op = data; unsigned int i;
@@ -1111,8 +1111,8 @@ static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *d { const struct wined3d_cs_set_predication *op = data;
- cs->state.predicate = op->predicate; - cs->state.predicate_value = op->value; + cs->cs_state->state.predicate = op->predicate; + cs->cs_state->state.predicate_value = op->value; }
void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) @@ -1132,10 +1132,10 @@ static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *dat const struct wined3d_cs_set_viewports *op = data;
if (op->viewport_count) - memcpy(cs->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports)); + memcpy(cs->cs_state->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports)); else - memset(cs->state.viewports, 0, sizeof(*cs->state.viewports)); - cs->state.viewport_count = op->viewport_count; + memset(cs->cs_state->state.viewports, 0, sizeof(*cs->cs_state->state.viewports)); + cs->cs_state->state.viewport_count = op->viewport_count; device_invalidate_state(cs->device, STATE_VIEWPORT); }
@@ -1158,10 +1158,10 @@ static void wined3d_cs_exec_set_scissor_rects(struct wined3d_cs *cs, const void const struct wined3d_cs_set_scissor_rects *op = data;
if (op->rect_count) - memcpy(cs->state.scissor_rects, op->rects, op->rect_count * sizeof(*op->rects)); + memcpy(cs->cs_state->state.scissor_rects, op->rects, op->rect_count * sizeof(*op->rects)); else - SetRectEmpty(cs->state.scissor_rects); - cs->state.scissor_rect_count = op->rect_count; + SetRectEmpty(cs->cs_state->state.scissor_rects); + cs->cs_state->state.scissor_rect_count = op->rect_count; device_invalidate_state(cs->device, STATE_SCISSORRECT); }
@@ -1184,8 +1184,8 @@ static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const v BOOL prev_alpha_swizzle, curr_alpha_swizzle; struct wined3d_rendertarget_view *prev;
- prev = cs->state.fb.render_targets[op->view_idx]; - cs->state.fb.render_targets[op->view_idx] = op->view; + prev = cs->cs_state->state.fb.render_targets[op->view_idx]; + cs->cs_state->state.fb.render_targets[op->view_idx] = op->view; device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; @@ -1213,7 +1213,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const struct wined3d_device *device = cs->device; struct wined3d_rendertarget_view *prev;
- if ((prev = cs->state.fb.depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER) + if ((prev = cs->cs_state->state.fb.depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER) { struct wined3d_texture *prev_texture = texture_from_resource(prev->resource);
@@ -1223,7 +1223,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED); }
- cs->state.fb.depth_stencil = op->view; + cs->cs_state->state.fb.depth_stencil = op->view;
if (!prev != !op->view) { @@ -1258,7 +1258,7 @@ static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const { const struct wined3d_cs_set_vertex_declaration *op = data;
- cs->state.vertex_declaration = op->declaration; + cs->cs_state->state.vertex_declaration = op->declaration; device_invalidate_state(cs->device, STATE_VDECL); }
@@ -1279,7 +1279,7 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void struct wined3d_stream_state *stream; struct wined3d_buffer *prev;
- stream = &cs->state.streams[op->stream_idx]; + stream = &cs->cs_state->state.streams[op->stream_idx]; prev = stream->buffer; stream->buffer = op->buffer; stream->offset = op->offset; @@ -1313,7 +1313,7 @@ static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const const struct wined3d_cs_set_stream_source_freq *op = data; struct wined3d_stream_state *stream;
- stream = &cs->state.streams[op->stream_idx]; + stream = &cs->cs_state->state.streams[op->stream_idx]; stream->frequency = op->frequency; stream->flags = op->flags;
@@ -1339,7 +1339,7 @@ static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void struct wined3d_stream_output *stream; struct wined3d_buffer *prev;
- stream = &cs->state.stream_output[op->stream_idx]; + stream = &cs->cs_state->state.stream_output[op->stream_idx]; prev = stream->buffer; stream->buffer = op->buffer; stream->offset = op->offset; @@ -1371,10 +1371,10 @@ static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void * const struct wined3d_cs_set_index_buffer *op = data; struct wined3d_buffer *prev;
- prev = cs->state.index_buffer; - cs->state.index_buffer = op->buffer; - cs->state.index_format = op->format_id; - cs->state.index_offset = op->offset; + prev = cs->cs_state->state.index_buffer; + cs->cs_state->state.index_buffer = op->buffer; + cs->cs_state->state.index_format = op->format_id; + cs->cs_state->state.index_offset = op->offset;
if (op->buffer) InterlockedIncrement(&op->buffer->resource.bind_count); @@ -1403,8 +1403,8 @@ static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const voi const struct wined3d_cs_set_constant_buffer *op = data; struct wined3d_buffer *prev;
- prev = cs->state.cb[op->type][op->cb_idx]; - cs->state.cb[op->type][op->cb_idx] = op->buffer; + prev = cs->cs_state->state.cb[op->type][op->cb_idx]; + cs->cs_state->state.cb[op->type][op->cb_idx] = op->buffer;
if (op->buffer) InterlockedIncrement(&op->buffer->resource.bind_count); @@ -1435,8 +1435,8 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) struct wined3d_texture *prev; BOOL old_use_color_key = FALSE, new_use_color_key = FALSE;
- prev = cs->state.textures[op->stage]; - cs->state.textures[op->stage] = op->texture; + prev = cs->cs_state->state.textures[op->stage]; + cs->cs_state->state.textures[op->stage] = op->texture;
if (op->texture) { @@ -1478,7 +1478,7 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) TRACE("Searching for other stages the texture is bound to.\n"); for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { - if (cs->state.textures[i] == prev) + if (cs->cs_state->state.textures[i] == prev) { TRACE("Texture is also bound to stage %u.\n", i); prev->sampler = i; @@ -1523,8 +1523,8 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons const struct wined3d_cs_set_shader_resource_view *op = data; struct wined3d_shader_resource_view *prev;
- prev = cs->state.shader_resource_view[op->type][op->view_idx]; - cs->state.shader_resource_view[op->type][op->view_idx] = op->view; + prev = cs->cs_state->state.shader_resource_view[op->type][op->view_idx]; + cs->cs_state->state.shader_resource_view[op->type][op->view_idx] = op->view;
if (op->view) InterlockedIncrement(&op->view->resource->bind_count); @@ -1556,8 +1556,8 @@ static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, con const struct wined3d_cs_set_unordered_access_view *op = data; struct wined3d_unordered_access_view *prev;
- prev = cs->state.unordered_access_view[op->pipeline][op->view_idx]; - cs->state.unordered_access_view[op->pipeline][op->view_idx] = op->view; + prev = cs->cs_state->state.unordered_access_view[op->pipeline][op->view_idx]; + cs->cs_state->state.unordered_access_view[op->pipeline][op->view_idx] = op->view;
if (op->view) InterlockedIncrement(&op->view->resource->bind_count); @@ -1589,7 +1589,7 @@ static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_sampler *op = data;
- cs->state.sampler[op->type][op->sampler_idx] = op->sampler; + cs->cs_state->state.sampler[op->type][op->sampler_idx] = op->sampler; if (op->type != WINED3D_SHADER_TYPE_COMPUTE) device_invalidate_state(cs->device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); else @@ -1614,7 +1614,7 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_shader *op = data;
- cs->state.shader[op->type] = op->shader; + cs->cs_state->state.shader[op->type] = op->shader; device_invalidate_state(cs->device, STATE_SHADER(op->type)); if (op->type != WINED3D_SHADER_TYPE_COMPUTE) device_invalidate_state(cs->device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); @@ -1637,7 +1637,7 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type static void wined3d_cs_exec_set_blend_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_blend_state *op = data; - struct wined3d_state *state = &cs->state; + struct wined3d_state *state = &cs->cs_state->state;
if (state->blend_state != op->state) { @@ -1667,7 +1667,7 @@ void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend static void wined3d_cs_exec_set_depth_stencil_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_depth_stencil_state *op = data; - struct wined3d_state *state = &cs->state; + struct wined3d_state *state = &cs->cs_state->state;
if (state->depth_stencil_state != op->state) { @@ -1695,7 +1695,7 @@ static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const vo { const struct wined3d_cs_set_rasterizer_state *op = data;
- cs->state.rasterizer_state = op->state; + cs->cs_state->state.rasterizer_state = op->state; device_invalidate_state(cs->device, STATE_RASTERIZER); }
@@ -1715,7 +1715,7 @@ static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void * { const struct wined3d_cs_set_render_state *op = data;
- cs->state.render_states[op->state] = op->value; + cs->cs_state->state.render_states[op->state] = op->value; device_invalidate_state(cs->device, STATE_RENDER(op->state)); }
@@ -1735,7 +1735,7 @@ static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void { const struct wined3d_cs_set_texture_state *op = data;
- cs->state.texture_states[op->stage][op->state] = op->value; + cs->cs_state->state.texture_states[op->stage][op->state] = op->value; device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); }
@@ -1757,7 +1757,7 @@ static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void { const struct wined3d_cs_set_sampler_state *op = data;
- cs->state.sampler_states[op->sampler_idx][op->state] = op->value; + cs->cs_state->state.sampler_states[op->sampler_idx][op->state] = op->value; device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); }
@@ -1779,7 +1779,7 @@ static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *dat { const struct wined3d_cs_set_transform *op = data;
- cs->state.transforms[op->state] = op->matrix; + cs->cs_state->state.transforms[op->state] = op->matrix; if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); } @@ -1801,7 +1801,7 @@ static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *da { const struct wined3d_cs_set_clip_plane *op = data;
- cs->state.clip_planes[op->plane_idx] = op->plane; + cs->cs_state->state.clip_planes[op->plane_idx] = op->plane; device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); }
@@ -1837,7 +1837,7 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat break;
case WINED3D_CKEY_SRC_BLT: - if (texture == cs->state.textures[0]) + if (texture == cs->cs_state->state.textures[0]) { device_invalidate_state(cs->device, STATE_COLOR_KEY); if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) @@ -1867,7 +1867,7 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat break;
case WINED3D_CKEY_SRC_BLT: - if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) + if (texture == cs->cs_state->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT; @@ -1904,7 +1904,7 @@ static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data { const struct wined3d_cs_set_material *op = data;
- cs->state.material = op->material; + cs->cs_state->state.material = op->material; device_invalidate_state(cs->device, STATE_MATERIAL); }
@@ -1927,7 +1927,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data)
light_idx = op->light.OriginalIndex;
- if (!(light_info = wined3d_light_state_get_light(&cs->state.light_state, light_idx))) + if (!(light_info = wined3d_light_state_get_light(&cs->cs_state->state.light_state, light_idx))) { TRACE("Adding new light.\n"); if (!(light_info = heap_alloc_zero(sizeof(*light_info)))) @@ -1937,7 +1937,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) }
hash_idx = LIGHTMAP_HASHFUNC(light_idx); - list_add_head(&cs->state.light_state.light_map[hash_idx], &light_info->entry); + list_add_head(&cs->cs_state->state.light_state.light_map[hash_idx], &light_info->entry); light_info->glIndex = -1; light_info->OriginalIndex = light_idx; } @@ -1974,14 +1974,14 @@ static void wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void * struct wined3d_light_info *light_info; int prev_idx;
- if (!(light_info = wined3d_light_state_get_light(&cs->state.light_state, op->idx))) + if (!(light_info = wined3d_light_state_get_light(&cs->cs_state->state.light_state, op->idx))) { ERR("Light doesn't exist.\n"); return; }
prev_idx = light_info->glIndex; - wined3d_light_state_enable_light(&cs->state.light_state, &device->adapter->d3d_info, light_info, op->enable); + wined3d_light_state_enable_light(&cs->cs_state->state.light_state, &device->adapter->d3d_info, light_info, op->enable); if (light_info->glIndex != prev_idx) { device_invalidate_state(device, STATE_LIGHT_TYPE); @@ -2037,7 +2037,7 @@ static void wined3d_cs_st_push_constants(struct wined3d_cs *cs, enum wined3d_pus device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count);
offset = wined3d_cs_push_constant_info[p].offset + start_idx * wined3d_cs_push_constant_info[p].size; - memcpy((BYTE *)&cs->state + offset, constants, count * wined3d_cs_push_constant_info[p].size); + memcpy((BYTE *)&cs->cs_state->state + offset, constants, count * wined3d_cs_push_constant_info[p].size); for (i = 0, context_count = device->context_count; i < context_count; ++i) { device->contexts[i]->constant_update_mask |= wined3d_cs_push_constant_info[p].mask; @@ -2073,9 +2073,9 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) { struct wined3d_adapter *adapter = cs->device->adapter;
- state_cleanup(&cs->state); - memset(&cs->state, 0, sizeof(cs->state)); - state_init(&cs->state, &adapter->d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + state_cleanup(&cs->cs_state->state); + memset(&cs->cs_state->state, 0, sizeof(cs->cs_state->state)); + state_init(&cs->cs_state->state, &adapter->d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); }
void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) @@ -2973,7 +2973,8 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) cs->device = device; cs->serialize_commands = TRACE_ON(d3d_sync) || wined3d_settings.cs_multithreaded & WINED3D_CSMT_SERIALIZE;
- state_init(&cs->state, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + cs->cs_state = &device->cs_state; + state_init(&cs->cs_state->state, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
cs->data_size = WINED3D_INITIAL_CS_SIZE; if (!(cs->data = heap_alloc(cs->data_size))) @@ -3013,7 +3014,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) return cs;
fail: - state_cleanup(&cs->state); + state_cleanup(&cs->cs_state->state); heap_free(cs); return NULL; } @@ -3028,7 +3029,7 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) ERR("Closing event failed.\n"); }
- state_cleanup(&cs->state); + state_cleanup(&cs->cs_state->state); heap_free(cs->data); heap_free(cs); } diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index d6408fb1c7a..17063a09009 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5314,8 +5314,8 @@ static void ffp_blitter_clear_rendertargets(struct wined3d_device *device, unsig uint32_t flags, const struct wined3d_color *colour, float depth, unsigned int stencil) { struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL; + const struct wined3d_state *state = &device->cs->cs_state->state; struct wined3d_rendertarget_view *dsv = fb->depth_stencil; - const struct wined3d_state *state = &device->cs->state; struct wined3d_texture *depth_stencil = NULL; unsigned int drawable_width, drawable_height; const struct wined3d_gl_info *gl_info; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 56d3ef8fea2..18717b5207f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3745,6 +3745,11 @@ struct wined3d_so_desc_entry struct wined3d_stream_output_element elements[1]; };
+struct wined3d_cs_state +{ + struct wined3d_state state; +}; + struct wined3d_device { LONG ref; @@ -3812,6 +3817,7 @@ struct wined3d_device struct wined3d_sampler *null_sampler;
/* Command stream */ + struct wined3d_cs_state cs_state; struct wined3d_cs *cs;
/* Context management */ @@ -4684,7 +4690,7 @@ struct wined3d_cs { const struct wined3d_cs_ops *ops; struct wined3d_device *device; - struct wined3d_state state; + struct wined3d_cs_state *cs_state; HMODULE wined3d_module; HANDLE thread; DWORD thread_id;