Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Set the auto_depth_stencil_view after resetting the state (so that I can get rid of old_fb). Thanks Henri! --- dlls/wined3d/arb_program_shader.c | 4 +-- dlls/wined3d/context.c | 10 +++--- dlls/wined3d/cs.c | 34 +++++++++---------- dlls/wined3d/device.c | 56 +++++++++++++++++-------------- dlls/wined3d/glsl_shader.c | 2 +- dlls/wined3d/shader.c | 6 ++-- dlls/wined3d/state.c | 30 ++++++++--------- dlls/wined3d/stateblock.c | 4 +-- dlls/wined3d/swapchain.c | 2 +- dlls/wined3d/utils.c | 4 +-- dlls/wined3d/wined3d_private.h | 11 +++--- 11 files changed, 81 insertions(+), 82 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index c39694f441e..36c920dc6e0 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -700,7 +700,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str { const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; - UINT rt_height = state->fb->render_targets[0]->height; + UINT rt_height = state->fb.render_targets[0]->height;
/* Load DirectX 9 float constants for pixel shader */ priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, @@ -4607,7 +4607,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context } else { - UINT rt_height = state->fb->render_targets[0]->height; + UINT rt_height = state->fb.render_targets[0]->height; shader_arb_ps_local_constants(compiled, context_gl, state, rt_height); }
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e92ce62662f..c6a1d762673 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3319,7 +3319,7 @@ BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, uint32_t rt_mask = 0, *cur_mask; unsigned int i;
- if (isStateDirty(&context_gl->c, STATE_FRAMEBUFFER) || fb != state->fb + if (isStateDirty(&context_gl->c, STATE_FRAMEBUFFER) || fb != &state->fb || rt_count != gl_info->limits.buffers) { if (!have_framebuffer_attachment(rt_count, rts, dsv)) @@ -3431,7 +3431,7 @@ BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl,
static uint32_t find_draw_buffers_mask(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { - struct wined3d_rendertarget_view * const *rts = state->fb->render_targets; + struct wined3d_rendertarget_view * const *rts = state->fb.render_targets; struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int rt_mask, mask; @@ -3463,7 +3463,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); uint32_t rt_mask = find_draw_buffers_mask(context_gl, state); - const struct wined3d_fb_state *fb = state->fb; + const struct wined3d_fb_state *fb = &state->fb; DWORD color_location = 0; DWORD *cur_mask;
@@ -4230,7 +4230,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_state_entry *state_table = context->state_table; struct wined3d_context_gl *context_gl = wined3d_context_gl(context); const struct wined3d_gl_info *gl_info = context_gl->gl_info; - const struct wined3d_fb_state *fb = state->fb; + const struct wined3d_fb_state *fb = &state->fb; unsigned int i, base; WORD map;
@@ -5121,7 +5121,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s const struct wined3d_draw_parameters *parameters) { BOOL emulation = FALSE, rasterizer_discard = FALSE; - const struct wined3d_fb_state *fb = state->fb; + const struct wined3d_fb_state *fb = &state->fb; const struct wined3d_stream_info *stream_info; struct wined3d_rendertarget_view *dsv, *rtv; struct wined3d_stream_info si_emulated; diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 0ab6dd5b189..899d5a712e4 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -612,7 +612,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->fb; + op->fb = &cs->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]); @@ -624,12 +624,12 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
for (i = 0; i < rt_count; ++i) { - if ((view = state->fb->render_targets[i])) + if ((view = state->fb.render_targets[i])) wined3d_resource_acquire(view->resource); } if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) { - view = state->fb->depth_stencil; + view = state->fb.depth_stencil; wined3d_resource_acquire(view->resource); }
@@ -915,11 +915,11 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) } for (i = 0; i < d3d_info->limits.max_rt_count; ++i) { - if (state->fb->render_targets[i]) - wined3d_resource_release(state->fb->render_targets[i]->resource); + if (state->fb.render_targets[i]) + wined3d_resource_release(state->fb.render_targets[i]->resource); } - if (state->fb->depth_stencil) - wined3d_resource_release(state->fb->depth_stencil->resource); + if (state->fb.depth_stencil) + wined3d_resource_release(state->fb.depth_stencil->resource); release_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); release_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL], state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); @@ -949,11 +949,11 @@ static void acquire_graphics_pipeline_resources(const struct wined3d_state *stat } for (i = 0; i < d3d_info->limits.max_rt_count; ++i) { - if (state->fb->render_targets[i]) - wined3d_resource_acquire(state->fb->render_targets[i]->resource); + if (state->fb.render_targets[i]) + wined3d_resource_acquire(state->fb.render_targets[i]->resource); } - if (state->fb->depth_stencil) - wined3d_resource_acquire(state->fb->depth_stencil->resource); + if (state->fb.depth_stencil) + wined3d_resource_acquire(state->fb.depth_stencil->resource); acquire_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL], state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); @@ -1103,8 +1103,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->fb.render_targets[op->view_idx] = op->view; + prev = cs->state.fb.render_targets[op->view_idx]; + cs->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; @@ -1132,7 +1132,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->state.fb.depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER) { struct wined3d_texture *prev_texture = texture_from_resource(prev->resource);
@@ -1142,7 +1142,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED); }
- cs->fb.depth_stencil = op->view; + cs->state.fb.depth_stencil = op->view;
if (!prev != !op->view) { @@ -1965,7 +1965,7 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data)
state_cleanup(&cs->state); memset(&cs->state, 0, sizeof(cs->state)); - state_init(&cs->state, &cs->fb, &adapter->d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + state_init(&cs->state, &adapter->d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); }
void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) @@ -2845,7 +2845,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) cs->ops = &wined3d_cs_st_ops; cs->device = device;
- state_init(&cs->state, &cs->fb, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + state_init(&cs->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))) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e0a1de79098..41554b93cfa 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1070,7 +1070,7 @@ HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, str } device->swapchains[0] = swapchain;
- memset(device->fb.render_targets, 0, sizeof(device->fb.render_targets)); + memset(device->state.fb.render_targets, 0, sizeof(device->state.fb.render_targets)); if (FAILED(hr = device->adapter->adapter_ops->adapter_init_3d(device))) goto err_out;
@@ -1152,8 +1152,6 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wined3d_cs_emit_reset_state(device->cs); state_cleanup(&device->state); - memset(&device->state, 0, sizeof(device->state)); - state_init(&device->state, &device->fb, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) { wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); @@ -1171,11 +1169,11 @@ void wined3d_device_uninit_3d(struct wined3d_device *device) device->adapter->adapter_ops->adapter_uninit_3d(device); device->d3d_initialized = FALSE;
- if ((view = device->fb.depth_stencil)) + if ((view = device->state.fb.depth_stencil)) { TRACE("Releasing depth/stencil view %p.\n", view);
- device->fb.depth_stencil = NULL; + device->state.fb.depth_stencil = NULL; wined3d_rendertarget_view_decref(view); }
@@ -1194,6 +1192,9 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
heap_free(device->swapchains); device->swapchains = NULL; + + memset(&device->state, 0, sizeof(device->state)); + state_init(&device->state, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); }
/* Enables thread safety in the wined3d device and its resources. Called by DirectDraw @@ -1662,7 +1663,7 @@ static void resolve_depth_buffer(struct wined3d_device *device) dst_resource = &dst_texture->resource; if (!(dst_resource->format_flags & WINED3DFMT_FLAG_DEPTH)) return; - if (!(src_view = state->fb->depth_stencil)) + if (!(src_view = state->fb.depth_stencil)) return;
wined3d_device_resolve_sub_resource(device, dst_resource, 0, @@ -3866,7 +3867,7 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) { - struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; + struct wined3d_rendertarget_view *ds = device->state.fb.depth_stencil; if (!ds) { WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); @@ -3875,8 +3876,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou } else if (flags & WINED3DCLEAR_TARGET) { - if (ds->width < device->fb.render_targets[0]->width - || ds->height < device->fb.render_targets[0]->height) + if (ds->width < device->state.fb.render_targets[0]->width + || ds->height < device->state.fb.render_targets[0]->height) { WARN("Silently ignoring depth and target clear with mismatching sizes\n"); return WINED3D_OK; @@ -4226,8 +4227,8 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_STENCILENABLE]) { - struct wined3d_rendertarget_view *rt = device->fb.render_targets[0]; - struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; + struct wined3d_rendertarget_view *rt = device->state.fb.render_targets[0]; + struct wined3d_rendertarget_view *ds = device->state.fb.depth_stencil;
if (ds && rt && (ds->width < rt->width || ds->height < rt->height)) { @@ -4732,14 +4733,14 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(co return NULL; }
- return device->fb.render_targets[view_idx]; + return device->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->fb.depth_stencil; + return device->state.fb.depth_stencil; }
static void wined3d_unbind_srv_for_rtv(struct wined3d_device *device, @@ -4804,13 +4805,13 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects); }
- prev = device->fb.render_targets[view_idx]; + prev = device->state.fb.render_targets[view_idx]; if (view == prev) return WINED3D_OK;
if (view) wined3d_rendertarget_view_incref(view); - device->fb.render_targets[view_idx] = view; + device->state.fb.render_targets[view_idx] = view; wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view); /* Release after the assignment, to prevent device_resource_released() * from seeing the surface as still in use. */ @@ -4836,14 +4837,14 @@ HRESULT CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *devic return WINED3DERR_INVALIDCALL; }
- prev = device->fb.depth_stencil; + prev = device->state.fb.depth_stencil; if (prev == view) { TRACE("Trying to do a NOP SetRenderTarget operation.\n"); return WINED3D_OK; }
- if ((device->fb.depth_stencil = view)) + if ((device->state.fb.depth_stencil = view)) wined3d_rendertarget_view_incref(view); wined3d_cs_emit_set_depth_stencil_view(device->cs, view); if (prev) @@ -5308,8 +5309,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, ERR("Failed to create rendertarget view, hr %#x.\n", hr); return hr; } - - wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); }
if ((view = device->back_buffer_view)) @@ -5354,14 +5353,19 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, device->adapter->adapter_ops->adapter_uninit_3d(device);
memset(&device->state, 0, sizeof(device->state)); - state_init(&device->state, &device->fb, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); + state_init(&device->state, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
device_init_swapchain_state(device, swapchain); if (wined3d_settings.logo) device_load_logo(device, wined3d_settings.logo); } - else if ((view = device->back_buffer_view)) - wined3d_device_set_rendertarget_view(device, 0, view, FALSE); + else + { + if ((view = device->back_buffer_view)) + wined3d_device_set_rendertarget_view(device, 0, view, FALSE); + if ((view = device->auto_depth_stencil_view)) + wined3d_device_set_depth_stencil_view(device, view); + }
if (device->d3d_initialized && reset_state) hr = device->adapter->adapter_ops->adapter_init_3d(device); @@ -5456,13 +5460,13 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
if (device->d3d_initialized) { - for (i = 0; i < ARRAY_SIZE(device->fb.render_targets); ++i) + for (i = 0; i < ARRAY_SIZE(device->state.fb.render_targets); ++i) { - if ((rtv = device->fb.render_targets[i]) && rtv->resource == resource) + if ((rtv = device->state.fb.render_targets[i]) && rtv->resource == resource) ERR("Resource %p is still in use as render target %u.\n", resource, i); }
- if ((rtv = device->fb.depth_stencil) && rtv->resource == resource) + if ((rtv = device->state.fb.depth_stencil) && rtv->resource == resource) ERR("Resource %p is still in use as depth/stencil buffer.\n", resource); }
@@ -5604,7 +5608,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined return hr; }
- state_init(&device->state, &device->fb, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); + state_init(&device->state, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
device->max_frame_latency = 3;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 4272453c1b5..c7feff85efb 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1734,7 +1734,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context const struct wined3d_vec4 correction_params = { /* Position is relative to the framebuffer, not the viewport. */ - context->render_offscreen ? 0.0f : (float)state->fb->render_targets[0]->height, + context->render_offscreen ? 0.0f : (float)state->fb.render_targets[0]->height, context->render_offscreen ? 1.0f : -1.0f, 0.0f, 0.0f, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 95db994ff30..41c48c0468b 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3904,7 +3904,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 unsigned int i;
memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ - if (!d3d_info->srgb_write_control && needs_srgb_write(d3d_info, state, state->fb)) + if (!d3d_info->srgb_write_control && needs_srgb_write(d3d_info, state, &state->fb)) { static unsigned int warned = 0;
@@ -4161,9 +4161,9 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] ? context->render_offscreen : 0;
- for (i = 0; i < ARRAY_SIZE(state->fb->render_targets); ++i) + for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i) { - struct wined3d_rendertarget_view *rtv = state->fb->render_targets[i]; + struct wined3d_rendertarget_view *rtv = state->fb.render_targets[i]; if (rtv && rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup)) args->rt_alpha_swizzle |= 1u << i; } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index b5d54db5b3b..d375122781b 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -236,7 +236,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
/* No z test without depth stencil buffers */ - if (!state->fb->depth_stencil) + if (!state->fb.depth_stencil) { TRACE("No Z buffer - disabling depth test\n"); zenable = WINED3D_ZB_FALSE; @@ -556,7 +556,7 @@ static BOOL is_blend_enabled(struct wined3d_context *context, const struct wined { const struct wined3d_blend_state *b = state->blend_state;
- if (!state->fb->render_targets[index]) + if (!state->fb.render_targets[index]) return FALSE;
if (!b->desc.rt[index].enable) @@ -566,7 +566,7 @@ static BOOL is_blend_enabled(struct wined3d_context *context, const struct wined * With blending on we could face a big performance penalty. * The d3d9 visual test confirms the behavior. */ if (context->render_offscreen - && !(state->fb->render_targets[index]->format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) + && !(state->fb.render_targets[index]->format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) return FALSE;
return TRUE; @@ -610,7 +610,7 @@ static void blend(struct wined3d_context *context, const struct wined3d_state *s gl_info->gl_ops.gl.p_glEnable(GL_BLEND); checkGLcall("glEnable GL_BLEND");
- rt_format = state->fb->render_targets[0]->format; + rt_format = state->fb.render_targets[0]->format;
gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.rt[0].src, b->desc.rt[0].dst, rt_format);
@@ -683,7 +683,7 @@ static void blend_db2(struct wined3d_context *context, const struct wined3d_stat return; }
- rt_format = state->fb->render_targets[0]->format; + rt_format = state->fb.render_targets[0]->format; gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.rt[0].src, b->desc.rt[0].dst, rt_format); gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, b->desc.rt[0].src_alpha, b->desc.rt[0].dst_alpha, rt_format);
@@ -766,7 +766,7 @@ static void blend_dbb(struct wined3d_context *context, const struct wined3d_stat GL_EXTCALL(glEnablei(GL_BLEND, i)); checkGLcall("glEnablei GL_BLEND");
- rt_format = state->fb->render_targets[i]->format; + rt_format = state->fb.render_targets[i]->format; gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.rt[i].src, b->desc.rt[i].dst, rt_format); gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, b->desc.rt[i].src_alpha, b->desc.rt[i].dst_alpha, rt_format); @@ -1061,7 +1061,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ GLint depthFail_back;
/* No stencil test without a stencil buffer. */ - if (!state->fb->depth_stencil) + if (!state->fb.depth_stencil) { gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); @@ -1075,7 +1075,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ if (!(func_back = wined3d_gl_compare_func(state->render_states[WINED3D_RS_BACK_STENCILFUNC]))) func_back = GL_ALWAYS; mask = state->render_states[WINED3D_RS_STENCILMASK]; - ref = state->render_states[WINED3D_RS_STENCILREF] & ((1 << state->fb->depth_stencil->format->stencil_size) - 1); + ref = state->render_states[WINED3D_RS_STENCILREF] & ((1 << state->fb.depth_stencil->format->stencil_size) - 1); stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]); depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]); stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]); @@ -1157,7 +1157,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
static void state_stencilwrite2s_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; + DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); @@ -1171,7 +1171,7 @@ static void state_stencilwrite2s_ext(struct wined3d_context *context, const stru
static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; + DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
gl_info->gl_ops.gl.p_glStencilMask(mask); @@ -1859,7 +1859,7 @@ static void depthbias(struct wined3d_context *context, const struct wined3d_stat
if (scale_bias || const_bias.f) { - const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; + const struct wined3d_rendertarget_view *depth = state->fb.depth_stencil; float factor, units, scale, clamp;
clamp = r ? r->desc.depth_bias_clamp : 0.0f; @@ -4092,8 +4092,8 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine static void get_viewports(struct wined3d_context *context, const struct wined3d_state *state, unsigned int viewport_count, struct wined3d_viewport *viewports) { - const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; - const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; + const struct wined3d_rendertarget_view *depth_stencil = state->fb.depth_stencil; + const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; unsigned int width, height, i;
for (i = 0; i < viewport_count; ++i) @@ -4342,7 +4342,7 @@ static void scissorrect(struct wined3d_context *context, const struct wined3d_st
if (!context->render_offscreen) { - const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; + const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; unsigned int width;
wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); @@ -4474,7 +4474,7 @@ void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
- if (needs_srgb_write(context->d3d_info, state, state->fb)) + if (needs_srgb_write(context->d3d_info, state, &state->fb)) gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); else gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index b6c3169c4c6..48d133485b8 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1851,13 +1851,11 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d state->streams[i].frequency = 1; }
-void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_d3d_info *d3d_info, DWORD flags) +void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, DWORD flags) { unsigned int i;
state->flags = flags; - state->fb = fb;
for (i = 0; i < LIGHTMAP_SIZE; i++) { diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index c5fd2879c05..e4cb5a27469 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -506,7 +506,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(swapchain); const struct wined3d_swapchain_desc *desc = &swapchain->state.desc; struct wined3d_texture *back_buffer = swapchain->back_buffers[0]; - const struct wined3d_fb_state *fb = &swapchain->device->cs->fb; + const struct wined3d_fb_state *fb = &swapchain->device->cs->state.fb; struct wined3d_rendertarget_view *dsv = fb->depth_stencil; struct wined3d_texture *logo_texture, *cursor_texture; const struct wined3d_gl_info *gl_info; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index f3ed3b3cec5..7b08851fbf9 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5493,7 +5493,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w float y_offset = flip ? (center_offset - (2.0f * y) - h) / h : (center_offset - (2.0f * y) - h) / -h; - enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? + enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; float z_scale = zenable ? clip_control ? 1.0f : 2.0f : 0.0f; float z_offset = zenable ? clip_control ? 0.0f : -1.0f : 0.0f; @@ -6236,7 +6236,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d break; } } - settings->sRGB_write = !d3d_info->srgb_write_control && needs_srgb_write(d3d_info, state, state->fb); + settings->sRGB_write = !d3d_info->srgb_write_control && needs_srgb_write(d3d_info, state, &state->fb); if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING] || !state->render_states[WINED3D_RS_CLIPPLANEENABLE]) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bb0551e2af0..e0e38ea660d 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3184,7 +3184,7 @@ struct wined3d_light_state struct wined3d_state { DWORD flags; - const struct wined3d_fb_state *fb; + struct wined3d_fb_state fb;
struct wined3d_vertex_declaration *vertex_declaration; struct wined3d_stream_output stream_output[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; @@ -3301,7 +3301,6 @@ struct wined3d_device struct wine_rb_tree samplers, rasterizer_states, blend_states;
/* Render Target Support */ - struct wined3d_fb_state fb; struct wined3d_rendertarget_view *auto_depth_stencil_view;
/* Cursor management */ @@ -3989,8 +3988,7 @@ HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, DWORD l const struct wined3d_light *params, struct wined3d_light_info **light_info) DECLSPEC_HIDDEN;
void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; -void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; +void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN;
enum wined3d_cs_queue_id @@ -4033,7 +4031,6 @@ struct wined3d_cs { const struct wined3d_cs_ops *ops; struct wined3d_device *device; - struct wined3d_fb_state fb; struct wined3d_state state; HMODULE wined3d_module; HANDLE thread; @@ -5304,12 +5301,12 @@ static inline BOOL wined3d_dsv_srv_conflict(const struct wined3d_rendertarget_vi static inline BOOL wined3d_resource_check_fbo_attached(const struct wined3d_state *state, const struct wined3d_resource *resource, const struct wined3d_format *srv_format) { - struct wined3d_rendertarget_view * const *rts = &state->fb->render_targets[0]; + struct wined3d_rendertarget_view * const *rts = &state->fb.render_targets[0]; const struct wined3d_rendertarget_view *dsv; unsigned int i;
if ((resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL) - && (dsv = state->fb->depth_stencil) && dsv->resource == resource + && (dsv = state->fb.depth_stencil) && dsv->resource == resource && wined3d_dsv_srv_conflict(dsv, srv_format)) return TRUE;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/device.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 41554b93cfa..f8caa0c23c6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -525,11 +525,11 @@ static void device_leftover_rasterizer_state(struct wine_rb_entry *entry, void * ERR("Leftover rasterizer state %p.\n", state); }
-static void device_free_blend_state(struct wine_rb_entry *entry, void *context) +static void device_leftover_blend_state(struct wine_rb_entry *entry, void *context) { - struct wined3d_blend_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry); + struct wined3d_blend_state *blend_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry);
- wined3d_blend_state_decref(state); + ERR("Leftover blend state %p.\n", blend_state); }
void wined3d_device_cleanup(struct wined3d_device *device) @@ -539,8 +539,6 @@ void wined3d_device_cleanup(struct wined3d_device *device) if (device->swapchain_count) wined3d_device_uninit_3d(device);
- wine_rb_destroy(&device->blend_states, device_free_blend_state, NULL); - wined3d_cs_destroy(device->cs);
for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i) @@ -570,6 +568,7 @@ void wined3d_device_cleanup(struct wined3d_device *device)
wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL); wine_rb_destroy(&device->rasterizer_states, device_leftover_rasterizer_state, NULL); + wine_rb_destroy(&device->blend_states, device_leftover_blend_state, NULL);
wined3d_decref(device->wined3d); device->wined3d = NULL; @@ -1118,6 +1117,13 @@ static void device_free_rasterizer_state(struct wine_rb_entry *entry, void *cont wined3d_rasterizer_state_decref(state); }
+static void device_free_blend_state(struct wine_rb_entry *entry, void *context) +{ + struct wined3d_blend_state *blend_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry); + + wined3d_blend_state_decref(blend_state); +} + void wined3d_device_uninit_3d(struct wined3d_device *device) { BOOL no3d = device->wined3d->flags & WINED3D_NO3D; @@ -1159,6 +1165,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wine_rb_clear(&device->samplers, device_free_sampler, NULL); wine_rb_clear(&device->rasterizer_states, device_free_rasterizer_state, NULL); + wine_rb_clear(&device->blend_states, device_free_blend_state, NULL);
LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) { @@ -5336,6 +5343,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
wine_rb_clear(&device->samplers, device_free_sampler, NULL); wine_rb_clear(&device->rasterizer_states, device_free_rasterizer_state, NULL); + wine_rb_clear(&device->blend_states, device_free_blend_state, NULL);
if (reset_state) {
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/adapter_gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index e269bf81381..0d51f584ce4 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -3422,7 +3422,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, {ARB_STENCIL_TEXTURING, MAKEDWORD_VERSION(4, 3)}, {ARB_TEXTURE_BUFFER_RANGE, MAKEDWORD_VERSION(4, 3)}, {ARB_TEXTURE_QUERY_LEVELS, MAKEDWORD_VERSION(4, 3)}, - {ARB_TEXTURE_STORAGE_MULTISAMPLE, MAKEDWORD_VERSION(4, 2)}, + {ARB_TEXTURE_STORAGE_MULTISAMPLE, MAKEDWORD_VERSION(4, 3)}, {ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)},
{ARB_BUFFER_STORAGE, MAKEDWORD_VERSION(4, 4)},
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- It's not just a performance improvement, it's actually a bugfix for some glitches I was getting with a Unity game (although I imagine it's probably hard-to-impossible to reproduce in practice without the buffer map optimizations).
What happened is that the game DISCARD maps the index buffer, then makes a bunch of non-indexed draws but still with the currently-mapped buffer set as index buffer, then eventually updates and unmaps the buffer and makes use of it in a draw. So it's important not to upload the buffer before it's actually needed. --- dlls/wined3d/context.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index c6a1d762673..2e363fb1d65 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -4225,7 +4225,7 @@ static void context_load_stream_output_buffers(struct wined3d_context *context,
/* Context activation is done by the caller. */ static BOOL context_apply_draw_state(struct wined3d_context *context, - const struct wined3d_device *device, const struct wined3d_state *state) + const struct wined3d_device *device, const struct wined3d_state *state, BOOL indexed) { const struct wined3d_state_entry *state_table = context->state_table; struct wined3d_context_gl *context_gl = wined3d_context_gl(context); @@ -4277,7 +4277,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, if (isStateDirty(context, STATE_STREAMSRC)) context_update_stream_info(context, state); } - if (state->index_buffer) + if (indexed && state->index_buffer) { if (context->stream_info.all_vbo) wined3d_buffer_load(state->index_buffer, context, state); @@ -5194,7 +5194,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (parameters->indirect) wined3d_buffer_load(parameters->u.indirect.buffer, context, state);
- if (!context_apply_draw_state(context, device, state)) + if (!context_apply_draw_state(context, device, state, parameters->indexed)) { context_release(context); WARN("Unable to apply draw state, skipping draw.\n");
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/buffer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 427b1a26493..dffa703dcc1 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -144,6 +144,8 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu { const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_resource *resource = &buffer_gl->b.resource; + struct wined3d_buffer *buffer = &buffer_gl->b; + struct wined3d_cs *cs = resource->device->cs; GLuint bo;
if (!buffer_gl->b.buffer_object) @@ -158,7 +160,8 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu { if (resource->bind_flags & WINED3D_BIND_VERTEX_BUFFER) device_invalidate_state(resource->device, STATE_STREAMSRC); - if (resource->bind_flags & WINED3D_BIND_INDEX_BUFFER) + if (resource->bind_flags & WINED3D_BIND_INDEX_BUFFER + && cs->state.index_buffer == buffer) device_invalidate_state(resource->device, STATE_INDEXBUFFER); if (resource->bind_flags & WINED3D_BIND_CONSTANT_BUFFER) {
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com