Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Version 2: * Use int for signed integers * Remove sqrtf(m *m) * Increase tolerance for floating-point slope scaled depth bias test to 140
--- dlls/d3d11/tests/d3d11.c | 315 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 298 insertions(+), 17 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 7d317dc1817c..bf62b48b8730 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -19,12 +19,13 @@
#include <assert.h> #include <float.h> +#include <limits.h> +#include <math.h> #include <stdlib.h> #define COBJMACROS #include "initguid.h" #include "d3d11_1.h" #include "wine/test.h" -#include <limits.h>
#ifndef ARRAY_SIZE #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) @@ -1247,14 +1248,14 @@ static void draw_quad_vs(unsigned int line, struct d3d11_test_context *context, { static const D3D11_INPUT_ELEMENT_DESC default_layout_desc[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; - static const struct vec2 quad[] = + static const struct vec3 quad[] = { - {-1.0f, -1.0f}, - {-1.0f, 1.0f}, - { 1.0f, -1.0f}, - { 1.0f, 1.0f}, + {-1.0f, -1.0f, 0.0f}, + {-1.0f, 1.0f, 0.0f}, + { 1.0f, -1.0f, 0.0f}, + { 1.0f, 1.0f, 0.0f}, };
ID3D11Device *device = context->device; @@ -15235,12 +15236,12 @@ static void test_face_culling(void) 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x00004002, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x0100003e, }; - static const struct vec2 ccw_quad[] = + static const struct vec3 ccw_quad[] = { - {-1.0f, 1.0f}, - {-1.0f, -1.0f}, - { 1.0f, 1.0f}, - { 1.0f, -1.0f}, + {-1.0f, 1.0f, 0.0f}, + {-1.0f, -1.0f, 0.0f}, + { 1.0f, 1.0f, 0.0f}, + { 1.0f, -1.0f, 0.0f}, }; static const struct { @@ -16115,12 +16116,12 @@ static void test_stencil_separate(void)
static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f}; static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f}; - static const struct vec2 ccw_quad[] = + static const struct vec3 ccw_quad[] = { - {-1.0f, -1.0f}, - { 1.0f, -1.0f}, - {-1.0f, 1.0f}, - { 1.0f, 1.0f}, + {-1.0f, -1.0f, 0.0f}, + { 1.0f, -1.0f, 0.0f}, + {-1.0f, 1.0f, 0.0f}, + { 1.0f, 1.0f, 0.0f}, };
if (!init_test_context(&test_context, NULL)) @@ -22134,6 +22135,285 @@ static void test_gather_c(void) release_test_context(&test_context); }
+static void test_depth_bias(void) +{ + struct vec3 vertices[] = + { + {-1.0f, -1.0f, 0.5f}, + {-1.0f, 1.0f, 0.5f}, + { 1.0f, -1.0f, 0.5f}, + { 1.0f, 1.0f, 0.5f}, + }; + struct d3d11_test_context test_context; + D3D11_RASTERIZER_DESC rasterizer_desc; + D3D11_TEXTURE2D_DESC texture_desc; + double m, r, bias, depth, data; + ID3D11DeviceContext *context; + struct resource_readback rb; + ID3D11DepthStencilView *dsv; + unsigned int expected_value; + ID3D11RasterizerState *rs; + ID3D11Texture2D *texture; + float depth_values[480]; + unsigned int format_idx; + unsigned int x, y, i, j; + unsigned int shift = 0; + ID3D11Device *device; + DXGI_FORMAT format; + const UINT32 *u32; + const UINT16 *u16; + UINT32 u32_value; + HRESULT hr; + + static const struct + { + float z; + float exponent; + } + quads[] = + { + {0.125f, -3.0f}, + {0.250f, -2.0f}, + {0.500f, -1.0f}, + {1.000f, 0.0f}, + }; + static const int bias_tests[] = + { + -10000, -1000, -100, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100, 200, 500, 1000, 10000, + }; + static const float quad_slopes[] = + { + 0.0f, 0.5f, 1.0f + }; + static const float slope_scaled_bias_tests[] = + { + 0.0f, 0.5f, 1.0f, 2.0f, 128.0f, 1000.0f, 10000.0f, + }; + static const DXGI_FORMAT formats[] = + { + DXGI_FORMAT_D32_FLOAT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_D16_UNORM, + }; + + if (!init_test_context(&test_context, NULL)) + return; + + device = test_context.device; + context = test_context.immediate_context; + + memset(&rasterizer_desc, 0, sizeof(rasterizer_desc)); + rasterizer_desc.FillMode = D3D11_FILL_SOLID; + rasterizer_desc.CullMode = D3D11_CULL_NONE; + rasterizer_desc.FrontCounterClockwise = FALSE; + rasterizer_desc.DepthBias = 0; + rasterizer_desc.DepthBiasClamp = 0.0f; + rasterizer_desc.SlopeScaledDepthBias = 0.0f; + rasterizer_desc.DepthClipEnable = TRUE; + + for (format_idx = 0; format_idx < ARRAY_SIZE(formats); ++format_idx) + { + format = formats[format_idx]; + + ID3D11Texture2D_GetDesc(test_context.backbuffer, &texture_desc); + texture_desc.Format = format; + texture_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &texture); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + hr = ID3D11Device_CreateDepthStencilView(device, (ID3D11Resource *)texture, NULL, &dsv); + ok(SUCCEEDED(hr), "Failed to create render depth stencil view, hr %#x.\n", hr); + ID3D11DeviceContext_OMSetRenderTargets(context, 1, &test_context.backbuffer_rtv, dsv); + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); + draw_quad(&test_context); + switch (format) + { + case DXGI_FORMAT_D32_FLOAT: + check_texture_float(texture, 0.0f, 0); + break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + /* FIXME: Depth/stencil byte order is reversed in wined3d. */ + shift = get_texture_color(texture, 0, 0) == 0xffffff ? 0 : 8; + todo_wine + check_texture_color(texture, 0xffffff, 1); + break; + case DXGI_FORMAT_D16_UNORM: + get_texture_readback(texture, 0, &rb); + for (y = 0; y < texture_desc.Height; ++y) + { + for (x = 0; x < texture_desc.Width; ++x) + { + u16 = get_readback_data(&rb, x, y, sizeof(*u16)); + ok(*u16 == 0xffff, "Got unexpected value %#x.\n", *u16); + } + } + release_resource_readback(&rb); + break; + default: + trace("Unhandled format %#x.\n", format); + break; + } + + /* DepthBias */ + for (i = 0; i < ARRAY_SIZE(quads); ++i) + { + for (j = 0; j < ARRAY_SIZE(vertices); ++j) + vertices[j].z = quads[i].z; + ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)test_context.vb, + 0, NULL, vertices, 0, 0); + + for (j = 0; j < ARRAY_SIZE(bias_tests); ++j) + { + rasterizer_desc.DepthBias = bias_tests[j]; + ID3D11Device_CreateRasterizerState(device, &rasterizer_desc, &rs); + ok(SUCCEEDED(hr), "Failed to create rasterizer state, hr %#x.\n", hr); + ID3D11DeviceContext_RSSetState(context, rs); + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 1.0f, 0); + draw_quad(&test_context); + switch (format) + { + case DXGI_FORMAT_D32_FLOAT: + bias = rasterizer_desc.DepthBias * pow(2.0f, quads[i].exponent - 23.0f); + depth = min(max(0.0f, quads[i].z + bias), 1.0f); + + check_texture_float(texture, depth, 2); + break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + r = 1.0f / 16777215.0f; + bias = rasterizer_desc.DepthBias * r; + depth = min(max(0.0f, quads[i].z + bias), 1.0f); + + get_texture_readback(texture, 0, &rb); + for (y = 0; y < texture_desc.Height; ++y) + { + expected_value = depth * 16777215.0f + 0.5f; + for (x = 0; x < texture_desc.Width; ++x) + { + u32 = get_readback_data(&rb, x, y, sizeof(*u32)); + u32_value = *u32 >> shift; + ok(abs(u32_value - expected_value) <= 1, + "Got value %#x (%.8e), expected %#x (%.8e).\n", + u32_value, u32_value / 16777215.0f, + expected_value, expected_value / 16777215.0f); + } + } + release_resource_readback(&rb); + break; + case DXGI_FORMAT_D16_UNORM: + r = 1.0f / 65535.0f; + bias = rasterizer_desc.DepthBias * r; + depth = min(max(0.0f, quads[i].z + bias), 1.0f); + + get_texture_readback(texture, 0, &rb); + for (y = 0; y < texture_desc.Height; ++y) + { + expected_value = depth * 65535.0f + 0.5f; + for (x = 0; x < texture_desc.Width; ++x) + { + u16 = get_readback_data(&rb, x, y, sizeof(*u16)); + ok(abs(*u16 - expected_value) <= 1, + "Got value %#x (%.8e), expected %#x (%.8e).\n", + *u16, *u16 / 65535.0f, expected_value, expected_value / 65535.0f); + } + } + release_resource_readback(&rb); + break; + default: + break; + } + ID3D11RasterizerState_Release(rs); + } + } + + /* SlopeScaledDepthBias */ + rasterizer_desc.DepthBias = 0; + for (i = 0; i < ARRAY_SIZE(quad_slopes); ++i) + { + for (j = 0; j < ARRAY_SIZE(vertices); ++j) + vertices[j].z = j == 1 || j == 3 ? 0.0f : quad_slopes[i]; + ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)test_context.vb, + 0, NULL, vertices, 0, 0); + + ID3D11DeviceContext_RSSetState(context, NULL); + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 1.0f, 0); + draw_quad(&test_context); + get_texture_readback(texture, 0, &rb); + for (y = 0; y < texture_desc.Height; ++y) + { + switch (format) + { + case DXGI_FORMAT_D32_FLOAT: + depth_values[y] = get_readback_float(&rb, 0, y); + break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + u32 = get_readback_data(&rb, 0, y, sizeof(*u32)); + u32_value = *u32 >> shift; + depth_values[y] = u32_value / 16777215.0f; + break; + case DXGI_FORMAT_D16_UNORM: + u16 = get_readback_data(&rb, 0, y, sizeof(*u16)); + depth_values[y] = *u16 / 65535.0f; + break; + default: + break; + } + } + release_resource_readback(&rb); + + for (j = 0; j < ARRAY_SIZE(slope_scaled_bias_tests); ++j) + { + rasterizer_desc.SlopeScaledDepthBias = slope_scaled_bias_tests[j]; + ID3D11Device_CreateRasterizerState(device, &rasterizer_desc, &rs); + ok(SUCCEEDED(hr), "Failed to create rasterizer state, hr %#x.\n", hr); + ID3D11DeviceContext_RSSetState(context, rs); + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 1.0f, 0); + draw_quad(&test_context); + + m = quad_slopes[i] / texture_desc.Height; + bias = rasterizer_desc.SlopeScaledDepthBias * m; + get_texture_readback(texture, 0, &rb); + for (y = 0; y < texture_desc.Height; ++y) + { + depth = min(max(0.0f, depth_values[y] + bias), 1.0f); + switch (format) + { + case DXGI_FORMAT_D32_FLOAT: + data = get_readback_float(&rb, 0, y); + ok(compare_float(data, depth, 140), + "Got depth %.8e, expected %.8e.\n", data, depth); + break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + u32 = get_readback_data(&rb, 0, y, sizeof(*u32)); + u32_value = *u32 >> shift; + expected_value = depth * 16777215.0f + 0.5f; + ok(abs(u32_value - expected_value) <= 3, + "Got value %#x (%.8e), expected %#x (%.8e).\n", + u32_value, u32_value / 16777215.0f, + expected_value, expected_value / 16777215.0f); + break; + case DXGI_FORMAT_D16_UNORM: + u16 = get_readback_data(&rb, 0, y, sizeof(*u16)); + expected_value = depth * 65535.0f + 0.5f; + ok(abs(*u16 - expected_value) <= 1, + "Got value %#x (%.8e), expected %#x (%.8e).\n", + *u16, *u16 / 65535.0f, expected_value, expected_value / 65535.0f); + break; + default: + break; + } + } + release_resource_readback(&rb); + ID3D11RasterizerState_Release(rs); + } + } + + ID3D11Texture2D_Release(texture); + ID3D11DepthStencilView_Release(dsv); + } + + release_test_context(&test_context); +} + static void test_fractional_viewports(void) { struct d3d11_test_context test_context; @@ -23591,6 +23871,7 @@ START_TEST(d3d11) test_stream_output_components(); test_gather(); test_gather_c(); + test_depth_bias(); test_fractional_viewports(); test_early_depth_stencil(); test_conservative_depth_output();
Makes the test much faster.
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Version 2: Set tolerance for floating-point slope scaled depth bias test to 64.
--- dlls/d3d11/tests/d3d11.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index bf62b48b8730..9a206dc39989 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -92,7 +92,8 @@ struct device_desc struct swapchain_desc { BOOL windowed; - UINT buffer_count; + unsigned buffer_count; + unsigned int width, height; DXGI_SWAP_EFFECT swap_effect; DWORD flags; }; @@ -1101,7 +1102,8 @@ static BOOL check_compute_shaders_via_sm4_support(ID3D11Device *device) return options.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; }
-static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window, const struct swapchain_desc *swapchain_desc) +static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window, + const struct swapchain_desc *swapchain_desc) { DXGI_SWAP_CHAIN_DESC dxgi_desc; IDXGISwapChain *swapchain; @@ -1140,6 +1142,10 @@ static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window, const dxgi_desc.Windowed = swapchain_desc->windowed; dxgi_desc.SwapEffect = swapchain_desc->swap_effect; dxgi_desc.BufferCount = swapchain_desc->buffer_count; + if (swapchain_desc->width) + dxgi_desc.BufferDesc.Width = swapchain_desc->width; + if (swapchain_desc->height) + dxgi_desc.BufferDesc.Height = swapchain_desc->height;
if (swapchain_desc->flags & SWAPCHAIN_FLAG_SHADER_INPUT) dxgi_desc.BufferUsage |= DXGI_USAGE_SHADER_INPUT; @@ -1170,10 +1176,12 @@ struct d3d11_test_context ID3D11Buffer *ps_cb; };
-#define init_test_context(c, l) init_test_context_(__LINE__, c, l) +#define init_test_context(a, b) init_test_context_(__LINE__, a, b, NULL) +#define init_test_context_ext(a, b, c) init_test_context_(__LINE__, a, b, c) static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *context, - const D3D_FEATURE_LEVEL *feature_level) + const D3D_FEATURE_LEVEL *feature_level, const struct swapchain_desc *swapchain_desc) { + unsigned int rt_width, rt_height; struct device_desc device_desc; D3D11_VIEWPORT vp; HRESULT hr; @@ -1188,11 +1196,14 @@ static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *con skip_(__FILE__, line)("Failed to create device.\n"); return FALSE; } - SetRect(&rect, 0, 0, 640, 480); + + rt_width = swapchain_desc && swapchain_desc->width ? swapchain_desc->width : 640; + rt_height = swapchain_desc && swapchain_desc->height ? swapchain_desc->height : 480; + SetRect(&rect, 0, 0, rt_width, rt_height); AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); context->window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); - context->swapchain = create_swapchain(context->device, context->window, NULL); + context->swapchain = create_swapchain(context->device, context->window, swapchain_desc); hr = IDXGISwapChain_GetBuffer(context->swapchain, 0, &IID_ID3D11Texture2D, (void **)&context->backbuffer); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
@@ -1206,8 +1217,8 @@ static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *con
vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; - vp.Width = 640.0f; - vp.Height = 480.0f; + vp.Width = rt_width; + vp.Height = rt_height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; ID3D11DeviceContext_RSSetViewports(context->immediate_context, 1, &vp); @@ -11106,6 +11117,7 @@ static void test_swapchain_flip(void) window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); desc.buffer_count = 3; + desc.width = desc.height = 0; desc.swap_effect = DXGI_SWAP_EFFECT_SEQUENTIAL; desc.windowed = TRUE; desc.flags = SWAPCHAIN_FLAG_SHADER_INPUT; @@ -22146,6 +22158,7 @@ static void test_depth_bias(void) }; struct d3d11_test_context test_context; D3D11_RASTERIZER_DESC rasterizer_desc; + struct swapchain_desc swapchain_desc; D3D11_TEXTURE2D_DESC texture_desc; double m, r, bias, depth, data; ID3D11DeviceContext *context; @@ -22154,11 +22167,11 @@ static void test_depth_bias(void) unsigned int expected_value; ID3D11RasterizerState *rs; ID3D11Texture2D *texture; - float depth_values[480]; unsigned int format_idx; unsigned int x, y, i, j; unsigned int shift = 0; ID3D11Device *device; + float *depth_values; DXGI_FORMAT format; const UINT32 *u32; const UINT16 *u16; @@ -22197,7 +22210,13 @@ static void test_depth_bias(void) DXGI_FORMAT_D16_UNORM, };
- if (!init_test_context(&test_context, NULL)) + swapchain_desc.windowed = TRUE; + swapchain_desc.buffer_count = 1; + swapchain_desc.width = 200; + swapchain_desc.height = 200; + swapchain_desc.swap_effect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.flags = 0; + if (!init_test_context_ext(&test_context, NULL, &swapchain_desc)) return;
device = test_context.device; @@ -22212,6 +22231,9 @@ static void test_depth_bias(void) rasterizer_desc.SlopeScaledDepthBias = 0.0f; rasterizer_desc.DepthClipEnable = TRUE;
+ depth_values = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*depth_values) * swapchain_desc.height); + ok(!!depth_values, "Failed to allocate memory.\n"); + for (format_idx = 0; format_idx < ARRAY_SIZE(formats); ++format_idx) { format = formats[format_idx]; @@ -22379,7 +22401,7 @@ static void test_depth_bias(void) { case DXGI_FORMAT_D32_FLOAT: data = get_readback_float(&rb, 0, y); - ok(compare_float(data, depth, 140), + ok(compare_float(data, depth, 64), "Got depth %.8e, expected %.8e.\n", data, depth); break; case DXGI_FORMAT_D24_UNORM_S8_UINT: @@ -22411,6 +22433,7 @@ static void test_depth_bias(void) ID3D11DepthStencilView_Release(dsv); }
+ HeapFree(GetProcessHeap(), 0, depth_values); release_test_context(&test_context); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com