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;
In order to avoid accessing the cs_state field from emit methods.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- An alternative approach could be to access device->cs_state.state.
dlls/wined3d/cs.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 9e3ea4c8086..e0d7169cc84 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -106,7 +106,7 @@ struct wined3d_cs_clear enum wined3d_cs_op opcode; DWORD flags; unsigned int rt_count; - struct wined3d_fb_state *fb; + struct wined3d_fb_state fb; RECT draw_rect; struct wined3d_color color; float depth; @@ -659,19 +659,19 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) unsigned int i;
device = cs->device; - device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, op->fb, + device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, &op->fb, op->rect_count, op->rects, &op->draw_rect, op->flags, &op->color, op->depth, op->stencil);
if (op->flags & WINED3DCLEAR_TARGET) { for (i = 0; i < op->rt_count; ++i) { - if (op->fb->render_targets[i]) - wined3d_resource_release(op->fb->render_targets[i]->resource); + if (op->fb.render_targets[i]) + wined3d_resource_release(op->fb.render_targets[i]->resource); } } if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - wined3d_resource_release(op->fb->depth_stencil->resource); + wined3d_resource_release(op->fb.depth_stencil->resource); }
void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, @@ -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->cs_state->state.fb; + op->fb = 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]); @@ -722,22 +722,21 @@ void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined
size = FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(struct wined3d_fb_state); op = wined3d_cs_require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT); - op->fb = (void *)&op->rects[1];
op->opcode = WINED3D_CS_OP_CLEAR; op->flags = flags & (WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); if (flags & WINED3DCLEAR_TARGET) { op->rt_count = 1; - op->fb->render_targets[0] = view; - op->fb->depth_stencil = NULL; + op->fb.render_targets[0] = view; + op->fb.depth_stencil = NULL; op->color = *color; } else { op->rt_count = 0; - op->fb->render_targets[0] = NULL; - op->fb->depth_stencil = view; + op->fb.render_targets[0] = NULL; + op->fb.depth_stencil = view; op->depth = depth; op->stencil = stencil; }
Deferred contexts have their own device states.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 21 +++- dlls/wined3d/device.c | 213 +++++++++++++++------------------ dlls/wined3d/texture.c | 2 +- dlls/wined3d/wined3d_private.h | 4 +- 4 files changed, 116 insertions(+), 124 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index e0d7169cc84..4ae9f1f8c09 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -677,7 +677,7 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - const struct wined3d_state *state = cs->device->state; + const struct wined3d_state *state = cs->state; const struct wined3d_viewport *vp = &state->viewports[0]; struct wined3d_rendertarget_view *view; struct wined3d_cs_clear *op; @@ -885,7 +885,7 @@ static void acquire_compute_pipeline_resources(const struct wined3d_state *state void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) { - const struct wined3d_state *state = cs->device->state; + const struct wined3d_state *state = cs->state; struct wined3d_cs_dispatch *op;
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); @@ -903,7 +903,7 @@ void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, struct wined3d_buffer *buffer, unsigned int offset) { - const struct wined3d_state *state = cs->device->state; + const struct wined3d_state *state = cs->state; struct wined3d_cs_dispatch *op;
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); @@ -1044,7 +1044,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, enum wined3d_primitive_type pri unsigned int index_count, unsigned int start_instance, unsigned int instance_count, bool indexed) { const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; - const struct wined3d_state *state = cs->device->state; + const struct wined3d_state *state = cs->state; struct wined3d_cs_draw *op;
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); @@ -1068,7 +1068,7 @@ void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, enum wined3d_primitive unsigned int patch_vertex_count, struct wined3d_buffer *buffer, unsigned int offset, bool indexed) { const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; - const struct wined3d_state *state = cs->device->state; + const struct wined3d_state *state = cs->state; struct wined3d_cs_draw *op;
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); @@ -2964,10 +2964,18 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_cs *cs; + HRESULT hr;
if (!(cs = heap_alloc_zero(sizeof(*cs)))) return NULL;
+ if (FAILED(hr = wined3d_state_create(device, &cs->state))) + { + ERR("Failed to create device state, hr %#x.\n", hr); + heap_free(cs); + return NULL; + } + cs->ops = &wined3d_cs_st_ops; cs->device = device; cs->serialize_commands = TRACE_ON(d3d_sync) || wined3d_settings.cs_multithreaded & WINED3D_CSMT_SERIALIZE; @@ -3014,6 +3022,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
fail: state_cleanup(&cs->cs_state->state); + state_cleanup(cs->state); heap_free(cs); return NULL; } @@ -3028,6 +3037,8 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) ERR("Closing event failed.\n"); }
+ wined3d_state_destroy(cs->state); + cs->state = NULL; state_cleanup(&cs->cs_state->state); heap_free(cs->data); heap_free(cs); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index aaf91a03947..7b9fd830a37 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -251,8 +251,6 @@ void wined3d_device_cleanup(struct wined3d_device *device) wine_rb_destroy(&device->depth_stencil_states, device_leftover_depth_stencil_state, NULL); wine_rb_destroy(&device->so_descs, device_free_so_desc, NULL);
- wined3d_state_destroy(device->state); - device->state = NULL; wined3d_decref(device->wined3d); device->wined3d = NULL; } @@ -1085,7 +1083,7 @@ HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, str { static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; const struct wined3d_swapchain_desc *swapchain_desc; - struct wined3d_fb_state *fb = &device->state->fb; + struct wined3d_fb_state *fb = &device->cs->state->fb; DWORD clear_flags = 0; unsigned int i; HRESULT hr; @@ -1192,7 +1190,7 @@ static void device_free_depth_stencil_state(struct wine_rb_entry *entry, void *c
void wined3d_device_uninit_3d(struct wined3d_device *device) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_resource *resource, *cursor; struct wined3d_rendertarget_view *view; struct wined3d_texture *texture; @@ -1302,7 +1300,7 @@ void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT return; }
- stream = &device->state->stream_output[idx]; + stream = &device->cs->state->stream_output[idx]; prev_buffer = stream->buffer;
if (buffer) @@ -1326,8 +1324,8 @@ struct wined3d_buffer * CDECL wined3d_device_get_stream_output(struct wined3d_de }
if (offset) - *offset = device->state->stream_output[idx].offset; - return device->state->stream_output[idx].buffer; + *offset = device->cs->state->stream_output[idx].offset; + return device->cs->state->stream_output[idx].buffer; }
HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UINT stream_idx, @@ -1350,7 +1348,7 @@ HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UI return WINED3DERR_INVALIDCALL; }
- stream = &device->state->streams[stream_idx]; + stream = &device->cs->state->streams[stream_idx]; prev_buffer = stream->buffer;
if (prev_buffer == buffer @@ -1387,7 +1385,7 @@ HRESULT CDECL wined3d_device_get_stream_source(const struct wined3d_device *devi return WINED3DERR_INVALIDCALL; }
- stream = &device->state->streams[stream_idx]; + stream = &device->cs->state->streams[stream_idx]; *buffer = stream->buffer; if (offset) *offset = stream->offset; @@ -1403,7 +1401,7 @@ static void wined3d_device_set_stream_source_freq(struct wined3d_device *device,
TRACE("device %p, stream_idx %u, divider %#x.\n", device, stream_idx, divider);
- stream = &device->state->streams[stream_idx]; + stream = &device->cs->state->streams[stream_idx]; old_flags = stream->flags; old_freq = stream->frequency;
@@ -1429,13 +1427,13 @@ static void wined3d_device_set_transform(struct wined3d_device *device, * tend towards setting the same matrix repeatedly for some reason. * * From here on we assume that the new matrix is different, wherever it matters. */ - if (!memcmp(&device->state->transforms[state], matrix, sizeof(*matrix))) + if (!memcmp(&device->cs->state->transforms[state], matrix, sizeof(*matrix))) { TRACE("The application is setting the same matrix over again.\n"); return; }
- device->state->transforms[state] = *matrix; + device->cs->state->transforms[state] = *matrix; wined3d_cs_emit_set_transform(device->cs, state, matrix); }
@@ -1444,7 +1442,7 @@ static void wined3d_device_get_transform(const struct wined3d_device *device, { TRACE("device %p, state %s, matrix %p.\n", device, debug_d3dtstype(state), matrix);
- *matrix = device->state->transforms[state]; + *matrix = device->cs->state->transforms[state]; }
/* Note lights are real special cases. Although the device caps state only @@ -1462,7 +1460,7 @@ static void wined3d_device_set_light(struct wined3d_device *device,
TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light);
- if (FAILED(wined3d_light_state_set_light(&device->state->light_state, light_idx, light, &object))) + if (FAILED(wined3d_light_state_set_light(&device->cs->state->light_state, light_idx, light, &object))) return;
/* Initialize the object. */ @@ -1556,7 +1554,7 @@ static void wined3d_device_set_light(struct wined3d_device *device,
static void wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable) { - struct wined3d_light_state *light_state = &device->state->light_state; + struct wined3d_light_state *light_state = &device->cs->state->light_state; struct wined3d_light_info *light_info;
TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable); @@ -1581,7 +1579,7 @@ static void wined3d_device_set_light_enable(struct wined3d_device *device, UINT static HRESULT wined3d_device_set_clip_plane(struct wined3d_device *device, UINT plane_idx, const struct wined3d_vec4 *plane) { - struct wined3d_vec4 *clip_planes = device->state->clip_planes; + struct wined3d_vec4 *clip_planes = device->cs->state->clip_planes;
TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
@@ -1630,14 +1628,14 @@ static void wined3d_device_set_material(struct wined3d_device *device, const str { TRACE("device %p, material %p.\n", device, material);
- device->state->material = *material; + device->cs->state->material = *material; wined3d_cs_emit_set_material(device->cs, material); }
void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device, struct wined3d_buffer *buffer, enum wined3d_format_id format_id, unsigned int offset) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; enum wined3d_format_id prev_format; struct wined3d_buffer *prev_buffer; unsigned int prev_offset; @@ -1665,7 +1663,7 @@ void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device, struct wined3d_buffer * CDECL wined3d_device_get_index_buffer(const struct wined3d_device *device, enum wined3d_format_id *format, unsigned int *offset) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state;
TRACE("device %p, format %p, offset %p.\n", device, format, offset);
@@ -1679,13 +1677,13 @@ void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, I { TRACE("device %p, base_index %d.\n", device, base_index);
- device->state->base_vertex_index = base_index; + device->cs->state->base_vertex_index = base_index; }
void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count, const struct wined3d_viewport *viewports) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; unsigned int i;
TRACE("device %p, viewport_count %u, viewports %p.\n", device, viewport_count, viewports); @@ -1708,7 +1706,7 @@ void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned void CDECL wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count, struct wined3d_viewport *viewports) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state; unsigned int count;
TRACE("device %p, viewport_count %p, viewports %p.\n", device, viewport_count, viewports); @@ -1722,7 +1720,7 @@ void CDECL wined3d_device_get_viewports(const struct wined3d_device *device, uns
static void resolve_depth_buffer(struct wined3d_device *device) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state; struct wined3d_rendertarget_view *src_view; struct wined3d_resource *dst_resource; struct wined3d_texture *dst_texture; @@ -1742,7 +1740,7 @@ static void resolve_depth_buffer(struct wined3d_device *device) void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state, const struct wined3d_color *blend_factor, unsigned int sample_mask) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_blend_state *prev;
TRACE("device %p, blend_state %p, blend_factor %s, sample_mask %#x.\n", @@ -1766,7 +1764,7 @@ void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct wined3d_device *device, struct wined3d_color *blend_factor, unsigned int *sample_mask) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state;
TRACE("device %p, blend_factor %p, sample_mask %p.\n", device, blend_factor, sample_mask);
@@ -1778,7 +1776,7 @@ struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct w void CDECL wined3d_device_set_depth_stencil_state(struct wined3d_device *device, struct wined3d_depth_stencil_state *depth_stencil_state, unsigned int stencil_ref) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_depth_stencil_state *prev;
TRACE("device %p, depth_stencil_state %p, stencil_ref %u.\n", device, depth_stencil_state, stencil_ref); @@ -1799,7 +1797,7 @@ void CDECL wined3d_device_set_depth_stencil_state(struct wined3d_device *device, struct wined3d_depth_stencil_state * CDECL wined3d_device_get_depth_stencil_state(const struct wined3d_device *device, unsigned int *stencil_ref) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state;
TRACE("device %p, stencil_ref %p.\n", device, stencil_ref);
@@ -1810,7 +1808,7 @@ struct wined3d_depth_stencil_state * CDECL wined3d_device_get_depth_stencil_stat void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, struct wined3d_rasterizer_state *rasterizer_state) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_rasterizer_state *prev;
TRACE("device %p, rasterizer_state %p.\n", device, rasterizer_state); @@ -1831,7 +1829,7 @@ struct wined3d_rasterizer_state * CDECL wined3d_device_get_rasterizer_state(stru { TRACE("device %p.\n", device);
- return device->state->rasterizer_state; + return device->cs->state->rasterizer_state; }
void CDECL wined3d_device_set_render_state(struct wined3d_device *device, @@ -1845,11 +1843,11 @@ void CDECL wined3d_device_set_render_state(struct wined3d_device *device, return; }
- if (value == device->state->render_states[state]) + if (value == device->cs->state->render_states[state]) TRACE("Application is setting the old value over, nothing to do.\n"); else { - device->state->render_states[state] = value; + device->cs->state->render_states[state] = value; wined3d_cs_emit_set_render_state(device->cs, state, value); }
@@ -1864,7 +1862,7 @@ DWORD CDECL wined3d_device_get_render_state(const struct wined3d_device *device, { TRACE("device %p, state %s (%#x).\n", device, debug_d3drenderstate(state), state);
- return device->state->render_states[state]; + return device->cs->state->render_states[state]; }
static void wined3d_device_set_sampler_state(struct wined3d_device *device, @@ -1873,20 +1871,20 @@ static void wined3d_device_set_sampler_state(struct wined3d_device *device, TRACE("device %p, sampler_idx %u, state %s, value %#x.\n", device, sampler_idx, debug_d3dsamplerstate(state), value);
- if (value == device->state->sampler_states[sampler_idx][state]) + if (value == device->cs->state->sampler_states[sampler_idx][state]) { TRACE("Application is setting the old value over, nothing to do.\n"); return; }
- device->state->sampler_states[sampler_idx][state] = value; + device->cs->state->sampler_states[sampler_idx][state] = value; wined3d_cs_emit_set_sampler_state(device->cs, sampler_idx, state, value); }
void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsigned int rect_count, const RECT *rects) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; unsigned int i;
TRACE("device %p, rect_count %u, rects %p.\n", device, rect_count, rects); @@ -1914,7 +1912,7 @@ void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsig
void CDECL wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, RECT *rects) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state; unsigned int count;
TRACE("device %p, rect_count %p, rects %p.\n", device, rect_count, rects); @@ -1933,7 +1931,7 @@ void CDECL wined3d_device_set_state(struct wined3d_device *device, struct wined3
TRACE("device %p, state %p.\n", device, state);
- device->state = state; + device->cs->state = state;
for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i) { @@ -2053,13 +2051,13 @@ struct wined3d_state * CDECL wined3d_device_get_state(struct wined3d_device *dev { TRACE("device %p.\n", device);
- return device->state; + return device->cs->state; }
void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device, struct wined3d_vertex_declaration *declaration) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_vertex_declaration *prev;
TRACE("device %p, declaration %p.\n", device, declaration); @@ -2080,12 +2078,12 @@ struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration( { TRACE("device %p.\n", device);
- return device->state->vertex_declaration; + return device->cs->state->vertex_declaration; }
void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader *prev;
TRACE("device %p, shader %p.\n", device, shader); @@ -2106,13 +2104,13 @@ struct wined3d_shader * CDECL wined3d_device_get_vertex_shader(const struct wine { TRACE("device %p.\n", device);
- return device->state->shader[WINED3D_SHADER_TYPE_VERTEX]; + return device->cs->state->shader[WINED3D_SHADER_TYPE_VERTEX]; }
void CDECL wined3d_device_set_constant_buffer(struct wined3d_device *device, enum wined3d_shader_type type, UINT idx, struct wined3d_buffer *buffer) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_buffer *prev;
TRACE("device %p, type %#x, idx %u, buffer %p.\n", device, type, idx, buffer); @@ -2146,14 +2144,14 @@ struct wined3d_buffer * CDECL wined3d_device_get_constant_buffer(const struct wi return NULL; }
- return device->state->cb[shader_type][idx]; + return device->cs->state->cb[shader_type][idx]; }
static void wined3d_device_set_shader_resource_view(struct wined3d_device *device, enum wined3d_shader_type type, UINT idx, struct wined3d_shader_resource_view *view) { const struct wined3d_rendertarget_view *dsv; - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader_resource_view *prev;
if (idx >= MAX_SHADER_RESOURCE_VIEWS) @@ -2206,7 +2204,7 @@ static struct wined3d_shader_resource_view *wined3d_device_get_shader_resource_v return NULL; }
- return device->state->shader_resource_view[shader_type][idx]; + return device->cs->state->shader_resource_view[shader_type][idx]; }
struct wined3d_shader_resource_view * CDECL wined3d_device_get_vs_resource_view(const struct wined3d_device *device, @@ -2220,7 +2218,7 @@ struct wined3d_shader_resource_view * CDECL wined3d_device_get_vs_resource_view( static void wined3d_device_set_sampler(struct wined3d_device *device, enum wined3d_shader_type type, UINT idx, struct wined3d_sampler *sampler) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_sampler *prev;
if (idx >= MAX_SAMPLER_OBJECTS) @@ -2257,7 +2255,7 @@ static struct wined3d_sampler *wined3d_device_get_sampler(const struct wined3d_d return NULL; }
- return device->state->sampler[shader_type][idx]; + return device->cs->state->sampler[shader_type][idx]; }
struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx) @@ -2275,7 +2273,7 @@ static void wined3d_device_set_vs_consts_b(struct wined3d_device *device, TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
- memcpy(&device->state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->cs->state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) @@ -2293,7 +2291,7 @@ static void wined3d_device_set_vs_consts_i(struct wined3d_device *device, TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
- memcpy(&device->state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->cs->state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) @@ -2311,7 +2309,7 @@ static void wined3d_device_set_vs_consts_f(struct wined3d_device *device, TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
- memcpy(&device->state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->cs->state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) @@ -2323,7 +2321,7 @@ static void wined3d_device_set_vs_consts_f(struct wined3d_device *device,
void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader *prev;
TRACE("device %p, shader %p.\n", device, shader); @@ -2344,7 +2342,7 @@ struct wined3d_shader * CDECL wined3d_device_get_pixel_shader(const struct wined { TRACE("device %p.\n", device);
- return device->state->shader[WINED3D_SHADER_TYPE_PIXEL]; + return device->cs->state->shader[WINED3D_SHADER_TYPE_PIXEL]; }
void CDECL wined3d_device_set_ps_resource_view(struct wined3d_device *device, @@ -2385,7 +2383,7 @@ static void wined3d_device_set_ps_consts_b(struct wined3d_device *device, TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
- memcpy(&device->state->ps_consts_b[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->cs->state->ps_consts_b[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) @@ -2403,7 +2401,7 @@ static void wined3d_device_set_ps_consts_i(struct wined3d_device *device, TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
- memcpy(&device->state->ps_consts_i[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->cs->state->ps_consts_i[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) @@ -2421,7 +2419,7 @@ static void wined3d_device_set_ps_consts_f(struct wined3d_device *device, TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
- memcpy(&device->state->ps_consts_f[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->cs->state->ps_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) @@ -2433,7 +2431,7 @@ static void wined3d_device_set_ps_consts_f(struct wined3d_device *device,
void CDECL wined3d_device_set_hull_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader *prev;
TRACE("device %p, shader %p.\n", device, shader); @@ -2453,7 +2451,7 @@ struct wined3d_shader * CDECL wined3d_device_get_hull_shader(const struct wined3 { TRACE("device %p.\n", device);
- return device->state->shader[WINED3D_SHADER_TYPE_HULL]; + return device->cs->state->shader[WINED3D_SHADER_TYPE_HULL]; }
void CDECL wined3d_device_set_hs_resource_view(struct wined3d_device *device, @@ -2489,7 +2487,7 @@ struct wined3d_sampler * CDECL wined3d_device_get_hs_sampler(const struct wined3
void CDECL wined3d_device_set_domain_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader *prev;
TRACE("device %p, shader %p.\n", device, shader); @@ -2509,7 +2507,7 @@ struct wined3d_shader * CDECL wined3d_device_get_domain_shader(const struct wine { TRACE("device %p.\n", device);
- return device->state->shader[WINED3D_SHADER_TYPE_DOMAIN]; + return device->cs->state->shader[WINED3D_SHADER_TYPE_DOMAIN]; }
void CDECL wined3d_device_set_ds_resource_view(struct wined3d_device *device, @@ -2545,7 +2543,7 @@ struct wined3d_sampler * CDECL wined3d_device_get_ds_sampler(const struct wined3
void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader *prev;
TRACE("device %p, shader %p.\n", device, shader); @@ -2565,7 +2563,7 @@ struct wined3d_shader * CDECL wined3d_device_get_geometry_shader(const struct wi { TRACE("device %p.\n", device);
- return device->state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; + return device->cs->state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; }
void CDECL wined3d_device_set_gs_resource_view(struct wined3d_device *device, @@ -2600,7 +2598,7 @@ struct wined3d_sampler * CDECL wined3d_device_get_gs_sampler(const struct wined3
void CDECL wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_shader *prev;
TRACE("device %p, shader %p.\n", device, shader); @@ -2620,7 +2618,7 @@ struct wined3d_shader * CDECL wined3d_device_get_compute_shader(const struct win { TRACE("device %p.\n", device);
- return device->state->shader[WINED3D_SHADER_TYPE_COMPUTE]; + return device->cs->state->shader[WINED3D_SHADER_TYPE_COMPUTE]; }
void CDECL wined3d_device_set_cs_resource_view(struct wined3d_device *device, @@ -2658,7 +2656,7 @@ static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_dev enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_unordered_access_view *prev;
if (idx >= MAX_UNORDERED_ACCESS_VIEWS) @@ -2688,7 +2686,7 @@ static struct wined3d_unordered_access_view *wined3d_device_get_pipeline_unorder return NULL; }
- return device->state->unordered_access_view[pipeline][idx]; + return device->cs->state->unordered_access_view[pipeline][idx]; }
void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx, @@ -3289,7 +3287,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO enum wined3d_material_color_source diffuse_source, specular_source, ambient_source, emissive_source; const struct wined3d_color *material_specular_state_colour; struct wined3d_matrix mat, proj_mat, view_mat, world_mat; - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state; const struct wined3d_format *output_colour_format; static const struct wined3d_color black; struct wined3d_map_desc map_desc; @@ -3607,7 +3605,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer, const struct wined3d_vertex_declaration *declaration, DWORD flags, DWORD dst_fvf) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_stream_info stream_info; struct wined3d_resource *resource; struct wined3d_box box = {0}; @@ -3696,13 +3694,13 @@ static void wined3d_device_set_texture_stage_state(struct wined3d_device *device return; }
- if (value == device->state->texture_states[stage][state]) + if (value == device->cs->state->texture_states[stage][state]) { TRACE("Application is setting the old value over, nothing to do.\n"); return; }
- device->state->texture_states[stage][state] = value; + device->cs->state->texture_states[stage][state] = value;
wined3d_cs_emit_set_texture_state(device->cs, stage, state, value); } @@ -3710,7 +3708,7 @@ static void wined3d_device_set_texture_stage_state(struct wined3d_device *device static void wined3d_device_set_texture(struct wined3d_device *device, UINT stage, struct wined3d_texture *texture) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_texture *prev;
TRACE("device %p, stage %u, texture %p.\n", device, stage, texture); @@ -4201,7 +4199,7 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - struct wined3d_fb_state *fb = &device->state->fb; + struct wined3d_fb_state *fb = &device->cs->state->fb;
TRACE("device %p, rect_count %u, rects %p, flags %#x, color %s, depth %.8e, stencil %u.\n", device, rect_count, rects, flags, debug_color(color), depth, stencil); @@ -4240,7 +4238,7 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou void CDECL wined3d_device_set_predication(struct wined3d_device *device, struct wined3d_query *predicate, BOOL value) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_query *prev;
TRACE("device %p, predicate %p, value %#x.\n", device, predicate, value); @@ -4260,7 +4258,7 @@ void CDECL wined3d_device_set_predication(struct wined3d_device *device,
struct wined3d_query * CDECL wined3d_device_get_predication(struct wined3d_device *device, BOOL *value) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, value %p.\n", device, value);
@@ -4289,7 +4287,7 @@ void CDECL wined3d_device_dispatch_compute_indirect(struct wined3d_device *devic void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, enum wined3d_primitive_type primitive_type, unsigned int patch_vertex_count) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, primitive_type %s, patch_vertex_count %u.\n", device, debug_d3dprimitivetype(primitive_type), patch_vertex_count); @@ -4301,7 +4299,7 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device, enum wined3d_primitive_type *primitive_type, unsigned int *patch_vertex_count) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state;
TRACE("device %p, primitive_type %p, patch_vertex_count %p.\n", device, primitive_type, patch_vertex_count); @@ -4315,7 +4313,7 @@ void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device
HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT start_vertex, UINT vertex_count) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, start_vertex %u, vertex_count %u.\n", device, start_vertex, vertex_count);
@@ -4328,7 +4326,7 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT void CDECL wined3d_device_draw_primitive_instanced(struct wined3d_device *device, UINT start_vertex, UINT vertex_count, UINT start_instance, UINT instance_count) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, start_vertex %u, vertex_count %u, start_instance %u, instance_count %u.\n", device, start_vertex, vertex_count, start_instance, instance_count); @@ -4340,7 +4338,7 @@ void CDECL wined3d_device_draw_primitive_instanced(struct wined3d_device *device void CDECL wined3d_device_draw_primitive_instanced_indirect(struct wined3d_device *device, struct wined3d_buffer *buffer, unsigned int offset) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
@@ -4350,7 +4348,7 @@ void CDECL wined3d_device_draw_primitive_instanced_indirect(struct wined3d_devic
HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
@@ -4373,7 +4371,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device, UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", device, start_idx, index_count, start_instance, instance_count); @@ -4385,7 +4383,7 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device void CDECL wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device, struct wined3d_buffer *buffer, unsigned int offset) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
@@ -4550,7 +4548,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes) { - const struct wined3d_state *state = device->state; + const struct wined3d_state *state = device->cs->state; struct wined3d_texture *texture; DWORD i;
@@ -5136,20 +5134,20 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(co return NULL; }
- return device->state->fb.render_targets[view_idx]; + return device->cs->state->fb.render_targets[view_idx]; }
struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(const struct wined3d_device *device) { TRACE("device %p.\n", device);
- return device->state->fb.depth_stencil; + return device->cs->state->fb.depth_stencil; }
static void wined3d_unbind_srv_for_rtv(struct wined3d_device *device, const struct wined3d_rendertarget_view *view, BOOL dsv) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state;
if (view && wined3d_is_rtv_srv_bound(view)) { @@ -5171,7 +5169,7 @@ static void wined3d_unbind_srv_for_rtv(struct wined3d_device *device, HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device, unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) { - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_rendertarget_view *prev; unsigned int max_rt_count;
@@ -5237,7 +5235,7 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device HRESULT CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) { - struct wined3d_fb_state *fb = &device->state->fb; + struct wined3d_fb_state *fb = &device->cs->state->fb; struct wined3d_rendertarget_view *prev;
TRACE("device %p, view %p.\n", device, view); @@ -5512,7 +5510,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_swapchain_state *swapchain_state; struct wined3d_swapchain_desc *current_desc; - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_resource *resource, *cursor; struct wined3d_rendertarget_view *view; struct wined3d_swapchain *swapchain; @@ -5867,7 +5865,7 @@ static void device_resource_remove(struct wined3d_device *device, struct wined3d void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) { enum wined3d_resource_type type = resource->type; - struct wined3d_state *state = device->state; + struct wined3d_state *state = device->cs->state; struct wined3d_rendertarget_view *rtv; unsigned int i;
@@ -6025,7 +6023,6 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx]; const struct wined3d_fragment_pipe_ops *fragment_pipeline; const struct wined3d_vertex_pipe_ops *vertex_pipeline; - struct wined3d_state *state; unsigned int i; HRESULT hr;
@@ -6076,39 +6073,23 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined return hr; }
- if (FAILED(hr = wined3d_state_create(device, &state))) - { - ERR("Failed to create device state, hr %#x.\n", hr); - goto err; - } - - device->state = state; device->max_frame_latency = 3;
if (!(device->cs = wined3d_cs_create(device))) { WARN("Failed to create command stream.\n"); - state_cleanup(state); - hr = E_FAIL; - goto err; + for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i) + heap_free(device->multistate_funcs[i]); + wine_rb_destroy(&device->samplers, NULL, NULL); + wine_rb_destroy(&device->rasterizer_states, NULL, NULL); + wine_rb_destroy(&device->blend_states, NULL, NULL); + wine_rb_destroy(&device->depth_stencil_states, NULL, NULL); + wine_rb_destroy(&device->so_descs, NULL, NULL); + wined3d_decref(device->wined3d); + return E_FAIL; }
return WINED3D_OK; - -err: - if (state) - wined3d_state_destroy(state); - for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i) - { - heap_free(device->multistate_funcs[i]); - } - wine_rb_destroy(&device->samplers, NULL, NULL); - wine_rb_destroy(&device->rasterizer_states, NULL, NULL); - wine_rb_destroy(&device->blend_states, NULL, NULL); - wine_rb_destroy(&device->depth_stencil_states, NULL, NULL); - wine_rb_destroy(&device->so_descs, NULL, NULL); - wined3d_decref(device->wined3d); - return hr; }
void device_invalidate_state(const struct wined3d_device *device, unsigned int state_id) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 17063a09009..b5c10156989 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1610,7 +1610,7 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) wined3d_texture_gl(texture)->texture_srgb.base_level = ~0u; if (resource->bind_count) wined3d_cs_emit_set_sampler_state(device->cs, texture->sampler, WINED3D_SAMP_MAX_MIP_LEVEL, - device->state->sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]); + device->cs->state->sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]); }
return old; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 18717b5207f..84f237f8189 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3781,8 +3781,6 @@ struct wined3d_device
enum wined3d_feature_level feature_level;
- struct wined3d_state *state; - /* Internal use fields */ struct wined3d_device_creation_parameters create_parms; HWND focus_window; @@ -4696,6 +4694,8 @@ struct wined3d_cs DWORD thread_id; BOOL serialize_commands;
+ struct wined3d_state *state; + struct wined3d_cs_queue queue[WINED3D_CS_QUEUE_COUNT]; size_t data_size, start, end; void *data;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 12 ++++++++ dlls/wined3d/device.c | 68 ------------------------------------------- 2 files changed, 12 insertions(+), 68 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 4ae9f1f8c09..561d577f441 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1623,7 +1623,19 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) { + struct wined3d_state *state = cs->state; struct wined3d_cs_set_shader *op; + struct wined3d_shader *prev; + + prev = state->shader[type]; + if (shader == prev) + return; + + if (shader) + wined3d_shader_incref(shader); + state->shader[type] = shader; + if (prev) + wined3d_shader_decref(prev);
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7b9fd830a37..9ffeeac187b 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2083,21 +2083,9 @@ struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration(
void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->cs->state; - struct wined3d_shader *prev; - TRACE("device %p, shader %p.\n", device, shader);
- prev = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - if (shader == prev) - return; - - if (shader) - wined3d_shader_incref(shader); - state->shader[WINED3D_SHADER_TYPE_VERTEX] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader); - if (prev) - wined3d_shader_decref(prev); }
struct wined3d_shader * CDECL wined3d_device_get_vertex_shader(const struct wined3d_device *device) @@ -2321,21 +2309,9 @@ static void wined3d_device_set_vs_consts_f(struct wined3d_device *device,
void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->cs->state; - struct wined3d_shader *prev; - TRACE("device %p, shader %p.\n", device, shader);
- prev = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - if (shader == prev) - return; - - if (shader) - wined3d_shader_incref(shader); - state->shader[WINED3D_SHADER_TYPE_PIXEL] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_PIXEL, shader); - if (prev) - wined3d_shader_decref(prev); }
struct wined3d_shader * CDECL wined3d_device_get_pixel_shader(const struct wined3d_device *device) @@ -2431,20 +2407,9 @@ static void wined3d_device_set_ps_consts_f(struct wined3d_device *device,
void CDECL wined3d_device_set_hull_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->cs->state; - struct wined3d_shader *prev; - TRACE("device %p, shader %p.\n", device, shader);
- prev = state->shader[WINED3D_SHADER_TYPE_HULL]; - if (shader == prev) - return; - if (shader) - wined3d_shader_incref(shader); - state->shader[WINED3D_SHADER_TYPE_HULL] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_HULL, shader); - if (prev) - wined3d_shader_decref(prev); }
struct wined3d_shader * CDECL wined3d_device_get_hull_shader(const struct wined3d_device *device) @@ -2487,20 +2452,9 @@ struct wined3d_sampler * CDECL wined3d_device_get_hs_sampler(const struct wined3
void CDECL wined3d_device_set_domain_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->cs->state; - struct wined3d_shader *prev; - TRACE("device %p, shader %p.\n", device, shader);
- prev = state->shader[WINED3D_SHADER_TYPE_DOMAIN]; - if (shader == prev) - return; - if (shader) - wined3d_shader_incref(shader); - state->shader[WINED3D_SHADER_TYPE_DOMAIN] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_DOMAIN, shader); - if (prev) - wined3d_shader_decref(prev); }
struct wined3d_shader * CDECL wined3d_device_get_domain_shader(const struct wined3d_device *device) @@ -2543,20 +2497,9 @@ struct wined3d_sampler * CDECL wined3d_device_get_ds_sampler(const struct wined3
void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->cs->state; - struct wined3d_shader *prev; - TRACE("device %p, shader %p.\n", device, shader);
- prev = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; - if (shader == prev) - return; - if (shader) - wined3d_shader_incref(shader); - state->shader[WINED3D_SHADER_TYPE_GEOMETRY] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_GEOMETRY, shader); - if (prev) - wined3d_shader_decref(prev); }
struct wined3d_shader * CDECL wined3d_device_get_geometry_shader(const struct wined3d_device *device) @@ -2598,20 +2541,9 @@ struct wined3d_sampler * CDECL wined3d_device_get_gs_sampler(const struct wined3
void CDECL wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_state *state = device->cs->state; - struct wined3d_shader *prev; - TRACE("device %p, shader %p.\n", device, shader);
- prev = state->shader[WINED3D_SHADER_TYPE_COMPUTE]; - if (shader == prev) - return; - if (shader) - wined3d_shader_incref(shader); - state->shader[WINED3D_SHADER_TYPE_COMPUTE] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_COMPUTE, shader); - if (prev) - wined3d_shader_decref(prev); }
struct wined3d_shader * CDECL wined3d_device_get_compute_shader(const struct wined3d_device *device)
On Tue, 2 Mar 2021 at 05:42, Zebediah Figura z.figura12@gmail.com wrote:
void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) {
struct wined3d_state *state = cs->state; struct wined3d_cs_set_shader *op;
struct wined3d_shader *prev;
prev = state->shader[type];
if (shader == prev)
return;
if (shader)
wined3d_shader_incref(shader);
state->shader[type] = shader;
if (prev)
wined3d_shader_decref(prev);
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER;
This kind of consolidation is fine, and we'll probably want to push it a little further still, like we do for e.g. wined3d_device_set_constant_buffer(), but I don't think it belongs in wined3d_cs_emit_set_shader(). I don't know what your plans for the public wined3d API for deferred contexts are, but I image we'd have something similar to the following:
HRESULT CDECL wined3d_device_context_set_shader(struct wined3d_device_context *context, enum wined3d_shader_type type, struct wined3d_shader *shader);
and that would seem like the right place for this code.
On 3/2/21 8:32 AM, Henri Verbeet wrote:
On Tue, 2 Mar 2021 at 05:42, Zebediah Figura z.figura12@gmail.com wrote:
void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) {
struct wined3d_state *state = cs->state; struct wined3d_cs_set_shader *op;
struct wined3d_shader *prev;
prev = state->shader[type];
if (shader == prev)
return;
if (shader)
wined3d_shader_incref(shader);
state->shader[type] = shader;
if (prev)
wined3d_shader_decref(prev);
op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER;
This kind of consolidation is fine, and we'll probably want to push it a little further still, like we do for e.g. wined3d_device_set_constant_buffer(), but I don't think it belongs in wined3d_cs_emit_set_shader(). I don't know what your plans for the public wined3d API for deferred contexts are, but I image we'd have something similar to the following:
HRESULT CDECL wined3d_device_context_set_shader(struct
wined3d_device_context *context, enum wined3d_shader_type type, struct wined3d_shader *shader);
and that would seem like the right place for this code.
Essentially, my plan *was* to export wined3d_cs_emit_set_shader() directly [perhaps with some terminology changed, but the same arguments]. I guess the only reason not to do that now is wined3d_device_set_state().
On Tue, 2 Mar 2021 at 17:36, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
Essentially, my plan *was* to export wined3d_cs_emit_set_shader() directly [perhaps with some terminology changed, but the same arguments]. I guess the only reason not to do that now is wined3d_device_set_state().
An argument could perhaps be made for e.g. a wined3d_cs_set_shader(), but ultimately the existence of struct wined3d_cs seems like a wined3d implementation detail from the point of view of e.g. d3d11.
On 3/2/21 10:59 AM, Henri Verbeet wrote:
On Tue, 2 Mar 2021 at 17:36, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
Essentially, my plan *was* to export wined3d_cs_emit_set_shader() directly [perhaps with some terminology changed, but the same arguments]. I guess the only reason not to do that now is wined3d_device_set_state().
An argument could perhaps be made for e.g. a wined3d_cs_set_shader(), but ultimately the existence of struct wined3d_cs seems like a wined3d implementation detail from the point of view of e.g. d3d11.
Sure, but it's not clear to me that's a sign that anything other than the terminology is bad (which was always going to be true). The wined3d_cs_* functions and wined3d_cs could be easily renamed to something else.
On Tue, 2 Mar 2021 at 18:07, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
Sure, but it's not clear to me that's a sign that anything other than the terminology is bad (which was always going to be true). The wined3d_cs_* functions and wined3d_cs could be easily renamed to something else.
True, I suppose.
On Tue, 2 Mar 2021 at 05:42, Zebediah Figura z.figura12@gmail.com wrote:
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.
As a principle, it's probably fine that an "immediate" cs would have some additional data that a deferred cs doesn't. I'd suggest to split that the same way we do in other places though. E.g.:
struct wined3d_cs { const struct wined3d_cs_ops *ops; ... };
struct wined3d_cs_immediate { struct wined3d_cs c; ... struct wined3d_state state; ... };
struct wined3d_cs_mt { struct wined3d_cs_immediate c; ... HANDLE thread; ... };
On 3/2/21 8:32 AM, Henri Verbeet wrote:
On Tue, 2 Mar 2021 at 05:42, Zebediah Figura z.figura12@gmail.com wrote:
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.
As a principle, it's probably fine that an "immediate" cs would have some additional data that a deferred cs doesn't. I'd suggest to split that the same way we do in other places though. E.g.:
struct wined3d_cs { const struct wined3d_cs_ops *ops; ... }; struct wined3d_cs_immediate { struct wined3d_cs c; ... struct wined3d_state state; ... }; struct wined3d_cs_mt { struct wined3d_cs_immediate c; ... HANDLE thread; ... };
Sure, that makes sense.
After mulling over this and the comments on patch 4/4, I'd like to propose the following:
struct wined3d_device_context { const struct wined3d_device_context_ops *ops; struct wined3d_device *device; struct wined3d_state state; };
struct wined3d_device_context_deferred { struct wined3d_device_context c;
size_t data_size, start, end; void *data; };
struct wined3d_cs { struct wined3d_device_context c;
struct wined3d_state cs_state;
struct list query_poll_list; BOOL queries_flushed;
LONG pending_presents; };
struct wined3d_cs_st { struct wined3d_cs c;
size_t data_size, start, end; void *data; };
struct wined3d_cs_mt { struct wined3d_cs c;
struct wined3d_cs_queue queue[WINED3D_CS_QUEUE_COUNT];
HMODULE wined3d_module; HANDLE thread; DWORD thread_id; BOOL serialize_commands;
HANDLE event; BOOL waiting_for_event; };
...
void d3d11_immediate_context_PSSetShader(...) { struct d3d_device_context *context = impl_from_immediate_ID3D11DeviceContext1(iface);
wined3d_mutex_lock(); wined3d_device_context_set_shader(context->wined3d_device_context, WINED3D_SHADER_TYPE_PIXEL, ps ? ps->wined3d_shader : NULL); wined3d_mutex_unlock(); }
...
void CDECL wined3d_device_context_set_shader( struct wined3d_device_context *device_context, enum wined3d_shader_type type, struct wined3d_shader *shader) { struct wined3d_state *state = device_context->state; struct wined3d_device_context_set_shader *op; struct wined3d_shader *prev;
prev = state->shader[type]; if (shader == prev) return;
if (shader) wined3d_shader_incref(shader); state->shader[type] = shader; if (prev) wined3d_shader_decref(prev);
op = wined3d_device_context_require_space(device_context, sizeof(*op), WINED3D_DEVICE_CONTEXT_QUEUE_DEFAULT); op->opcode = WINED3D_DEVICE_CONTEXT_OP_SET_SHADER; op->type = type; op->shader = shader;
wined3d_device_context_submit(device_context, WINED3D_DEVICE_CONTEXT_QUEUE_DEFAULT); }
...
static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) { const struct wined3d_device_context_set_shader *op = data;
cs->cs_state.shader[op->type] = op->shader; device_invalidate_state(cs->c.device, STATE_SHADER(op->type)); if (op->type != WINED3D_SHADER_TYPE_COMPUTE) device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); else device_invalidate_state(cs->c.device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); }
In essence, this is pretty much the same thing as I was proposing with patch 4/4, except with different names, and with the struct inheritance as proposed in patch 1/4. Actually, in terms of naming, it's even closer to how I originally started writing this series, before I decided to try an approach that would thrash cs.c less.
The naming is arguably still a little janky (e.g. "wined3d_cs" inheriting from "wined3d_device_context"), but maybe un-janky enough to work.
"wined3d_device_context" is very long, though. I would also propose using "wined3d_queue" instead, which seems shorter and about as accurate. (I think I may have borrowed that one from Matteo.)
SwapContextState() isn't valid on deferred contexts. I'm not sure whether we should ignore that detail in wined3d and treat it like it is, or effectively make it into a wined3d_device_context_ops method. Either way, I think we'd either need to keep state management and op queuing separate (as they are now), or make wined3d_device_set_state into a proper CS operation. I guess I don't have a strong feeling either way.
On Tue, 2 Mar 2021 at 22:11, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
After mulling over this and the comments on patch 4/4, I'd like to propose the following:
I think that largely makes sense. Note however that wined3d_cs_st_require_space() is also used by wined3d_cs_mt_require_space(), so you'll need the "data" and associated fields in wined3d_cs_mt too. The fields for query and present handling aren't used by wined3d_cs_st_ops, although it may still be more convenient to keep them in the base structure. In any case, I think that splitting wined3d_cs_mt and wined3d_cs_st is ultimately only of secondary concern, and it would be fine to defer that.
In essence, this is pretty much the same thing as I was proposing with patch 4/4, except with different names, and with the struct inheritance as proposed in patch 1/4. Actually, in terms of naming, it's even closer to how I originally started writing this series, before I decided to try an approach that would thrash cs.c less.
The naming is arguably still a little janky (e.g. "wined3d_cs" inheriting from "wined3d_device_context"), but maybe un-janky enough to work.
Well, inheritance is a (somewhat discredited) OOP concept that doesn't exist as such in C. In case it helps, try to think about it as composition instead of inheritance. :D
"wined3d_device_context" is very long, though. I would also propose using "wined3d_queue" instead, which seems shorter and about as accurate. (I think I may have borrowed that one from Matteo.)
True, although it would by no means be the longest structure name we have in wined3d (e.g., struct wined3d_unordered_access_view_vk). I suppose we could use "wined3d_dc", but that's hardly unambiguous. Historically we have tended to favour clarity over brevity for things like (public) structure and function names, but that does mean some of our names are a bit on the long side.
SwapContextState() isn't valid on deferred contexts. I'm not sure whether we should ignore that detail in wined3d and treat it like it is, or effectively make it into a wined3d_device_context_ops method. Either way, I think we'd either need to keep state management and op queuing separate (as they are now), or make wined3d_device_set_state into a proper CS operation. I guess I don't have a strong feeling either way.
My initial thought would be to prefer the former, but I don't (yet) feel strongly about it either.