From: Evan Tang etang@codeweavers.com
--- dlls/d3d11/tests/d3d11.c | 174 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index b144fb36aca..86ad973aa0d 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -35266,6 +35266,179 @@ static void test_keyed_mutex(void) ok(!ref, "got %ld.\n", ref); }
+static void test_clear_during_render(void) +{ + /* Quads only cover left half so we can see both drawn color on the left and clear color on the right. */ + static const struct vec3 depth_quarter_quad_data[] = + { + {-1.0f, -1.0f, 0.25f}, + {-1.0f, 1.0f, 0.25f}, + { 0.0f, -1.0f, 0.25f}, + { 0.0f, 1.0f, 0.25f}, + }; + static const struct vec3 depth_three_quarter_quad_data[] = + { + {-1.0f, -1.0f, 0.75f}, + {-1.0f, 1.0f, 0.75f}, + { 0.0f, -1.0f, 0.75f}, + { 0.0f, 1.0f, 0.75f}, + }; + static const struct vec4 draw_color_data = {1, 0, 0, 1}; + struct d3d11_test_context test_context; + struct resource_readback rb; + ID3D11DeviceContext *context; + ID3D11Device *device; + ID3D11Texture2D *tex, *dstex; + ID3D11DepthStencilView *dsv; + ID3D11RenderTargetView *rtv; + ID3D11DepthStencilState *depth_none, *depth_ge, *depth_write_ge; + ID3D11Buffer *depth_quarter_quad, *depth_three_quarter_quad, *draw_color; + D3D11_DEPTH_STENCIL_DESC depth_stencil_desc; + D3D11_TEXTURE2D_DESC texture_desc; + HRESULT hr; + unsigned int test; + + if (!init_test_context(&test_context, NULL)) + return; + + device = test_context.device; + context = test_context.immediate_context; + depth_quarter_quad = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, sizeof(depth_quarter_quad_data), &depth_quarter_quad_data); + depth_three_quarter_quad = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, sizeof(depth_three_quarter_quad_data), &depth_three_quarter_quad_data); + draw_color = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER, sizeof(draw_color_data), &draw_color_data); + + memset(&depth_stencil_desc, 0, sizeof(depth_stencil_desc)); + hr = ID3D11Device_CreateDepthStencilState(device, &depth_stencil_desc, &depth_none); + ok(hr == S_OK, "Failed to create depth none dss: %#lx.\n", hr); + depth_stencil_desc.DepthEnable = TRUE; + depth_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depth_stencil_desc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depth_stencil_desc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; + hr = ID3D11Device_CreateDepthStencilState(device, &depth_stencil_desc, &depth_write_ge); + ok(hr == S_OK, "Failed to create depth write ge dss: %#lx.\n", hr); + depth_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + hr = ID3D11Device_CreateDepthStencilState(device, &depth_stencil_desc, &depth_ge); + ok(hr == S_OK, "Failed to create depth ge dss: %#lx.\n", hr); + + memset(&texture_desc, 0, sizeof(texture_desc)); + texture_desc.Width = 2; + texture_desc.Height = 1; + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.Usage = D3D11_USAGE_DEFAULT; + texture_desc.BindFlags = D3D11_BIND_RENDER_TARGET; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &tex); + ok(hr == S_OK, "Failed to create color texture: %#lx.\n", hr); + texture_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + texture_desc.Format = DXGI_FORMAT_D32_FLOAT; + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &dstex); + ok(hr == S_OK, "Failed to create depth texture: %#lx.\n", hr); + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource*)tex, NULL, &rtv); + ok(hr == S_OK, "Failed to create rtv: %#lx.\n", hr); + hr = ID3D11Device_CreateDepthStencilView(device, (ID3D11Resource*)dstex, NULL, &dsv); + ok(hr == S_OK, "Failed to create dsv: %#lx.\n", hr); + + for (test = 0; test < 5; test++) + { + unsigned int i; + static const UINT vertex_stride = sizeof(depth_quarter_quad_data[0]); + static const UINT vertex_offset = 0; + static const struct vec4 initial_color = {0, 0, 0, 1}; + static const float clear_color[] = {0, 1, 0, 1}; + DWORD expected_color[] = {0xff000000, 0xff000000}; + float expected_depth[] = {0.5f, 0.5f}; + D3D11_VIEWPORT viewport = {0, 0, (float)texture_desc.Width, (float)texture_desc.Height, 0, 1}; + + ID3D11DeviceContext_RSSetViewports(context, 1, &viewport); + ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rtv, dsv); + ID3D11DeviceContext_OMSetDepthStencilState(context, depth_none, 0); + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 0.5f, 0); + draw_color_quad(&test_context, &initial_color); + + /* We can't use draw_color_quad in here because the buffer updates it does can suppress bugs. */ + switch (test) + { + case 0: + /* Nothing, verify initial values. */ + break; + case 1: + /* Draw with succeeding depth compare. */ + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 0.0f, 0); + ID3D11DeviceContext_OMSetDepthStencilState(context, depth_ge, 0); + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &depth_quarter_quad, &vertex_stride, &vertex_offset); + ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &draw_color); + ID3D11DeviceContext_Draw(context, 4, 0); + expected_color[0] = 0xff0000ff; + expected_depth[0] = expected_depth[1] = 0.0f; + break; + case 2: + /* Draw with failing depth compare. */ + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 1.0f, 0); + ID3D11DeviceContext_OMSetDepthStencilState(context, depth_ge, 0); + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &depth_three_quarter_quad, &vertex_stride, &vertex_offset); + ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &draw_color); + ID3D11DeviceContext_Draw(context, 4, 0); + expected_depth[0] = expected_depth[1] = 1.0f; + break; + case 3: + /* Draw with depth write. */ + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 0.0f, 0); + ID3D11DeviceContext_OMSetDepthStencilState(context, depth_write_ge, 0); + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &depth_quarter_quad, &vertex_stride, &vertex_offset); + ID3D11DeviceContext_PSSetShader(context, NULL, NULL, 0); + ID3D11DeviceContext_Draw(context, 4, 0); + expected_depth[0] = 0.25f; + expected_depth[1] = 0.0f; + break; + case 4: + /* Color write */ + ID3D11DeviceContext_ClearRenderTargetView(context, rtv, clear_color); + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &depth_quarter_quad, &vertex_stride, &vertex_offset); + ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &draw_color); + ID3D11DeviceContext_Draw(context, 4, 0); + expected_color[0] = 0xff0000ff; + expected_color[1] = 0xff00ff00; + break; + default: + break; + } + + get_texture_readback(tex, 0, &rb); + for (i = 0; i < ARRAY_SIZE(expected_color); i++) + { + DWORD color = get_readback_color(&rb, i, 0, 0); + todo_wine_if( + (damavand && (((test == 1 || test == 2) && i == 0) || (test == 4 && i == 1))) || + (!damavand && test == 3 && i == 0) /* Draw with no PS doesn't write color on D3D11 but does on OpenGL. */ + ) + ok(color == expected_color[i], "Test %d: Got unexpected color 0x%08lx instead of 0x%08lx at %u.\n", test, color, expected_color[i], i); + } + release_resource_readback(&rb); + get_texture_readback(dstex, 0, &rb); + for (i = 0; i < ARRAY_SIZE(expected_depth); i++) + { + float depth = get_readback_float(&rb, i, 0); + todo_wine_if(damavand && test == 3) + ok(depth == expected_depth[i], "Test %d: Got unexpected depth %.8e instead of %.8e at %u.\n", test, depth, expected_depth[i], i); + } + release_resource_readback(&rb); + } + + ID3D11Buffer_Release(depth_quarter_quad); + ID3D11Buffer_Release(depth_three_quarter_quad); + ID3D11Buffer_Release(draw_color); + ID3D11RenderTargetView_Release(rtv); + ID3D11DepthStencilView_Release(dsv); + ID3D11Texture2D_Release(tex); + ID3D11Texture2D_Release(dstex); + ID3D11DepthStencilState_Release(depth_none); + ID3D11DepthStencilState_Release(depth_ge); + ID3D11DepthStencilState_Release(depth_write_ge); + release_test_context(&test_context); +} + START_TEST(d3d11) { unsigned int argc, i; @@ -35462,6 +35635,7 @@ START_TEST(d3d11) queue_test(test_dxgi_resources); queue_for_each_feature_level(test_shared_resource); queue_test(test_keyed_mutex); + queue_test(test_clear_during_render);
run_queued_tests();