From: Józef Kucia jkucia@codeweavers.com
Avoids allocating system memory for depth/stencil and 3D textures.
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
It's a small step to reduce unncessary system memory allocations in wined3d. We shouldn't need to allocate system memory to initialize content for GPU resources, instead we should use glClearBuffer() and glClearTexImage().
--- dlls/wined3d/buffer.c | 6 +++--- dlls/wined3d/resource.c | 13 +++++-------- dlls/wined3d/texture.c | 17 ++++++++++------- 3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 5b924704dfff..3f4552f2bbe5 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -615,10 +615,7 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, return TRUE;
if (!wined3d_resource_allocate_sysmem(&buffer->resource)) - { - ERR("Failed to allocate system memory.\n"); return FALSE; - } return TRUE;
case WINED3D_LOCATION_BUFFER: @@ -1359,6 +1356,9 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device buffer->bind_flags = bind_flags; buffer->locations = WINED3D_LOCATION_SYSMEM;
+ if (!wined3d_resource_allocate_sysmem(&buffer->resource)) + return E_OUTOFMEMORY; + TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n", buffer, buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory); diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 2a6fa6ad7ec2..b5dcdf012db7 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -191,12 +191,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; resource->map_binding = WINED3D_LOCATION_SYSMEM; - - if (!wined3d_resource_allocate_sysmem(resource)) - { - ERR("Failed to allocate system memory.\n"); - return E_OUTOFMEMORY; - } + resource->heap_memory = NULL;
if (!(usage & WINED3DUSAGE_PRIVATE)) { @@ -205,8 +200,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * { if (size > wined3d_device_get_available_texture_mem(device)) { - ERR("Out of adapter memory\n"); - wined3d_resource_free_sysmem(resource); + ERR("Out of adapter memory.\n"); return WINED3DERR_OUTOFVIDEOMEMORY; } adapter_adjust_memory(device->adapter, size); @@ -383,7 +377,10 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) void *mem;
if (!(mem = heap_alloc_zero(resource->size + align))) + { + ERR("Failed to allocate system memory.\n"); return FALSE; + }
p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; *p = mem; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index b56e6e4e65e2..b9b304eb9ecd 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1683,10 +1683,7 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned return TRUE;
if (!wined3d_resource_allocate_sysmem(&texture->resource)) - { - ERR("Failed to allocate system memory.\n"); return FALSE; - } return TRUE;
case WINED3D_LOCATION_USER_MEMORY: @@ -2674,11 +2671,17 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
if (wined3d_texture_use_pbo(texture, gl_info)) - { - if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D - || (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) - wined3d_resource_free_sysmem(&texture->resource); texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + + if ((desc->resource_type != WINED3D_RTYPE_TEXTURE_3D + && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) + || !wined3d_texture_use_pbo(texture, gl_info)) + { + if (!wined3d_resource_allocate_sysmem(&texture->resource)) + { + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; + } }
sub_count = level_count * layer_count;
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 81 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 2f47124a2329..bff8b51ae73c 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -14017,6 +14017,7 @@ static void test_shader_interstage_interface(void) ID3D11Device *device; UINT stride, offset; ID3D11Buffer *vb; + unsigned int i; HRESULT hr;
static const DWORD vs_code[] = @@ -14089,6 +14090,56 @@ static void test_shader_interstage_interface(void) 0x0010000a, 0x00000000, 0x07000000, 0x00102012, 0x00000000, 0x0010101a, 0x00000001, 0x0010100a, 0x00000002, 0x05000036, 0x001020c2, 0x00000000, 0x001012a6, 0x00000001, 0x0100003e, }; + static const DWORD ps_partial_input_code[] = + { +#if 0 + void main(float4 position : SV_Position, float2 t0 : TEXCOORD0, + nointerpolation float t1 : TEXCOORD1, uint t2 : TEXCOORD2, + uint t3 : TEXCOORD3, out float4 o : SV_Target) + { + o.x = t0.y + t1; + o.y = t2 + t3; + o.z = 0.0f; + o.w = t0.x; + } +#endif + 0x43425844, 0x5b1db356, 0xaa5a5e9d, 0xb916a081, 0x61e6dcb1, 0x00000001, 0x000001cc, 0x00000003, + 0x0000002c, 0x000000cc, 0x00000100, 0x4e475349, 0x00000098, 0x00000005, 0x00000008, 0x00000080, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000008c, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000303, 0x0000008c, 0x00000001, 0x00000000, 0x00000003, 0x00000002, + 0x00000101, 0x0000008c, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000202, 0x0000008c, + 0x00000003, 0x00000000, 0x00000001, 0x00000002, 0x00000404, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000000c4, 0x00000040, 0x00000031, 0x03001062, 0x00101032, 0x00000001, 0x03000862, + 0x00101012, 0x00000002, 0x03000862, 0x00101022, 0x00000002, 0x03000862, 0x00101042, 0x00000002, + 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0700001e, 0x00100012, 0x00000000, + 0x0010102a, 0x00000002, 0x0010101a, 0x00000002, 0x05000056, 0x00102022, 0x00000000, 0x0010000a, + 0x00000000, 0x07000000, 0x00102012, 0x00000000, 0x0010101a, 0x00000001, 0x0010100a, 0x00000002, + 0x05000036, 0x00102042, 0x00000000, 0x00004001, 0x00000000, 0x05000036, 0x00102082, 0x00000000, + 0x0010100a, 0x00000001, 0x0100003e, + }; + static const DWORD ps_single_input_code[] = + { +#if 0 + void main(float4 position : SV_Position, float2 t0 : TEXCOORD0, out float4 o : SV_Target) + { + o.x = t0.x; + o.y = t0.y; + o.z = 1.0f; + o.w = 2.0f; + } +#endif + 0x43425844, 0x7cc601b6, 0xc65b8bdb, 0x54d0f606, 0x9cc74d3d, 0x00000001, 0x00000118, 0x00000003, + 0x0000002c, 0x00000084, 0x000000b8, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000303, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, + 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000058, + 0x00000040, 0x00000016, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x05000036, 0x00102032, 0x00000000, 0x00101046, 0x00000001, 0x08000036, 0x001020c2, 0x00000000, + 0x00004002, 0x00000000, 0x00000000, 0x3f800000, 0x40000000, 0x0100003e, + }; static const D3D11_INPUT_ELEMENT_DESC layout_desc[] = { {"SV_POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, @@ -14115,7 +14166,18 @@ static void test_shader_interstage_interface(void) {{ 1.0f, 1.0f}, {3.0f, 5.0f}, 5.0f, 2, 6, 7.0f}, }; static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; - static const struct vec4 expected_result = {10.0f, 8.0f, 7.0f, 3.0f}; + static const struct + { + const DWORD *ps_code; + size_t ps_size; + struct vec4 expected_result; + } + tests[] = + { + {ps_code, sizeof(ps_code), {10.0f, 8.0f, 7.0f, 3.0f}}, + {ps_partial_input_code, sizeof(ps_partial_input_code), {10.0f, 8.0f, 0.0f, 3.0f}}, + {ps_single_input_code, sizeof(ps_single_input_code), {3.0f, 5.0f, 1.0f, 2.0f}}, + };
if (!init_test_context(&test_context, NULL)) return; @@ -14125,8 +14187,6 @@ static void test_shader_interstage_interface(void)
hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs); ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); - ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
ID3D11Texture2D_GetDesc(test_context.backbuffer, &texture_desc); texture_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; @@ -14145,21 +14205,26 @@ static void test_shader_interstage_interface(void) ID3D11DeviceContext_ClearRenderTargetView(context, rtv, white);
ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rtv, NULL); - - ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); ID3D11DeviceContext_IASetInputLayout(context, input_layout); ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); offset = 0; stride = sizeof(*quad); ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &vb, &stride, &offset); - ID3D11DeviceContext_Draw(context, 4, 0); - check_texture_vec4(render_target, &expected_result, 0); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = ID3D11Device_CreatePixelShader(device, tests[i].ps_code, tests[i].ps_size, NULL, &ps); + ok(hr == S_OK, "Failed to create pixel shader, hr %#x.\n", hr); + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + ID3D11DeviceContext_Draw(context, 4, 0); + check_texture_vec4(render_target, &tests[i].expected_result, 0); + ID3D11PixelShader_Release(ps); + }
ID3D11InputLayout_Release(input_layout); ID3D11RenderTargetView_Release(rtv); ID3D11Texture2D_Release(render_target); - ID3D11PixelShader_Release(ps); ID3D11VertexShader_Release(vs); ID3D11Buffer_Release(vb); release_test_context(&test_context);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d10core/tests/device.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index 8b0567696c96..e9394db2b0e5 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -1003,12 +1003,14 @@ static BOOL is_d3d11_interface_available(ID3D10Device *device) struct swapchain_desc { BOOL windowed; - UINT buffer_count; + unsigned int buffer_count; + unsigned int width, height; DXGI_SWAP_EFFECT swap_effect; DWORD flags; };
-static IDXGISwapChain *create_swapchain(ID3D10Device *device, HWND window, const struct swapchain_desc *swapchain_desc) +static IDXGISwapChain *create_swapchain(ID3D10Device *device, HWND window, + const struct swapchain_desc *swapchain_desc) { IDXGISwapChain *swapchain; DXGI_SWAP_CHAIN_DESC dxgi_desc; @@ -1047,6 +1049,10 @@ static IDXGISwapChain *create_swapchain(ID3D10Device *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; @@ -1075,9 +1081,12 @@ struct d3d10core_test_context ID3D10Buffer *ps_cb; };
-#define init_test_context(c) init_test_context_(__LINE__, c) -static BOOL init_test_context_(unsigned int line, struct d3d10core_test_context *context) +#define init_test_context(a) init_test_context_(__LINE__, a, NULL) +#define init_test_context_ext(a, b) init_test_context_(__LINE__, a, b) +static BOOL init_test_context_(unsigned int line, struct d3d10core_test_context *context, + const struct swapchain_desc *swapchain_desc) { + unsigned int rt_width, rt_height; D3D10_VIEWPORT vp; HRESULT hr; RECT rect; @@ -1089,11 +1098,14 @@ static BOOL init_test_context_(unsigned int line, struct d3d10core_test_context 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", "d3d10core_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_ID3D10Texture2D, (void **)&context->backbuffer); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
@@ -1105,8 +1117,8 @@ static BOOL init_test_context_(unsigned int line, struct d3d10core_test_context
vp.TopLeftX = 0; vp.TopLeftY = 0; - vp.Width = 640; - vp.Height = 480; + vp.Width = rt_width; + vp.Height = rt_height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; ID3D10Device_RSSetViewports(context->device, 1, &vp); @@ -9861,6 +9873,7 @@ static void test_swapchain_flip(void) window = CreateWindowA("static", "d3d10core_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;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d10core/tests/device.c | 433 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 383 insertions(+), 50 deletions(-)
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index e9394db2b0e5..d64a892b4a1f 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -17,12 +17,13 @@ */
#include <assert.h> +#include <limits.h> +#include <math.h> #define COBJMACROS #include "initguid.h" #include "d3d11_4.h" #include "wine/heap.h" #include "wine/test.h" -#include <limits.h>
#ifndef ARRAY_SIZE #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) @@ -1075,6 +1076,8 @@ struct d3d10core_test_context
ID3D10InputLayout *input_layout; ID3D10VertexShader *vs; + const DWORD *vs_code; + ID3D10Buffer *vs_cb; ID3D10Buffer *vb;
ID3D10PixelShader *ps; @@ -1135,6 +1138,8 @@ static void release_test_context_(unsigned int line, struct d3d10core_test_conte ID3D10InputLayout_Release(context->input_layout); if (context->vs) ID3D10VertexShader_Release(context->vs); + if (context->vs_cb) + ID3D10Buffer_Release(context->vs_cb); if (context->vb) ID3D10Buffer_Release(context->vb); if (context->ps) @@ -1151,12 +1156,14 @@ static void release_test_context_(unsigned int line, struct d3d10core_test_conte ok_(__FILE__, line)(!ref, "Device has %u references left.\n", ref); }
-#define draw_quad(c) draw_quad_(__LINE__, c) -static void draw_quad_(unsigned int line, struct d3d10core_test_context *context) +#define draw_quad(context) draw_quad_vs_(__LINE__, context, NULL, 0) +#define draw_quad_vs(a, b, c) draw_quad_vs_(__LINE__, a, b, c) +static void draw_quad_vs_(unsigned int line, struct d3d10core_test_context *context, + const DWORD *vs_code, size_t vs_code_size) { static const D3D10_INPUT_ELEMENT_DESC default_layout_desc[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; static const DWORD default_vs_code[] = { @@ -1174,26 +1181,40 @@ static void draw_quad_(unsigned int line, struct d3d10core_test_context *context 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, }; - 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}, };
ID3D10Device *device = context->device; unsigned int stride, offset; HRESULT hr;
+ if (!vs_code) + { + vs_code = default_vs_code; + vs_code_size = sizeof(default_vs_code); + } + if (!context->input_layout) { hr = ID3D10Device_CreateInputLayout(device, default_layout_desc, ARRAY_SIZE(default_layout_desc), - default_vs_code, sizeof(default_vs_code), &context->input_layout); + vs_code, vs_code_size, &context->input_layout); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + } + + if (context->vs_code != vs_code) + { + if (context->vs) + ID3D10VertexShader_Release(context->vs);
- hr = ID3D10Device_CreateVertexShader(device, default_vs_code, sizeof(default_vs_code), &context->vs); - ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + hr = ID3D10Device_CreateVertexShader(device, vs_code, vs_code_size, &context->vs); + ok_(__FILE__, line)(hr == S_OK, "Failed to create vertex shader, hr %#x.\n", hr); + + context->vs_code = vs_code; }
if (!context->vb) @@ -1209,8 +1230,45 @@ static void draw_quad_(unsigned int line, struct d3d10core_test_context *context ID3D10Device_Draw(context->device, 4, 0); }
-#define draw_color_quad(c, color) draw_color_quad_(__LINE__, c, color) -static void draw_color_quad_(unsigned int line, struct d3d10core_test_context *context, const struct vec4 *color) +#define draw_quad_z(context, z) draw_quad_z_(__LINE__, context, z) +static void draw_quad_z_(unsigned int line, struct d3d10core_test_context *context, float z) +{ + static const DWORD vs_code[] = + { +#if 0 + float depth; + + void main(float4 in_position : POSITION, out float4 out_position : SV_Position) + { + out_position = in_position; + out_position.z = depth; + } +#endif + 0x43425844, 0x22d7ff76, 0xd53b167c, 0x1b49ccf1, 0xbebfec39, 0x00000001, 0x00000100, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000b0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x52444853, 0x00000064, 0x00010040, + 0x00000019, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005f, 0x001010b2, 0x00000000, + 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x05000036, 0x001020b2, 0x00000000, 0x00101c46, + 0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, + }; + + struct vec4 data = {z}; + + if (!context->vs_cb) + context->vs_cb = create_buffer(context->device, D3D10_BIND_CONSTANT_BUFFER, sizeof(data), NULL); + + ID3D10Device_UpdateSubresource(context->device, (ID3D10Resource *)context->vs_cb, 0, NULL, &data, 0, 0); + + ID3D10Device_VSSetConstantBuffers(context->device, 0, 1, &context->vs_cb); + draw_quad_vs_(__LINE__, context, vs_code, sizeof(vs_code)); +} + +#define draw_color_quad(a, b) draw_color_quad_(__LINE__, a, b, NULL, 0) +#define draw_color_quad_vs(a, b, c, d) draw_color_quad_(__LINE__, a, b, c, d) +static void draw_color_quad_(unsigned int line, struct d3d10core_test_context *context, + const struct vec4 *color, const DWORD *vs_code, unsigned int vs_code_size) { static const DWORD ps_color_code[] = { @@ -1247,7 +1305,7 @@ static void draw_color_quad_(unsigned int line, struct d3d10core_test_context *c
ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)context->ps_cb, 0, NULL, color, 0, 0);
- draw_quad_(line, context); + draw_quad_vs_(line, context, vs_code, vs_code_size); }
static void test_feature_level(void) @@ -9526,8 +9584,6 @@ float4 main(const ps_in v) : SV_TARGET colors_cb = create_buffer(device, D3D10_BIND_CONSTANT_BUFFER, sizeof(colors), &colors); index_cb = create_buffer(device, D3D10_BIND_CONSTANT_BUFFER, sizeof(index), NULL);
- hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &test_context.vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps); ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
@@ -9542,7 +9598,7 @@ float4 main(const ps_in v) : SV_TARGET index[0] = test_data[i].index; ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)index_cb, 0, NULL, index, 0, 0);
- draw_quad(&test_context); + draw_quad_vs(&test_context, vs_code, sizeof(vs_code)); color = get_texture_color(test_context.backbuffer, 319, 239); ok(compare_color(color, test_data[i].expected, 1), "Got unexpected color 0x%08x for index %d.\n", color, test_data[i].index); @@ -9650,9 +9706,6 @@ static void test_vs_input_relative_addressing(void) offset = 0; ID3D10Device_IASetVertexBuffers(device, 1, 1, &vb, &stride, &offset);
- hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &test_context.vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps); ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); ID3D10Device_PSSetShader(device, ps); @@ -9662,7 +9715,7 @@ static void test_vs_input_relative_addressing(void) *index = i; ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)cb, 0, NULL, index, 0, 0); ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_quad(&test_context); + draw_quad_vs(&test_context, vs_code, sizeof(vs_code)); check_texture_color(test_context.backbuffer, colors[i], 1); }
@@ -12045,12 +12098,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 { @@ -12680,12 +12733,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)) @@ -14284,6 +14337,295 @@ static void test_stream_output_resume(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 d3d10core_test_context test_context; + D3D10_RASTERIZER_DESC rasterizer_desc; + struct swapchain_desc swapchain_desc; + D3D10_TEXTURE2D_DESC texture_desc; + double m, r, bias, depth, data; + struct resource_readback rb; + ID3D10DepthStencilView *dsv; + unsigned int expected_value; + ID3D10RasterizerState *rs; + ID3D10Texture2D *texture; + unsigned int format_idx; + unsigned int x, y, i, j; + unsigned int shift = 0; + ID3D10Device *device; + float *depth_values; + 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, + }; + + 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, &swapchain_desc)) + return; + + device = test_context.device; + + memset(&rasterizer_desc, 0, sizeof(rasterizer_desc)); + rasterizer_desc.FillMode = D3D10_FILL_SOLID; + rasterizer_desc.CullMode = D3D10_CULL_NONE; + rasterizer_desc.FrontCounterClockwise = FALSE; + rasterizer_desc.DepthBias = 0; + rasterizer_desc.DepthBiasClamp = 0.0f; + rasterizer_desc.SlopeScaledDepthBias = 0.0f; + rasterizer_desc.DepthClipEnable = TRUE; + + depth_values = heap_calloc(swapchain_desc.height, sizeof(*depth_values)); + ok(!!depth_values, "Failed to allocate memory.\n"); + + for (format_idx = 0; format_idx < ARRAY_SIZE(formats); ++format_idx) + { + format = formats[format_idx]; + + ID3D10Texture2D_GetDesc(test_context.backbuffer, &texture_desc); + texture_desc.Format = format; + texture_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL; + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + hr = ID3D10Device_CreateDepthStencilView(device, (ID3D10Resource *)texture, NULL, &dsv); + ok(SUCCEEDED(hr), "Failed to create render depth stencil view, hr %#x.\n", hr); + ID3D10Device_OMSetRenderTargets(device, 1, &test_context.backbuffer_rtv, dsv); + ID3D10Device_ClearDepthStencilView(device, dsv, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); + draw_quad_z(&test_context, 1.0f); + switch (format) + { + case DXGI_FORMAT_D32_FLOAT: + check_texture_float(texture, 1.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; + } + draw_quad(&test_context); + + /* DepthBias */ + for (i = 0; i < ARRAY_SIZE(quads); ++i) + { + for (j = 0; j < ARRAY_SIZE(vertices); ++j) + vertices[j].z = quads[i].z; + ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)test_context.vb, + 0, NULL, vertices, 0, 0); + + for (j = 0; j < ARRAY_SIZE(bias_tests); ++j) + { + rasterizer_desc.DepthBias = bias_tests[j]; + ID3D10Device_CreateRasterizerState(device, &rasterizer_desc, &rs); + ok(SUCCEEDED(hr), "Failed to create rasterizer state, hr %#x.\n", hr); + ID3D10Device_RSSetState(device, rs); + ID3D10Device_ClearDepthStencilView(device, dsv, D3D10_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; + } + ID3D10RasterizerState_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]; + ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)test_context.vb, + 0, NULL, vertices, 0, 0); + + ID3D10Device_RSSetState(device, NULL); + ID3D10Device_ClearDepthStencilView(device, dsv, D3D10_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]; + ID3D10Device_CreateRasterizerState(device, &rasterizer_desc, &rs); + ok(SUCCEEDED(hr), "Failed to create rasterizer state, hr %#x.\n", hr); + ID3D10Device_RSSetState(device, rs); + ID3D10Device_ClearDepthStencilView(device, dsv, D3D10_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, 64), + "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); + ID3D10RasterizerState_Release(rs); + } + } + + ID3D10Texture2D_Release(texture); + ID3D10DepthStencilView_Release(dsv); + } + + heap_free(depth_values); + release_test_context(&test_context); +} + static void test_format_compatibility(void) { ID3D10Texture2D *dst_texture, *src_texture; @@ -14691,9 +15033,6 @@ static void test_clip_distance(void) offset = 0; ID3D10Device_IASetVertexBuffers(device, 1, 1, &vb, &stride, &offset);
- hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &test_context.vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - memset(&cb_data, 0, sizeof(cb_data)); cb_data.tessellation_factor = 1.0f; vs_cb = create_buffer(device, D3D10_BIND_CONSTANT_BUFFER, sizeof(cb_data), &cb_data); @@ -14703,7 +15042,7 @@ static void test_clip_distance(void)
/* vertex shader */ ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_code, sizeof(vs_code)); check_texture_color(test_context.backbuffer, 0xff00ff00, 1);
check_clip_distance(&test_context, vb); @@ -14729,10 +15068,6 @@ static void test_clip_distance(void) /* multiple clip distances */ ID3D10Device_GSSetShader(device, NULL);
- ID3D10VertexShader_Release(test_context.vs); - hr = ID3D10Device_CreateVertexShader(device, vs_multiple_code, sizeof(vs_multiple_code), &test_context.vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - cb_data.use_constant = FALSE; ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vs_cb, 0, NULL, &cb_data, 0, 0);
@@ -14740,7 +15075,7 @@ static void test_clip_distance(void) vertices[i].clip_distance0 = 1.0f; ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vb, 0, NULL, vertices, 0, 0); ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_multiple_code, sizeof(vs_multiple_code)); check_texture_color(test_context.backbuffer, 0xff00ff00, 1);
for (i = 0; i < ARRAY_SIZE(vertices); ++i) @@ -14750,7 +15085,7 @@ static void test_clip_distance(void) } ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vb, 0, NULL, vertices, 0, 0); ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_multiple_code, sizeof(vs_multiple_code)); get_texture_readback(test_context.backbuffer, 0, &rb); SetRect(&rect, 0, 0, 320, 240); check_readback_data_color(&rb, &rect, 0xff00ff00, 1); @@ -14765,7 +15100,7 @@ static void test_clip_distance(void) cb_data.clip_distance1 = 0.0f; ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vs_cb, 0, NULL, &cb_data, 0, 0); ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_multiple_code, sizeof(vs_multiple_code)); check_texture_color(test_context.backbuffer, 0xff00ff00, 1);
ID3D10GeometryShader_Release(gs); @@ -14913,11 +15248,8 @@ static void test_combined_clip_and_cull_distances(void) offset = 0; ID3D10Device_IASetVertexBuffers(device, 1, 1, &vb, &stride, &offset);
- hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &test_context.vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_code, sizeof(vs_code)); check_texture_color(test_context.backbuffer, 0xff00ff00, 1);
for (i = 0; i < ARRAY_SIZE(vertices->cull_distance); ++i) @@ -14933,7 +15265,7 @@ static void test_combined_clip_and_cull_distances(void) ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vb, 0, NULL, vertices, 0, 0);
ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_code, sizeof(vs_code));
for (k = 0; k < ARRAY_SIZE(expected_color); ++k) expected_color[k] = test->triangle_visible[k] ? 0xff00ff00 : 0xffffffff; @@ -14964,7 +15296,7 @@ static void test_combined_clip_and_cull_distances(void) ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vb, 0, NULL, vertices, 0, 0);
ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_code, sizeof(vs_code)); check_texture_color(test_context.backbuffer, 0xffffffff, 1);
for (j = 0; j < ARRAY_SIZE(vertices); ++j) @@ -14974,7 +15306,7 @@ static void test_combined_clip_and_cull_distances(void) memset(vertices, 0, sizeof(vertices)); ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)vb, 0, NULL, vertices, 0, 0); ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); - draw_color_quad(&test_context, &green); + draw_color_quad_vs(&test_context, &green, vs_code, sizeof(vs_code)); check_texture_color(test_context.backbuffer, 0xff00ff00, 1);
ID3D10Buffer_Release(vb); @@ -15757,6 +16089,7 @@ START_TEST(device) test_geometry_shader(); test_stream_output(); test_stream_output_resume(); + test_depth_bias(); test_format_compatibility(); test_clip_distance(); test_combined_clip_and_cull_distances();
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Unfortunately, the test may fail on Linux with some drivers, e.g. Nvidia Linux driver implements the negative viewport quirk also in OpenGL.
--- dlls/d3d11/tests/d3d11.c | 164 +++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 83 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index bff8b51ae73c..593573216294 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -629,6 +629,21 @@ static void check_uav_desc_(unsigned int line, const D3D11_UNORDERED_ACCESS_VIEW } }
+static void set_viewport(ID3D11DeviceContext *context, float x, float y, + float width, float height, float min_depth, float max_depth) +{ + D3D11_VIEWPORT vp; + + vp.TopLeftX = x; + vp.TopLeftY = y; + vp.Width = width; + vp.Height = height; + vp.MinDepth = min_depth; + vp.MaxDepth = max_depth; + + ID3D11DeviceContext_RSSetViewports(context, 1, &vp); +} + #define create_buffer(a, b, c, d) create_buffer_(__LINE__, a, b, 0, c, d) #define create_buffer_misc(a, b, c, d, e) create_buffer_(__LINE__, a, b, c, d, e) static ID3D11Buffer *create_buffer_(unsigned int line, ID3D11Device *device, @@ -1272,7 +1287,6 @@ static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *con { unsigned int rt_width, rt_height; struct device_desc device_desc; - D3D11_VIEWPORT vp; HRESULT hr; RECT rect;
@@ -1304,13 +1318,7 @@ static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *con
ID3D11DeviceContext_OMSetRenderTargets(context->immediate_context, 1, &context->backbuffer_rtv, NULL);
- vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = rt_width; - vp.Height = rt_height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context->immediate_context, 1, &vp); + set_viewport(context->immediate_context, 0.0f, 0.0f, rt_width, rt_height, 0.0f, 1.0f);
return TRUE; } @@ -5129,7 +5137,6 @@ static void test_occlusion_query(void) unsigned int data_size, i; ID3D11Texture2D *texture; ID3D11Device *device; - D3D11_VIEWPORT vp; union { UINT64 uint; @@ -5227,13 +5234,7 @@ static void test_occlusion_query(void) ok(SUCCEEDED(hr), "Failed to create render target view, hr %#x.\n", hr);
ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rtv, NULL); - vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = texture_desc.Width; - vp.Height = texture_desc.Height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, texture_desc.Width, texture_desc.Height, 0.0f, 1.0f);
ID3D11DeviceContext_Begin(context, query); for (i = 0; i < 100; i++) @@ -5255,9 +5256,7 @@ static void test_occlusion_query(void) hr = ID3D11Device_CreateQuery(device, &query_desc, (ID3D11Query **)&query); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- vp.Width = 64.0f; - vp.Height = 64.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f); ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); ID3D11DeviceContext_Begin(context, query); draw_color_quad(&test_context, &red); @@ -5977,7 +5976,6 @@ static void test_blend(void) ID3D11VertexShader *vs; ID3D11PixelShader *ps; ID3D11Device *device; - D3D11_VIEWPORT vp; ID3D11Buffer *vb; DWORD color; HRESULT hr; @@ -6143,13 +6141,7 @@ static void test_blend(void)
ID3D11DeviceContext_OMSetRenderTargets(context, 1, &offscreen_rtv, NULL);
- vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = 128.0f; - vp.Height = 128.0f; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 128.0f, 128.0f, 0.0f, 1.0f);
ID3D11DeviceContext_ClearRenderTargetView(context, offscreen_rtv, red);
@@ -8656,7 +8648,6 @@ static void test_multiple_render_targets(void) ID3D11VertexShader *vs; ID3D11PixelShader *ps; ID3D11Device *device; - D3D11_VIEWPORT vp; ID3D11Buffer *vb; ULONG refcount; HRESULT hr; @@ -8775,13 +8766,7 @@ static void test_multiple_render_targets(void) ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
- vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = 640.0f; - vp.Height = 480.0f; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
for (i = 0; i < ARRAY_SIZE(rtv); ++i) ID3D11DeviceContext_ClearRenderTargetView(context, rtv[i], red); @@ -12354,7 +12339,6 @@ static void test_swapchain_flip(void) ID3D11VertexShader *vs; ID3D11PixelShader *ps; ID3D11Device *device; - D3D11_VIEWPORT vp; ID3D11Buffer *vb; ULONG refcount; DWORD color; @@ -12493,13 +12477,7 @@ static void test_swapchain_flip(void) hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)offscreen, NULL, &offscreen_rtv); ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); ID3D11DeviceContext_OMSetRenderTargets(context, 1, &offscreen_rtv, NULL); - vp.TopLeftX = 0; - vp.TopLeftY = 0; - vp.Width = 640; - vp.Height = 480; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
vb = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, sizeof(quad), quad);
@@ -13157,12 +13135,10 @@ static void test_initial_depth_stencil_state(void) /* check if depth function is D3D11_COMPARISON_LESS */ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, 0.5f, 0); - vp.MinDepth = vp.MaxDepth = 0.4f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, vp.TopLeftX, vp.TopLeftY, vp.Width, vp.Height, 0.4f, 0.4f); draw_color_quad(&test_context, &green); draw_color_quad(&test_context, &red); - vp.MinDepth = vp.MaxDepth = 0.6f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, vp.TopLeftX, vp.TopLeftY, vp.Width, vp.Height, 0.6f, 0.6f); draw_color_quad(&test_context, &red); check_texture_color(test_context.backbuffer, 0xff00ff00, 1); check_texture_float(texture, 0.4f, 1); @@ -13183,7 +13159,6 @@ static void test_draw_depth_only(void) ID3D11Texture2D *texture; ID3D11Device *device; unsigned int i, j; - D3D11_VIEWPORT vp; struct vec4 depth; ID3D11Buffer *cb; HRESULT hr; @@ -13280,13 +13255,7 @@ static void test_draw_depth_only(void) depth.x = 1.0f / 16.0f * (j + 4 * i); ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)cb, 0, NULL, &depth, 0, 0);
- vp.TopLeftX = 160.0f * j; - vp.TopLeftY = 120.0f * i; - vp.Width = 160.0f; - vp.Height = 120.0f; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 160.0f * j, 120.0f * i, 160.0f, 120.0f, 0.0f, 1.0f);
draw_quad(&test_context); } @@ -13324,7 +13293,6 @@ static void test_draw_uav_only(void) ID3D11Texture2D *texture; ID3D11PixelShader *ps; ID3D11Device *device; - D3D11_VIEWPORT vp; HRESULT hr;
static const DWORD ps_code[] = @@ -13378,10 +13346,7 @@ static void test_draw_uav_only(void) 0, 1, &uav, NULL);
ID3D11DeviceContext_ClearUnorderedAccessViewUint(context, uav, values); - memset(&vp, 0, sizeof(vp)); - vp.Width = 10.0f; - vp.Height = 10.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 10.0f, 10.0f, 0.0f, 0.0f); ID3D11DeviceContext_ClearUnorderedAccessViewUint(context, uav, values); draw_quad(&test_context); check_texture_color(texture, 100, 1); @@ -18577,7 +18542,6 @@ static void test_atomic_instructions(void) ID3D11ComputeShader *cs; ID3D11PixelShader *ps; ID3D11Device *device; - D3D11_VIEWPORT vp; unsigned int i, j; HRESULT hr;
@@ -18727,13 +18691,7 @@ static void test_atomic_instructions(void) hr = ID3D11Device_CreateUnorderedAccessView(device, (ID3D11Resource *)out_buffer, &uav_desc, &out_uav); ok(SUCCEEDED(hr), "Failed to create unordered access view, hr %#x.\n", hr);
- vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = 1.0f; - vp.Height = 1.0f; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f);
hr = ID3D11Device_CreatePixelShader(device, ps_atomics_code, sizeof(ps_atomics_code), NULL, &ps); ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); @@ -23820,7 +23778,6 @@ static void test_fractional_viewports(void) ID3D11Device *device; ID3D11Texture2D *rt; UINT offset, stride; - D3D11_VIEWPORT vp; ID3D11Buffer *vb; HRESULT hr;
@@ -23935,13 +23892,8 @@ static void test_fractional_viewports(void)
for (i = 0; i < ARRAY_SIZE(viewport_offsets); ++i) { - vp.TopLeftX = viewport_offsets[i]; - vp.TopLeftY = viewport_offsets[i]; - vp.Width = texture_desc.Width; - vp.Height = texture_desc.Height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, viewport_offsets[i], viewport_offsets[i], + texture_desc.Width, texture_desc.Height, 0.0f, 1.0f); ID3D11DeviceContext_ClearRenderTargetView(context, rtv, white); ID3D11DeviceContext_Draw(context, 4, 0); get_texture_readback(rt, 0, &rb); @@ -23974,6 +23926,57 @@ static void test_fractional_viewports(void) release_test_context(&test_context); }
+static void test_negative_viewports(const D3D_FEATURE_LEVEL feature_level) +{ + struct d3d11_test_context test_context; + ID3D11DeviceContext *context; + BOOL quirk; + RECT rect; + + static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f}; + + if (!init_test_context(&test_context, &feature_level)) + return; + context = test_context.immediate_context; + + set_viewport(context, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f); + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); + draw_color_quad(&test_context, &green); + check_texture_color(test_context.backbuffer, 0xff00ff00, 0); + + set_viewport(context, -0.0f, -0.0f, 640.0f, 480.0f, 0.0f, 1.0f); + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); + draw_color_quad(&test_context, &green); + check_texture_color(test_context.backbuffer, 0xff00ff00, 0); + + /* For feature levels greater than or equal to 11_0, a negative top left + * corner shifts the bottom right corner by a whole integer. It seems that + * floor() is used to round viewport corners to integers. + */ + quirk = feature_level >= D3D_FEATURE_LEVEL_11_0; + + set_viewport(context, -0.4f, -0.4f, 640.0f, 480.0f, 0.0f, 1.0f); + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); + draw_color_quad(&test_context, &green); + SetRect(&rect, 0, 0, 639, 479); + check_texture_sub_resource_color(test_context.backbuffer, 0, &rect, 0xff00ff00, 1); + SetRect(&rect, 639, 479, 640, 480); + todo_wine_if(quirk) + check_texture_sub_resource_color(test_context.backbuffer, 0, &rect, quirk ? 0xffffffff : 0xff00ff00, 1); + + set_viewport(context, -1.0f / 128.0f, -1.0 / 128.0f, 640.0f, 480.0f, 0.0f, 1.0f); + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); + draw_color_quad(&test_context, &green); + SetRect(&rect, 0, 0, 639, 479); + check_texture_sub_resource_color(test_context.backbuffer, 0, &rect, 0xff00ff00, 1); + SetRect(&rect, 639, 479, 640, 480); + todo_wine_if(quirk) + check_texture_sub_resource_color(test_context.backbuffer, 0, &rect, quirk ? 0xffffffff : 0xff00ff00, 1); + + release_test_context(&test_context); +} + static void test_early_depth_stencil(void) { ID3D11DepthStencilState *depth_stencil_state; @@ -23986,7 +23989,6 @@ static void test_early_depth_stencil(void) ID3D11DepthStencilView *dsv; ID3D11PixelShader *ps; ID3D11Device *device; - D3D11_VIEWPORT vp; HRESULT hr;
static const DWORD ps_code[] = @@ -24055,12 +24057,7 @@ static void test_early_depth_stencil(void) ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
- memset(&vp, 0, sizeof(vp)); - vp.Width = 1.0f; - vp.Height = 100.0f; - vp.MinDepth = 0.5f; - vp.MaxDepth = 0.5f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + set_viewport(context, 0.0f, 0.0f, 1.0f, 100.0f, 0.5f, 0.5f); ID3D11DeviceContext_OMSetDepthStencilState(context, depth_stencil_state, 0); ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context, 1, &test_context.backbuffer_rtv, dsv, 1, 1, &uav, NULL); @@ -26045,6 +26042,7 @@ START_TEST(d3d11) test_gather_c(); test_depth_bias(); test_fractional_viewports(); + run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_11_0, test_negative_viewports); test_early_depth_stencil(); test_conservative_depth_output(); test_format_compatibility();
On 10 April 2018 at 14:59, Józef Kucia joseph.kucia@gmail.com wrote:
Unfortunately, the test may fail on Linux with some drivers, e.g. Nvidia Linux driver implements the negative viewport quirk also in OpenGL.
It seems to fail here as well for me (Intel SKL, Mesa 17.3).
On Tue, Apr 10, 2018 at 6:01 PM, Henri Verbeet hverbeet@gmail.com wrote:
On 10 April 2018 at 14:59, Józef Kucia joseph.kucia@gmail.com wrote:
Unfortunately, the test may fail on Linux with some drivers, e.g. Nvidia Linux driver implements the negative viewport quirk also in OpenGL.
It seems to fail here as well for me (Intel SKL, Mesa 17.3).
Right, it seems to be the same bug as Nvidia. I guess we haven't found earlier because Intel driver currently reports 0 for GL_VIEWPORT_SUBPIXEL_BITS.
FWIW, the test succeeds with radeonsi.
2018-04-10 23:32 GMT+02:00 Józef Kucia joseph.kucia@gmail.com:
On Tue, Apr 10, 2018 at 6:01 PM, Henri Verbeet hverbeet@gmail.com wrote:
On 10 April 2018 at 14:59, Józef Kucia joseph.kucia@gmail.com wrote:
Unfortunately, the test may fail on Linux with some drivers, e.g. Nvidia Linux driver implements the negative viewport quirk also in OpenGL.
It seems to fail here as well for me (Intel SKL, Mesa 17.3).
Right, it seems to be the same bug as Nvidia. I guess we haven't found earlier because Intel driver currently reports 0 for GL_VIEWPORT_SUBPIXEL_BITS.
FWIW, the test succeeds with radeonsi.
Also works fine for me on r600g. While I didn't run this test specifically, I know that the same issue was also present on Intel Broadwell when I last tried a few months ago.
On 10 April 2018 at 12:29, Józef Kucia joseph.kucia@gmail.com wrote:
It's a small step to reduce unncessary system memory allocations in wined3d. We shouldn't need to allocate system memory to initialize content for GPU resources, instead we should use glClearBuffer() and glClearTexImage().
If it's any help, one approach I've been considering for a while would be to essentially take a page out of the fast clear book, and introduce a WINED3D_LOCATION_CLEARED resource location. It would move the responsibility of actually clearing resources to the location management code, and ultimately the blitter, and would allow skipping clearing resources entirely for cases where resources are subsequently overwritten completely.