Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3d10core/tests/d3d10core.c | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/dlls/d3d10core/tests/d3d10core.c b/dlls/d3d10core/tests/d3d10core.c index b92448ba932..4bbfc494d47 100644 --- a/dlls/d3d10core/tests/d3d10core.c +++ b/dlls/d3d10core/tests/d3d10core.c @@ -19482,6 +19482,71 @@ static void test_rtv_depth_slice(void) release_test_context(&test_context); }
+/* This is a regression test for a rather specific code path, triggered by + * SnowRunner. + * + * When a DSV is written to with a depth/stencil state that only writes stencil, + * we need to ensure that locations other than the draw binding are invalidated. + * In particular, if the texture was previously in CLEARED, that must be + * invalidated. + */ +static void test_stencil_only_write_after_clear(void) +{ + static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f}; + static const struct vec4 red = {1.0f, 0.0f, 0.0f, 1.0f}; + struct d3d10core_test_context test_context; + ID3D10DepthStencilState *ds_state; + D3D10_TEXTURE2D_DESC texture_desc; + ID3D10DepthStencilView *dsv; + ID3D10Texture2D *ds_texture; + ID3D10Device *device; + HRESULT hr; + + static const struct D3D10_DEPTH_STENCIL_DESC ds_desc = + { + .DepthEnable = FALSE, + .StencilEnable = TRUE, + .StencilReadMask = 0xff, + .StencilWriteMask = 0xff, + .FrontFace.StencilFunc = D3D10_COMPARISON_NOT_EQUAL, + .FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE, + .FrontFace.StencilFailOp = D3D10_STENCIL_OP_REPLACE, + .FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_REPLACE, + .BackFace.StencilFunc = D3D10_COMPARISON_NOT_EQUAL, + .BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE, + .BackFace.StencilFailOp = D3D10_STENCIL_OP_REPLACE, + .BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_REPLACE, + }; + + if (!init_test_context(&test_context)) + return; + device = test_context.device; + + ID3D10Texture2D_GetDesc(test_context.backbuffer, &texture_desc); + texture_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + texture_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL; + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &ds_texture); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = ID3D10Device_CreateDepthStencilView(device, (ID3D10Resource *)ds_texture, NULL, &dsv); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = ID3D10Device_CreateDepthStencilState(device, &ds_desc, &ds_state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ID3D10Device_OMSetDepthStencilState(device, ds_state, 0xff); + ID3D10Device_OMSetRenderTargets(device, 1, &test_context.backbuffer_rtv, dsv); + + ID3D10Device_ClearDepthStencilView(device, dsv, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); + draw_color_quad(&test_context, &green); + draw_color_quad(&test_context, &red); + check_texture_color(test_context.backbuffer, 0xff00ff00, 0); + + ID3D10Texture2D_Release(ds_texture); + ID3D10DepthStencilView_Release(dsv); + ID3D10DepthStencilState_Release(ds_state); + release_test_context(&test_context); +} + START_TEST(d3d10core) { unsigned int argc, i; @@ -19614,6 +19679,7 @@ START_TEST(d3d10core) queue_test(test_texture_compressed_3d); queue_test(test_dynamic_map_synchronization); queue_test(test_rtv_depth_slice); + queue_test(test_stencil_only_write_after_clear);
run_queued_tests();
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/context_gl.c | 2 +- dlls/wined3d/context_vk.c | 2 +- dlls/wined3d/state.c | 7 +++++++ dlls/wined3d/wined3d_private.h | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index b9964b1fd86..721ffdc3c09 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -5172,7 +5172,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s return; }
- if (dsv && (!state->depth_stencil_state || state->depth_stencil_state->desc.depth_write)) + if (dsv && (!state->depth_stencil_state || state->depth_stencil_state->writes_ds)) { DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index c257b5f3c86..a9b875a132e 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -3455,7 +3455,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c wined3d_rendertarget_view_prepare_location(dsv, &context_vk->c, dsv->resource->draw_binding); }
- if (!state->depth_stencil_state || state->depth_stencil_state->desc.depth_write) + if (!state->depth_stencil_state || state->depth_stencil_state->writes_ds) invalidate_ds = true;
sample_count = max(1, wined3d_resource_get_sample_count(dsv->resource)); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 56fd759e5e2..228b4901c00 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -146,6 +146,11 @@ void * CDECL wined3d_depth_stencil_state_get_parent(const struct wined3d_depth_s return state->parent; }
+static bool depth_stencil_state_desc_writes_ds(const struct wined3d_depth_stencil_state_desc *desc) +{ + return desc->depth_write; +} + HRESULT CDECL wined3d_depth_stencil_state_create(struct wined3d_device *device, const struct wined3d_depth_stencil_state_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_depth_stencil_state **state) @@ -164,6 +169,8 @@ HRESULT CDECL wined3d_depth_stencil_state_create(struct wined3d_device *device, object->parent_ops = parent_ops; object->device = device;
+ object->writes_ds = depth_stencil_state_desc_writes_ds(desc); + TRACE("Created depth/stencil state %p.\n", object); *state = object;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c1ec05a28c6..affef24d353 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3779,6 +3779,8 @@ struct wined3d_depth_stencil_state LONG refcount; struct wined3d_depth_stencil_state_desc desc;
+ bool writes_ds; + void *parent; const struct wined3d_parent_ops *parent_ops;
This allows menu items to be rendered in Snowrunner.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- The mentioned graphical error is probably a regression caused by the recent clear patches, but I haven't verified that.
dlls/wined3d/state.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 228b4901c00..a732182d6c5 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -146,9 +146,25 @@ void * CDECL wined3d_depth_stencil_state_get_parent(const struct wined3d_depth_s return state->parent; }
+static bool stencil_op_writes_ds(const struct wined3d_stencil_op_desc *desc) +{ + return desc->fail_op != WINED3D_STENCIL_OP_KEEP + || desc->depth_fail_op != WINED3D_STENCIL_OP_KEEP + || desc->pass_op != WINED3D_STENCIL_OP_KEEP; +} + static bool depth_stencil_state_desc_writes_ds(const struct wined3d_depth_stencil_state_desc *desc) { - return desc->depth_write; + if (desc->depth_write) + return true; + + if (desc->stencil && desc->stencil_write_mask) + { + if (stencil_op_writes_ds(&desc->front) || stencil_op_writes_ds(&desc->back)) + return true; + } + + return false; }
HRESULT CDECL wined3d_depth_stencil_state_create(struct wined3d_device *device,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index a732182d6c5..ee3e083e812 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -155,7 +155,7 @@ static bool stencil_op_writes_ds(const struct wined3d_stencil_op_desc *desc)
static bool depth_stencil_state_desc_writes_ds(const struct wined3d_depth_stencil_state_desc *desc) { - if (desc->depth_write) + if (desc->depth && desc->depth_write) return true;
if (desc->stencil && desc->stencil_write_mask)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116125
Your paranoid android.
=== w10pro64 (64 bit report) ===
d3d10core: d3d10core.c:4676: Test failed: Got unexpected query result 0x0000000000000000.