Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 398 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 1505b3fddbc..aa500634fe1 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -30025,6 +30025,403 @@ done: release_test_context(&test_context); }
+struct resolve_test_context +{ + ID3D11Device *device; + ID3D11DeviceContext *device_context; + ID3D11VertexShader *vertex_shader; + ID3D11InputLayout *input_layout; + ID3D11Buffer *vertex_buffer; +}; + +static void run_test_multisample_resolve(struct resolve_test_context *context, + ID3D11PixelShader *pixel_shader, DXGI_FORMAT render_target_view_format, + DXGI_FORMAT source_format, DXGI_FORMAT destination_format, DXGI_FORMAT resolve_format, + unsigned byte_count, void *bytes_out) +{ + ID3D11Texture2D *staging_texture, *resolve_target, *render_target; + D3D11_VIEWPORT viewport = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; + D3D11_RENDER_TARGET_VIEW_DESC render_view_desc = {}; + unsigned vertex_buffer_stride = 6 * sizeof(float); + float clear_color[4] = {0.2f, 0.2f, 0.2f, 1.0f}; + D3D11_MAPPED_SUBRESOURCE staging_mapped = {}; + ID3D11RenderTargetView *render_target_view; + D3D11_TEXTURE2D_DESC staging_desc = {}; + D3D11_TEXTURE2D_DESC resolve_desc = {}; + D3D11_TEXTURE2D_DESC render_desc = {}; + unsigned vertex_buffer_offset = 0; + unsigned vertex_count = 3; + HRESULT hr; + + staging_desc.Width = 1; + staging_desc.Height = 1; + staging_desc.MipLevels = 1; + staging_desc.ArraySize = 1; + staging_desc.Format = resolve_format; + staging_desc.SampleDesc.Count = 1; + staging_desc.SampleDesc.Quality = 0; + staging_desc.Usage = D3D11_USAGE_STAGING; + staging_desc.BindFlags = 0; + staging_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + staging_desc.MiscFlags = 0; + + render_desc.Width = 1; + render_desc.Height = 1; + render_desc.MipLevels = 1; + render_desc.ArraySize = 1; + render_desc.Format = source_format; + render_desc.SampleDesc.Count = 2; + render_desc.SampleDesc.Quality = 0; + render_desc.Usage = D3D11_USAGE_DEFAULT; + render_desc.BindFlags = D3D11_BIND_RENDER_TARGET; + render_desc.CPUAccessFlags = 0; + render_desc.MiscFlags = 0; + + render_view_desc.Format = render_target_view_format; + render_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + + resolve_desc.Width = 1; + resolve_desc.Height = 1; + resolve_desc.MipLevels = 1; + resolve_desc.ArraySize = 1; + resolve_desc.Format = destination_format; + resolve_desc.SampleDesc.Count = 1; + resolve_desc.SampleDesc.Quality = 0; + resolve_desc.Usage = D3D11_USAGE_DEFAULT; + resolve_desc.BindFlags = 0; + resolve_desc.CPUAccessFlags = 0; + resolve_desc.MiscFlags = 0; + + memset(bytes_out, 0, byte_count); + + hr = ID3D11Device_CreateTexture2D(context->device, &staging_desc, NULL, &staging_texture); + if (FAILED(hr)) + { + trace("Failed to create staging texture, hr %#x.\n", hr); + return; + } + + hr = ID3D11Device_CreateTexture2D(context->device, &render_desc, NULL, &render_target); + if (FAILED(hr)) + { + trace("Failed to create render target texture, hr %#x.\n", hr); + return; + } + + hr = ID3D11Device_CreateRenderTargetView(context->device, (ID3D11Resource *)render_target, + &render_view_desc, &render_target_view); + if (FAILED(hr)) + { + trace("Failed to create render target view, hr %#x.\n", hr); + return; + } + + hr = ID3D11Device_CreateTexture2D(context->device, &resolve_desc, NULL, &resolve_target); + if (FAILED(hr)) + { + trace("Failed to create resolve texture, hr %#x.\n", hr); + return; + } + + ID3D11DeviceContext_RSSetViewports(context->device_context, 1, &viewport); + ID3D11DeviceContext_OMSetRenderTargets(context->device_context, 1, &render_target_view, NULL); + ID3D11DeviceContext_IASetPrimitiveTopology(context->device_context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D11DeviceContext_IASetInputLayout(context->device_context, context->input_layout); + ID3D11DeviceContext_VSSetShader(context->device_context, context->vertex_shader, NULL, 0); + ID3D11DeviceContext_PSSetShader(context->device_context, pixel_shader, NULL, 0); + ID3D11DeviceContext_IASetVertexBuffers(context->device_context, 0, 1, &context->vertex_buffer, + &vertex_buffer_stride, &vertex_buffer_offset); + ID3D11DeviceContext_ClearRenderTargetView(context->device_context, render_target_view, clear_color); + ID3D11DeviceContext_Draw(context->device_context, vertex_count, 0); + ID3D11DeviceContext_ResolveSubresource(context->device_context, (ID3D11Resource *)resolve_target, + 0, (ID3D11Resource *)render_target, 0, resolve_format); + ID3D11DeviceContext_CopyResource(context->device_context, (ID3D11Resource *)staging_texture, + (ID3D11Resource *)resolve_target); + ID3D11DeviceContext_Map(context->device_context, (ID3D11Resource *)staging_texture, 0, + D3D11_MAP_READ, 0, &staging_mapped); + memcpy(bytes_out, staging_mapped.pData, byte_count); + ID3D11DeviceContext_Unmap(context->device_context, (ID3D11Resource *)staging_texture, 0); + ID3D11RenderTargetView_Release(render_target_view); + ID3D11Texture2D_Release(render_target); + ID3D11Texture2D_Release(resolve_target); + ID3D11Texture2D_Release(staging_texture); +} + +static void test_multisample_resolve2(void) +{ + D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_0 }; + UINT device_creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + ID3D11PixelShader *pixel_shader, *pixel_shader_uint; + struct resolve_test_context context; + unsigned int i, quality_levels; + unsigned char result[4]; + HRESULT hr; + + const BYTE vs_code[] = + { +#if 0 + struct VS_Input + { + float2 pos : POS; + float4 color : COL; + }; + + struct VS_Output + { + float4 position : SV_POSITION; + float4 color : COL; + }; + + VS_Output vs_main(VS_Input input) + { + VS_Output output; + output.position = float4(input.pos, 0.0f, 1.0f); + output.color = input.color; + + return output; + } +#endif + 68,88,66,67,30,184,39,220,81,141,142,55,98,251,192,170,226,59, + 159,54,1,0,0,0,104,2,0,0,5,0,0,0,52,0,0,0,160,0,0,0,232,0,0,0, + 56,1,0,0,204,1,0,0,82,68,69,70,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 60,0,0,0,0,5,254,255,0,1,0,0,60,0,0,0,82,68,49,49,60,0,0,0,24,0, + 0,0,32,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,77,105,99,114,111, + 115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101, + 114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,73,83,71, + 78,64,0,0,0,2,0,0,0,8,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0, + 0,0,3,3,0,0,60,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,15,15,0,0, + 80,79,83,0,67,79,76,0,79,83,71,78,72,0,0,0,2,0,0,0,8,0,0,0,56,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,68,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,1,0,0,0,15,0,0,0,83,86,95,80,79,83,73,84,73,79,78, + 0,67,79,76,0,83,72,69,88,140,0,0,0,80,0,1,0,35,0,0,0,106,8,0,1, + 95,0,0,3,50,16,16,0,0,0,0,0,95,0,0,3,242,16,16,0,1,0,0,0,103,0,0, + 4,242,32,16,0,0,0,0,0,1,0,0,0,101,0,0,3,242,32,16,0,1,0,0,0,54, + 0,0,5,50,32,16,0,0,0,0,0,70,16,16,0,0,0,0,0,54,0,0,8,194,32,16,0, + 0,0,0,0,2,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,63,54,0,0,5,242, + 32,16,0,1,0,0,0,70,30,16,0,1,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + + const BYTE ps_code[] = + { +#if 0 + float4 ps_main(VS_Output input) : SV_TARGET + { + return input.color; + } +#endif + 68,88,66,67,39,85,23,171,129,58,200,222,67,215,85,143,48,99,104,37, + 1,0,0,0,4,2,0,0,5,0,0,0,52,0,0,0,160,0,0,0,240,0,0,0,36,1,0,0,104, + 1,0,0,82,68,69,70,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,0,0,0,0,5, + 255,255,0,1,0,0,60,0,0,0,82,68,49,49,60,0,0,0,24,0,0,0,32,0,0,0,40, + 0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,77,105,99,114,111,115,111,102,116, + 32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109, + 112,105,108,101,114,32,49,48,46,49,0,73,83,71,78,72,0,0,0,2,0,0,0,8, + 0,0,0,56,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,68,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,15,15,0,0,83,86,95,80,79,83,73,84,73, + 79,78,0,67,79,76,0,79,83,71,78,44,0,0,0,1,0,0,0,8,0,0,0,32,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,83,86,95,84,65,82,71,69,84,0, + 171,171,83,72,69,88,60,0,0,0,80,0,0,0,15,0,0,0,106,8,0,1,98,16,0,3, + 242,16,16,0,1,0,0,0,101,0,0,3,242,32,16,0,0,0,0,0,54,0,0,5,242,32, + 16,0,0,0,0,0,70,30,16,0,1,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0 + }; + + const BYTE ps_uint_code[] = + { +#if 0 + uint4 ps_main_uint(VS_Output input) : SV_TARGET + { + return 255 * input.color; + } +#endif + 68,88,66,67,183,183,169,55,133,61,81,26,195,69,141,254,78,169,90,79, + 1,0,0,0,52,2,0,0,5,0,0,0,52,0,0,0,160,0,0,0,240,0,0,0,36,1,0,0,152, + 1,0,0,82,68,69,70,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,0,0,0,0,5,255, + 255,0,1,0,0,60,0,0,0,82,68,49,49,60,0,0,0,24,0,0,0,32,0,0,0,40,0,0,0, + 36,0,0,0,12,0,0,0,0,0,0,0,77,105,99,114,111,115,111,102,116,32,40,82, + 41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108, + 101,114,32,49,48,46,49,0,73,83,71,78,72,0,0,0,2,0,0,0,8,0,0,0,56,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,68,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,1,0,0,0,15,15,0,0,83,86,95,80,79,83,73,84,73,79,78,0,67,79,76,0, + 79,83,71,78,44,0,0,0,1,0,0,0,8,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 0,0,0,0,15,0,0,0,83,86,95,84,65,82,71,69,84,0,171,171,83,72,69,88,108, + 0,0,0,80,0,0,0,27,0,0,0,106,8,0,1,98,16,0,3,242,16,16,0,1,0,0,0,101,0, + 0,3,242,32,16,0,0,0,0,0,104,0,0,2,1,0,0,0,56,0,0,10,242,0,16,0,0,0,0, + 0,70,30,16,0,1,0,0,0,2,64,0,0,0,0,127,67,0,0,127,67,0,0,127,67,0,0,127, + 67,28,0,0,5,242,32,16,0,0,0,0,0,70,14,16,0,0,0,0,0,62,0,0,1,83,84,65, + 84,148,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + + float vertex_data [] = + { /* x, y, r, g, b, a */ + 1.0f, 1.0f, .8f, 0.f, 0.f, 1.f, + 1.0f, -1.0f, .8f, 0.f, 0.f, 1.f, + -1.0f, -1.0f, .8f, 0.f, 0.f, 1.f, + }; + + D3D11_INPUT_ELEMENT_DESC input_elements[] = + { + { "POS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + struct + { + BOOL use_uint_shader; + DXGI_FORMAT render_target_view_format; + DXGI_FORMAT source_format; + DXGI_FORMAT destination_format; + DXGI_FORMAT resolve_format; + unsigned int byte_count; + unsigned char expected[4]; + BOOL todo; + } + tests[] = + { + { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, + 4, { 0, 0, 0, 0x3f } }, + { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, + 4, { 0, 0, 0, 0x3f }, TRUE }, + { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, + 4, { 0, 0, 0, 0x3f }, TRUE }, + { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, + 4, { 0, 0, 0, 0x3f }, TRUE }, + { FALSE, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, + 2, { 0, 0x80 } }, + { FALSE, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, + 2, { 0xff, 0x37 } }, + { FALSE, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_FLOAT, + 2, { 0xff, 0x37 } }, + { FALSE, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, + 2, { 0x66, 0x36 }, TRUE }, + { FALSE, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_FLOAT, + 2, { 0xbd, 0xc8 } }, + { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, + 4, { 0x80, 0x19, 0x19, 0xff } }, + { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + 4, { 0x99, 0x23, 0x23, 0xff }, TRUE }, + { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + 4, { 0x99, 0x23, 0x23, 0xff }, TRUE }, + { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_SNORM, + 4, { 0, 0x19, 0x19, 0xff }, TRUE }, + { FALSE, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, + 4, { 0x3f, 0xc, 0xc, 0x7f }, TRUE }, + { TRUE, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, + 4, { 0x3f, 0, 0, 0x40 }, TRUE }, + { TRUE, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_SNORM, + 4, { 0x40, 0, 0, 0x40 }, TRUE }, + { TRUE, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, + 4, { 0x66, 0, 0, 0x80 }, TRUE }, + }; + + hr = D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, device_creation_flags, + feature_levels, ARRAY_SIZE(feature_levels), D3D11_SDK_VERSION, &context.device, + 0, &context.device_context); + if (FAILED(hr)) + { + trace("Failed to create device, hr %#x.\n", hr); + return; + } + + hr = ID3D11Device_CreateVertexShader(context.device, vs_code, sizeof(vs_code), + NULL, &context.vertex_shader); + if (FAILED(hr)) + { + trace("Failed to create vertex shader, hr %#x.\n", hr); + goto out_1; + } + hr = ID3D11Device_CreatePixelShader(context.device, ps_code, sizeof(ps_code), + NULL, &pixel_shader); + if (FAILED(hr)) + { + trace("Failed to create pixel shader, hr %#x.\n", hr); + goto out_2; + } + hr = ID3D11Device_CreatePixelShader(context.device, ps_uint_code, sizeof(ps_uint_code), + NULL, &pixel_shader_uint); + if (FAILED(hr)) + { + trace("Failed to create uint pixel shader, hr %#x.\n", hr); + goto out_3; + } + hr = ID3D11Device_CreateInputLayout(context.device, input_elements, + ARRAY_SIZE(input_elements), vs_code, sizeof(vs_code), &context.input_layout); + if (FAILED(hr)) + { + trace("Failed to create input layout, hr %#x.\n", hr); + goto out_4; + } + context.vertex_buffer = create_buffer(context.device, D3D11_BIND_VERTEX_BUFFER, + sizeof(vertex_data), vertex_data); + if (!context.vertex_buffer) + goto out_5; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = ID3D11Device_CheckMultisampleQualityLevels(context.device, tests[i].source_format, 2, &quality_levels); + ok(hr == S_OK, "Failed to check multisample quality levels, hr %#x.\n", hr); + if (!quality_levels) + { + skip("Test %3u: 2xMSAA not supported.\n", i); + } + else + { + run_test_multisample_resolve(&context, tests[i].use_uint_shader ? pixel_shader_uint : pixel_shader, + tests[i].render_target_view_format, tests[i].source_format, tests[i].destination_format, + tests[i].resolve_format, tests[i].byte_count, result); + + todo_wine_if(tests[i].todo) + ok(!memcmp(result, tests[i].expected, tests[i].byte_count), + "Test %3u: expected: %2x %2x %2x %2x, got: %2x %2x %2x %2x\n", i, + tests[i].expected[0], tests[i].expected[1], tests[i].expected[2], tests[i].expected[3], + result[0], result[1], result[2], result[3]); + } + } + + ID3D11Buffer_Release(context.vertex_buffer); +out_5: + ID3D11InputLayout_Release(context.input_layout); +out_4: + ID3D11PixelShader_Release(pixel_shader_uint); +out_3: + ID3D11PixelShader_Release(pixel_shader); +out_2: + ID3D11VertexShader_Release(context.vertex_shader); +out_1: + ID3D11DeviceContext_Release(context.device_context); + ID3D11Device_Release(context.device); +} + static void test_multisample_resolve(void) { struct d3d11_test_context test_context; @@ -32194,6 +32591,7 @@ START_TEST(d3d11) queue_test(test_unbound_multisample_texture); queue_test(test_multiple_viewports); queue_test(test_multisample_resolve); + queue_test(test_multisample_resolve2); queue_test(test_sample_shading); queue_test(test_sample_mask); queue_test(test_depth_clip);
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 18 +- dlls/d3d8/device.c | 6 +- dlls/d3d9/device.c | 4 +- dlls/ddraw/device.c | 2 +- dlls/ddraw/surface.c | 6 +- dlls/wined3d/arb_program_shader.c | 8 +- dlls/wined3d/cs.c | 10 +- dlls/wined3d/device.c | 12 +- dlls/wined3d/glsl_shader.c | 8 +- dlls/wined3d/surface.c | 12 +- dlls/wined3d/swapchain.c | 4 +- dlls/wined3d/texture.c | 440 +++++++++++++++++++++++++++--- dlls/wined3d/wined3d_private.h | 6 +- include/wine/wined3d.h | 2 +- 14 files changed, 448 insertions(+), 90 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index aa500634fe1..ebe7486972b 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -30296,13 +30296,13 @@ static void test_multisample_resolve2(void) 4, { 0, 0, 0, 0x3f } }, { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, - 4, { 0, 0, 0, 0x3f }, TRUE }, + 4, { 0, 0, 0, 0x3f } }, { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, - 4, { 0, 0, 0, 0x3f }, TRUE }, + 4, { 0, 0, 0, 0x3f } }, { FALSE, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, - 4, { 0, 0, 0, 0x3f }, TRUE }, + 4, { 0, 0, 0, 0x3f } }, { FALSE, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, 2, { 0, 0x80 } }, @@ -30314,7 +30314,7 @@ static void test_multisample_resolve2(void) 2, { 0xff, 0x37 } }, { FALSE, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, - 2, { 0x66, 0x36 }, TRUE }, + 2, { 0x66, 0x36 } }, { FALSE, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_FLOAT, 2, { 0xbd, 0xc8 } }, @@ -30323,16 +30323,16 @@ static void test_multisample_resolve2(void) 4, { 0x80, 0x19, 0x19, 0xff } }, { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - 4, { 0x99, 0x23, 0x23, 0xff }, TRUE }, + 4, { 0x99, 0x23, 0x23, 0xff } }, { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - 4, { 0x99, 0x23, 0x23, 0xff }, TRUE }, + 4, { 0x99, 0x23, 0x23, 0xff } }, { FALSE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_SNORM, - 4, { 0, 0x19, 0x19, 0xff }, TRUE }, + 4, { 0, 0x19, 0x19, 0xff } }, { FALSE, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, - 4, { 0x3f, 0xc, 0xc, 0x7f }, TRUE }, + 4, { 0x3f, 0xc, 0xc, 0x7f } }, { TRUE, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, 4, { 0x3f, 0, 0, 0x40 }, TRUE }, @@ -30487,7 +30487,7 @@ static void test_multisample_resolve(void) DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - &color, 0xffe1bc89, TRUE}, + &color, 0xffe1bc89}, {DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index f4bdb748275..93fc55db73c 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1395,7 +1395,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, { RECT rect = {0, 0, src_w, src_h}; wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &rect, - src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT); + src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); } else { @@ -1411,7 +1411,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, dst_points[i].x + w, dst_points[i].y + h};
wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect, - src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT); + src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); } } else @@ -1423,7 +1423,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, RECT dst_rect = {0, 0, w, h};
wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect, - src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT); + src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); } } } diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index fec631e0e67..ec6839751af 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1773,7 +1773,7 @@ static HRESULT WINAPI d3d9_device_GetRenderTargetData(IDirect3DDevice9Ex *iface, hr = D3DERR_INVALIDCALL; else hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, - rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); + rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); wined3d_mutex_unlock();
return hr; @@ -1874,7 +1874,7 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect }
hr = wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, dst_rect, src->wined3d_texture, - src->sub_resource_idx, src_rect, 0, NULL, wined3d_texture_filter_type_from_d3d(filter)); + src->sub_resource_idx, src_rect, 0, NULL, wined3d_texture_filter_type_from_d3d(filter), WINED3DFMT_UNKNOWN); if (hr == WINEDDERR_INVALIDRECT) hr = D3DERR_INVALIDCALL; if (SUCCEEDED(hr) && dst->texture) diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 4d24c22650e..c187be02980 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -6123,7 +6123,7 @@ static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *d RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h};
if (FAILED(hr = wined3d_texture_blt(dst_level->wined3d_texture, dst_level->sub_resource_idx, &dst_rect, - src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) + src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN))) ERR("Blit failed, hr %#x.\n", hr);
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 0ca19d4f8a5..686fc267c43 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -113,7 +113,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, dst_texture = ddraw->wined3d_frontbuffer;
if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture, - surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval) + surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN)) && swap_interval) { hr = wined3d_swapchain_present(ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0); ddraw->flags |= DDRAW_SWAPPED; @@ -1535,7 +1535,7 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * wined3d_flags |= WINED3D_BLT_SYNCHRONOUS;
return wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, dst_rect, - src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter); + src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter, WINED3DFMT_UNKNOWN); }
static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, const RECT *dst_rect_in, @@ -4377,7 +4377,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0); if (SUCCEEDED(hr)) hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, - src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT); + src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0); wined3d_mutex_unlock(); diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index af8f2a508fa..bd23f0830b4 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7792,7 +7792,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); struct wined3d_context_gl *context_gl = wined3d_context_gl(context); @@ -7805,10 +7805,10 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl RECT s, d;
TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n", blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter)); + wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location, &dst_texture->resource, dst_location)) @@ -7821,7 +7821,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
TRACE("Forwarding to blitter %p.\n", next); return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter, format_id); }
arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 0385b8f4693..635a030e46b 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -411,6 +411,7 @@ struct wined3d_cs_blt_sub_resource DWORD flags; struct wined3d_blt_fx fx; enum wined3d_texture_filter_type filter; + enum wined3d_format_id format_id; };
struct wined3d_cs_update_sub_resource @@ -549,7 +550,7 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
/* Blit the logo into the upper left corner of the back-buffer. */ wined3d_texture_blt(back_buffer, 0, &rect, logo_texture, 0, - &rect, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT); + &rect, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); }
if ((cursor_texture = swapchain->device->cursor_texture) @@ -574,7 +575,7 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&dst_rect, 2); if (wined3d_clip_blit(&clip_rect, &dst_rect, &src_rect)) wined3d_texture_blt(back_buffer, 0, &dst_rect, cursor_texture, 0, - &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT); + &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); }
swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->swap_interval, op->flags); @@ -2368,7 +2369,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * { if (FAILED(texture2d_blt(texture_from_resource(op->dst_resource), op->dst_sub_resource_idx, &op->dst_box, texture_from_resource(op->src_resource), op->src_sub_resource_idx, - &op->src_box, op->flags, &op->fx, op->filter))) + &op->src_box, op->flags, &op->fx, op->filter, op->format_id))) FIXME("Blit failed.\n"); }
@@ -2381,7 +2382,7 @@ error: void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_cs_blt_sub_resource *op;
@@ -2399,6 +2400,7 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso else memset(&op->fx, 0, sizeof(op->fx)); op->filter = filter; + op->format_id = format_id;
wined3d_resource_acquire(dst_resource); if (src_resource) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1fd5f4b012e..53922efc078 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4316,7 +4316,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, wined3d_cs_emit_blt_sub_resource(device->cs, &dst_texture->resource, j * dst_level_count + i, &box, &src_texture->resource, j * src_level_count + i + src_skip_levels, &box, - 0, NULL, WINED3D_TEXF_POINT); + 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); } } } @@ -4362,7 +4362,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, wined3d_cs_emit_blt_sub_resource(device->cs, &dst_texture->resource, i * dst_level_count + j, &box, &src_texture->resource, i * src_level_count + src_level, &box, - 0, NULL, WINED3D_TEXF_POINT); + 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); } } } @@ -4594,7 +4594,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, { wined3d_box_set(&src_box, 0, 0, src_resource->size, 1, 0, 1); wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, 0, &src_box, - src_resource, 0, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT); + src_resource, 0, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); return; }
@@ -4619,7 +4619,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, unsigned int idx = j * dst_texture->level_count + i;
wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, idx, &dst_box, - src_resource, idx, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT); + src_resource, idx, &src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); } } } @@ -4780,7 +4780,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev }
wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box, - src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT); + src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
return WINED3D_OK; } @@ -4895,7 +4895,7 @@ void CDECL wined3d_device_resolve_sub_resource(struct wined3d_device *device, SetRect(&src_rect, 0, 0, wined3d_texture_get_level_width(src_texture, src_level), wined3d_texture_get_level_height(src_texture, src_level)); wined3d_texture_blt(dst_texture, dst_sub_resource_idx, &dst_rect, - src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); + src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT, format_id); }
HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 45eebcc2c20..4567370f3fc 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -13061,7 +13061,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); struct wined3d_texture_gl *dst_texture_gl = wined3d_texture_gl(dst_texture); @@ -13078,10 +13078,10 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli RECT s, d;
TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n", blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); + wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
if (!glsl_blitter_supported(op, context, src_texture_gl, src_location, dst_texture_gl, dst_location)) { @@ -13093,7 +13093,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli
TRACE("Forwarding to blitter %p.\n", next); return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id); }
glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index d5d07d8c401..4b39c47cfe2 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1400,7 +1400,7 @@ static DWORD cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; @@ -1476,7 +1476,7 @@ static bool wined3d_is_colour_blit(enum wined3d_blit_op blit_op) HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx, - enum wined3d_texture_filter_type filter) + enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource; struct wined3d_device *device = dst_texture->resource.device; @@ -1495,9 +1495,9 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ | WINED3D_BLT_RAW;
TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, " - "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n", + "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s, format_id %s.\n", dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, src_sub_resource_idx, - debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter)); + debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id)); TRACE("Usage is %s.\n", debug_d3dusage(dst_texture->resource.usage));
if (fx) @@ -1581,7 +1581,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ context = context_acquire(device, dst_texture, dst_sub_resource_idx); valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context, src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect, - dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter); + dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter, format_id); context_release(context);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations); @@ -1715,7 +1715,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context, src_texture, src_sub_resource_idx, src_location, &src_rect, - dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter); + dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter, format_id);
context_release(context);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 72e17a6f833..39fac6c37fa 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -267,7 +267,7 @@ HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapc }
return wined3d_texture_blt(dst_texture, sub_resource_idx, &dst_rect, - swapchain->front_buffer, 0, &src_rect, 0, NULL, WINED3D_TEXF_POINT); + swapchain->front_buffer, 0, &src_rect, 0, NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN); }
struct wined3d_texture * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain, @@ -492,7 +492,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, texture, 0, - location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter); + location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter, WINED3DFMT_UNKNOWN); wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); }
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index f4f929db2ca..1d763bbb369 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -320,9 +320,13 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont enum wined3d_texture_filter_type filter, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, - const RECT *dst_rect) + const RECT *dst_rect, enum wined3d_format_id format_id) { + unsigned int dst_save_sub_resource_idx = dst_sub_resource_idx; struct wined3d_texture *required_texture, *restore_texture; + struct wined3d_texture *dst_save_texture = dst_texture; + struct wined3d_texture *src_staging_texture = NULL; + struct wined3d_texture *dst_staging_texture = NULL; const struct wined3d_gl_info *gl_info; struct wined3d_context_gl *context_gl; unsigned int restore_idx; @@ -332,10 +336,10 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont RECT s, d;
TRACE("device %p, context %p, filter %s, src_texture %p, src_sub_resource_idx %u, src_location %s, " - "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", + "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, format_id %s.\n", device, context, debug_d3dtexturefiltertype(filter), src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, - dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); + dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect), debug_d3dformat(format_id));
scaled_resolve = wined3d_texture_gl_is_multisample_location(wined3d_texture_gl(src_texture), src_location) && (abs(src_rect->bottom - src_rect->top) != abs(dst_rect->bottom - dst_rect->top) @@ -346,6 +350,101 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont else gl_filter = scaled_resolve ? GL_SCALED_RESOLVE_FASTEST_EXT : GL_NEAREST;
+ context_gl = wined3d_context_gl(context); + if (!context_gl->valid) + { + context_release(context); + WARN("Invalid context, skipping blit.\n"); + return; + } + + gl_info = context_gl->gl_info; + + switch (format_id) + { + case WINED3DFMT_R8G8B8A8_UNORM_SRGB: + case WINED3DFMT_B8G8R8A8_UNORM_SRGB: + case WINED3DFMT_B8G8R8X8_UNORM_SRGB: + gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + break; + default: + break; + } + + if (format_id != WINED3DFMT_UNKNOWN && src_texture->resource.format->id != format_id) + { + struct wined3d_texture_gl *src_staging_texture_gl = NULL; + struct wined3d_texture_gl *src_texture_gl = NULL; + struct wined3d_resource_desc desc; + unsigned src_level; + HRESULT hr; + + src_level = src_sub_resource_idx % src_texture->level_count; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + desc.format = format_id; + desc.multisample_type = src_texture->resource.multisample_type; + desc.multisample_quality = src_texture->resource.multisample_quality; + desc.usage = WINED3DUSAGE_PRIVATE; + desc.bind_flags = 0; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + desc.width = wined3d_texture_get_level_width(src_texture, src_level); + desc.height = wined3d_texture_get_level_height(src_texture, src_level); + desc.depth = 1; + desc.size = 0; + + hr = wined3d_texture_create(device, &desc, 1, 1, 0, NULL, NULL, &wined3d_null_parent_ops, &src_staging_texture); + if (FAILED(hr)) + { + ERR("Failed to create staging texture, hr %#x.\n", hr); + return; + } + + src_texture_gl = wined3d_texture_gl(src_texture); + src_staging_texture_gl = wined3d_texture_gl(src_staging_texture); + + wined3d_texture_prepare_location(src_staging_texture, 0, context, WINED3D_LOCATION_TEXTURE_RGB); + + GL_EXTCALL(glCopyImageSubData(wined3d_texture_gl_get_texture_name(src_texture_gl, context, false), + src_texture_gl->target, src_level, 0, 0, 0, + wined3d_texture_gl_get_texture_name(src_staging_texture_gl, context, false), + src_staging_texture_gl->target, 0, 0, 0, 0, desc.width, desc.height, 1)); + + checkGLcall("glCopyImageSubData()"); + src_texture = src_staging_texture; + src_sub_resource_idx = 0; + } + + if (format_id != WINED3DFMT_UNKNOWN && dst_texture->resource.format->id != format_id) + { + struct wined3d_resource_desc desc; + unsigned dst_level; + HRESULT hr; + + dst_level = dst_sub_resource_idx % dst_texture->level_count; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + desc.format = format_id; + desc.multisample_type = dst_texture->resource.multisample_type; + desc.multisample_quality = dst_texture->resource.multisample_quality; + desc.usage = WINED3DUSAGE_PRIVATE; + desc.bind_flags = 0; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + desc.width = wined3d_texture_get_level_width(dst_texture, dst_level); + desc.height = wined3d_texture_get_level_height(dst_texture, dst_level); + desc.depth = 1; + desc.size = 0; + + hr = wined3d_texture_create(device, &desc, 1, 1, 0, NULL, NULL, &wined3d_null_parent_ops, &dst_staging_texture); + if (FAILED(hr)) + { + ERR("Failed to create staging texture, hr %#x.\n", hr); + return; + } + + dst_texture = dst_staging_texture; + dst_sub_resource_idx = 0; + } + /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. (And is * in fact harmful if we're being called by surface_load_location() with @@ -374,16 +473,6 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont else restore_texture = NULL;
- context_gl = wined3d_context_gl(context); - if (!context_gl->valid) - { - context_release(context); - WARN("Invalid context, skipping blit.\n"); - return; - } - - gl_info = context_gl->gl_info; - if (src_location == WINED3D_LOCATION_DRAWABLE) { TRACE("Source texture %p is onscreen.\n", src_texture); @@ -437,6 +526,27 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont if (dst_location == WINED3D_LOCATION_DRAWABLE && dst_texture->swapchain->front_buffer == dst_texture) gl_info->gl_ops.gl.p_glFlush();
+ if (dst_staging_texture) + { + struct wined3d_texture_gl *dst_texture_gl, *dst_save_texture_gl; + dst_texture_gl = wined3d_texture_gl(dst_texture); + dst_save_texture_gl = wined3d_texture_gl(dst_save_texture); + + wined3d_texture_prepare_location(dst_save_texture, 0, context, WINED3D_LOCATION_TEXTURE_RGB); + + GL_EXTCALL(glCopyImageSubData(wined3d_texture_gl_get_texture_name(dst_texture_gl, context, false), + dst_texture_gl->target, 0, 0, 0, 0, + wined3d_texture_gl_get_texture_name(dst_save_texture_gl, context, false), + dst_save_texture_gl->target, dst_save_sub_resource_idx % dst_texture->level_count, 0, 0, 0, + dst_texture->resource.width, dst_texture->resource.height, 1)); + + checkGLcall("glCopyImageSubData()"); + wined3d_texture_decref(dst_texture); + } + + if (src_staging_texture) + wined3d_texture_decref(src_staging_texture); + if (restore_texture) context_restore(context, restore_texture, restore_idx); } @@ -682,8 +792,8 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, { DWORD required_access = wined3d_resource_access_from_location(location); if ((texture->resource.access & required_access) != required_access) - WARN("Operation requires %#x access, but texture only has %#x.\n", - required_access, texture->resource.access); + WARN("Operation requires %#x access, but texture only has %#x, location %s, current %s.\n", + required_access, texture->resource.access, wined3d_debug_location(location), wined3d_debug_location(current)); }
if (current & WINED3D_LOCATION_DISCARDED) @@ -2933,7 +3043,7 @@ static BOOL wined3d_texture_load_drawable(struct wined3d_texture *texture, device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &r, texture, sub_resource_idx, WINED3D_LOCATION_DRAWABLE, &r, - NULL, WINED3D_TEXF_POINT); + NULL, WINED3D_TEXF_POINT, WINED3DFMT_UNKNOWN);
return TRUE; } @@ -2971,7 +3081,7 @@ static BOOL wined3d_texture_load_renderbuffer(struct wined3d_texture *texture, src_location = WINED3D_LOCATION_TEXTURE_RGB;
texture2d_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, texture, - sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect); + sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect, WINED3DFMT_UNKNOWN);
return TRUE; } @@ -3018,11 +3128,11 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g if (srgb) texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect, - &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect); + &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect, WINED3DFMT_UNKNOWN); else texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect, - &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); + &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect, WINED3DFMT_UNKNOWN);
return TRUE; } @@ -3039,7 +3149,7 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info, &texture_gl->t.resource, src_location, &texture_gl->t.resource, dst_location)) texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, &texture_gl->t, sub_resource_idx, - src_location, &src_rect, &texture_gl->t, sub_resource_idx, dst_location, &src_rect); + src_location, &src_rect, &texture_gl->t, sub_resource_idx, dst_location, &src_rect, WINED3DFMT_UNKNOWN);
return TRUE; } @@ -3849,16 +3959,18 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) + const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, + enum wined3d_format_id format_id) { struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; HRESULT hr;
TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, " - "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n", + "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s, format_id %s.\n", dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, - src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); + src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter), + debug_d3dformat(format_id));
if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) @@ -3901,7 +4013,7 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned }
wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx, - &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter); + &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter, format_id);
return WINED3D_OK; } @@ -5655,7 +5767,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); struct wined3d_context_gl *context_gl = wined3d_context_gl(context); @@ -5676,7 +5788,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit { if ((next = blitter->next)) return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id); }
TRACE("Blt from texture %p, %u to rendertarget %p, %u.\n", @@ -5864,7 +5976,7 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct wined3d_resource *src_resource, *dst_resource; @@ -5873,10 +5985,10 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit struct wined3d_blitter *next;
TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n", blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); + wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
src_resource = &src_texture->resource; dst_resource = &dst_texture->resource; @@ -5902,14 +6014,14 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
TRACE("Forwarding to blitter %p.\n", next); return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id); }
if (blit_op == WINED3D_BLIT_OP_COLOR_BLIT) { TRACE("Colour blit.\n"); texture2d_blt_fbo(device, context, filter, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, format_id); return dst_location; }
@@ -5980,7 +6092,7 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); struct wined3d_texture_gl *dst_texture_gl = wined3d_texture_gl(dst_texture); @@ -6007,7 +6119,7 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
TRACE("Forwarding to blitter %p.\n", next); return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id); }
TRACE("Blit using ARB_copy_image.\n"); @@ -6381,7 +6493,7 @@ static void vk_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_dev
static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wined3d_context *context, const struct wined3d_resource *src_resource, const RECT *src_rect, - const struct wined3d_resource *dst_resource, const RECT *dst_rect) + const struct wined3d_resource *dst_resource, const RECT *dst_rect, enum wined3d_format_id format_id) { const struct wined3d_format *src_format = src_resource->format; const struct wined3d_format *dst_format = dst_resource->format; @@ -6413,7 +6525,9 @@ static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wine }
if (op != WINED3D_BLIT_OP_RAW_BLIT - && wined3d_format_vk(src_format)->vk_format != wined3d_format_vk(dst_format)->vk_format) + && wined3d_format_vk(src_format)->vk_format != wined3d_format_vk(dst_format)->vk_format + && ((!wined3d_format_is_typeless(src_format) && !wined3d_format_is_typeless(dst_format)) + || (format_id == WINED3DFMT_UNKNOWN))) { TRACE("Format conversion not supported.\n"); return false; @@ -6445,11 +6559,78 @@ static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wine return true; }
+static VkResult create_staging_image_for_resolve(struct wined3d_context_vk *context_vk, + VkImageType vk_image_type, VkFormat vk_format, unsigned width, unsigned height, unsigned depth, + unsigned sample_count, VkImage *image) +{ + struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter); + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkMemoryAllocateInfo allocate_info = {0}; + VkMemoryRequirements memory_requirements; + VkImageCreateInfo create_info; + VkDeviceMemory device_memory; + VkResult vr; + + create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + create_info.pNext = NULL; + create_info.flags = 0; + create_info.imageType = vk_image_type; + create_info.format = vk_format; + create_info.extent.width = width; + create_info.extent.height = height; + create_info.extent.depth = depth; + create_info.mipLevels = 1; + create_info.arrayLayers = 1; + create_info.samples = sample_count; + create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT + | VK_IMAGE_USAGE_TRANSFER_DST_BIT + | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + create_info.queueFamilyIndexCount = 0; + create_info.pQueueFamilyIndices = NULL; + create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + vr = VK_CALL(vkCreateImage(device_vk->vk_device, &create_info, NULL, image)); + if (vr != VK_SUCCESS) + { + ERR("Failed to create image, vr %#x.\n", vr); + return vr; + } + + wined3d_context_vk_destroy_image(context_vk, *image, context_vk->current_command_buffer.id); + + VK_CALL(vkGetImageMemoryRequirements(device_vk->vk_device, *image, &memory_requirements)); + + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.allocationSize = memory_requirements.size; + allocate_info.memoryTypeIndex = wined3d_adapter_vk_get_memory_type_index(adapter_vk, ~0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vr = VK_CALL(vkAllocateMemory(device_vk->vk_device, &allocate_info, NULL, &device_memory)); + if (vr != VK_SUCCESS) + { + ERR("Failed to allocate memory, vr %#x.\n", vr); + return vr; + } + + wined3d_context_vk_destroy_memory(context_vk, device_memory, context_vk->current_command_buffer.id); + + vr = VK_CALL(vkBindImageMemory(device_vk->vk_device, *image, device_memory, 0)); + if (vr != VK_SUCCESS) + { + ERR("Failed to bind image memory, vr %#x.\n", vr); + return vr; + } + + return VK_SUCCESS; +} + static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) { struct wined3d_texture_vk *src_texture_vk = wined3d_texture_vk(src_texture); struct wined3d_texture_vk *dst_texture_vk = wined3d_texture_vk(dst_texture); @@ -6459,21 +6640,23 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ VkImageAspectFlags src_aspect, dst_aspect; VkCommandBuffer vk_command_buffer; struct wined3d_blitter *next; + unsigned src_sample_count; bool resolve = false;
TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s, format_id %s.\n", blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), - wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); + wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter), debug_d3dformat(format_id));
- if (!vk_blitter_blit_supported(op, context, &src_texture->resource, src_rect, &dst_texture->resource, dst_rect)) + if (!vk_blitter_blit_supported(op, context, &src_texture->resource, src_rect, &dst_texture->resource, dst_rect, format_id)) goto next;
src_aspect = vk_aspect_mask_from_format(src_texture_vk->t.resource.format); dst_aspect = vk_aspect_mask_from_format(dst_texture_vk->t.resource.format);
- if (wined3d_resource_get_sample_count(&src_texture_vk->t.resource) > 1) + src_sample_count = wined3d_resource_get_sample_count(&src_texture_vk->t.resource); + if (src_sample_count > 1) resolve = true;
src_level = src_sub_resource_idx % src_texture->level_count; @@ -6523,7 +6706,180 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ dst_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_texture_vk->vk_image, dst_aspect);
- if (resolve) + + if (resolve && format_id != WINED3DFMT_UNKNOWN + && (src_texture->resource.format->id != format_id || dst_texture->resource.format->id != format_id)) + { + const struct wined3d_format_vk *src_format_vk = wined3d_format_vk(src_texture->resource.format); + const struct wined3d_format_vk *dst_format_vk = wined3d_format_vk(dst_texture->resource.format); + VkImage src_vk_image, dst_vk_image; + VkImageResolve resolve_region; + VkImageType vk_image_type; + VkImageCopy copy_region; + VkFormat vk_format; + VkResult vr; + + TRACE("Doing typeless resolve %s to %s (via %s)\n", debug_d3dformat(src_texture->resource.format->id), + debug_d3dformat(dst_texture->resource.format->id), debug_d3dformat(format_id)); + + if (!wined3d_format_is_typeless(&src_format_vk->f)) + { + vk_format = src_format_vk->vk_format; + } + else if (!wined3d_format_is_typeless(&dst_format_vk->f)) + { + vk_format = dst_format_vk->vk_format; + } + else + { + vk_format = wined3d_format_vk(wined3d_get_format(context->device->adapter, format_id, 0))->vk_format; + } + + switch (src_texture->resource.type) + { + case WINED3D_RTYPE_TEXTURE_1D: + vk_image_type = VK_IMAGE_TYPE_1D; + break; + case WINED3D_RTYPE_TEXTURE_2D: + vk_image_type = VK_IMAGE_TYPE_2D; + break; + case WINED3D_RTYPE_TEXTURE_3D: + vk_image_type = VK_IMAGE_TYPE_3D; + break; + default: + ERR("Unexpected resource type: %s\n", debug_d3dresourcetype(src_texture->resource.type)); + goto next; + } + + resolve_region.dstSubresource.aspectMask = dst_aspect; + resolve_region.extent.width = src_rect->right - src_rect->left; + resolve_region.extent.height = src_rect->bottom - src_rect->top; + resolve_region.extent.depth = 1; + + if (src_texture->resource.format->id != format_id) + { + vr = create_staging_image_for_resolve(context_vk, vk_image_type, vk_format, + resolve_region.extent.width, resolve_region.extent.height, 1, src_sample_count, &src_vk_image); + if (vr != VK_SUCCESS) + goto next; + + wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, src_vk_image, src_aspect); + + copy_region.srcSubresource.aspectMask = src_aspect; + copy_region.srcSubresource.mipLevel = src_level; + copy_region.srcSubresource.baseArrayLayer = src_layer; + copy_region.srcSubresource.layerCount = 1; + copy_region.srcOffset.x = src_rect->left; + copy_region.srcOffset.y = src_rect->top; + copy_region.srcOffset.z = 0; + copy_region.dstSubresource.aspectMask = src_aspect; + copy_region.dstSubresource.mipLevel = 0; + copy_region.dstSubresource.baseArrayLayer = 0; + copy_region.dstSubresource.layerCount = 1; + copy_region.dstOffset.x = 0; + copy_region.dstOffset.y = 0; + copy_region.dstOffset.z = 0; + copy_region.extent.width = resolve_region.extent.width; + copy_region.extent.height = resolve_region.extent.height; + copy_region.extent.depth = 1; + + VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + src_vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region)); + + wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + src_vk_image, src_aspect); + + resolve_region.srcSubresource.aspectMask = src_aspect; + resolve_region.srcSubresource.mipLevel = 0; + resolve_region.srcSubresource.baseArrayLayer = 0; + resolve_region.srcSubresource.layerCount = 1; + resolve_region.srcOffset.x = 0; + resolve_region.srcOffset.y = 0; + resolve_region.srcOffset.z = 0; + } + else + { + src_vk_image = src_texture_vk->vk_image; + + resolve_region.srcSubresource.aspectMask = src_aspect; + resolve_region.srcSubresource.mipLevel = src_level; + resolve_region.srcSubresource.baseArrayLayer = src_layer; + resolve_region.srcSubresource.layerCount = 1; + resolve_region.srcOffset.x = src_rect->left; + resolve_region.srcOffset.y = src_rect->top; + resolve_region.srcOffset.z = 0; + } + + if (dst_texture->resource.format->id != format_id) + { + vr = create_staging_image_for_resolve(context_vk, vk_image_type, vk_format, + resolve_region.extent.width, resolve_region.extent.height, 1, VK_SAMPLE_COUNT_1_BIT, &dst_vk_image); + if (vr != VK_SUCCESS) + goto next; + + wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_vk_image, dst_aspect); + + resolve_region.dstSubresource.mipLevel = 0; + resolve_region.dstSubresource.baseArrayLayer = 0; + resolve_region.dstSubresource.layerCount = 1; + resolve_region.dstOffset.x = 0; + resolve_region.dstOffset.y = 0; + resolve_region.dstOffset.z = 0; + } + else + { + dst_vk_image = dst_texture_vk->vk_image; + + resolve_region.dstSubresource.mipLevel = dst_level; + resolve_region.dstSubresource.baseArrayLayer = dst_layer; + resolve_region.dstSubresource.layerCount = 1; + resolve_region.dstOffset.x = dst_rect->left; + resolve_region.dstOffset.y = dst_rect->top; + resolve_region.dstOffset.z = 0; + } + + VK_CALL(vkCmdResolveImage(vk_command_buffer, src_vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst_vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region)); + + if (dst_vk_image != dst_texture_vk->vk_image) + { + wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst_vk_image, dst_aspect); + + copy_region.srcSubresource.aspectMask = dst_aspect; + copy_region.srcSubresource.mipLevel = 0; + copy_region.srcSubresource.baseArrayLayer = 0; + copy_region.srcSubresource.layerCount = 1; + copy_region.srcOffset.x = 0; + copy_region.srcOffset.y = 0; + copy_region.srcOffset.z = 0; + copy_region.dstSubresource.aspectMask = dst_aspect; + copy_region.dstSubresource.mipLevel = dst_level; + copy_region.dstSubresource.baseArrayLayer = dst_layer; + copy_region.dstSubresource.layerCount = 1; + copy_region.dstOffset.x = dst_rect->left; + copy_region.dstOffset.y = dst_rect->top; + copy_region.dstOffset.z = 0; + copy_region.extent.width = resolve_region.extent.width; + copy_region.extent.height = resolve_region.extent.height; + copy_region.extent.depth = 1; + + VK_CALL(vkCmdCopyImage(vk_command_buffer, dst_vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region)); + } + } + else if (resolve) { VkImageResolve region;
@@ -6606,7 +6962,7 @@ next:
TRACE("Forwarding to blitter %p.\n", next); return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, - src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter, format_id); }
static const struct wined3d_blitter_ops vk_blitter_ops = diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2a75ab5d43d..b141918cefa 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2756,7 +2756,7 @@ struct wined3d_blitter_ops struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, - enum wined3d_texture_filter_type filter); + enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id); };
void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, @@ -4320,7 +4320,7 @@ static inline bool wined3d_texture_is_full_rect(const struct wined3d_texture *te HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, - const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) DECLSPEC_HIDDEN; void texture2d_get_blt_info(const struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info) DECLSPEC_HIDDEN; void texture2d_load_fb_texture(struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, @@ -4710,7 +4710,7 @@ void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs, void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id format_id) DECLSPEC_HIDDEN; void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 96cb6fc1d86..e47f823ea13 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2830,7 +2830,7 @@ HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture UINT layer, const struct wined3d_box *dirty_region); HRESULT __cdecl wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_idx, const RECT *dst_rect_in, struct wined3d_texture *src_texture, unsigned int src_idx, const RECT *src_rect_in, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter); + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter, enum wined3d_format_id); HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
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=86060
Your paranoid android.
=== w8 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w8adm (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w864 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1507 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064 (32 bit report) ===
d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:5658: Test failed: Got unexpected query result 0x0000000000000000. d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w864 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1507 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1809 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064_2qxl (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_ar (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_he (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_ja (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_zh_CN (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== debiant2 (32 bit Chinese:China report) ===
ddraw: ddraw1.c:14219: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1031,794). ddraw1.c:14237: Test failed: Expect window rect (0,0)-(1024,768), got (1024,-8)-(2048,760). ddraw1.c:14244: Test failed: Expect window rect (0,0)-(1024,768), got (1024,-8)-(2048,760).
On Wed, 24 Feb 2021 at 11:41, Jan Sikorski jsikorski@codeweavers.com wrote:
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com
dlls/d3d11/tests/d3d11.c | 18 +- dlls/d3d8/device.c | 6 +- dlls/d3d9/device.c | 4 +- dlls/ddraw/device.c | 2 +- dlls/ddraw/surface.c | 6 +- dlls/wined3d/arb_program_shader.c | 8 +- dlls/wined3d/cs.c | 10 +- dlls/wined3d/device.c | 12 +- dlls/wined3d/glsl_shader.c | 8 +- dlls/wined3d/surface.c | 12 +- dlls/wined3d/swapchain.c | 4 +- dlls/wined3d/texture.c | 440 +++++++++++++++++++++++++++--- dlls/wined3d/wined3d_private.h | 6 +- include/wine/wined3d.h | 2 +- 14 files changed, 448 insertions(+), 90 deletions(-)
There are a couple of different things happening in this patch, please split it. From a quick skim, there's at least: - The change to the public (wined3d_texture_blt()) blitter API - The change to the internal (struct wined3d_blitter_ops) blitter API - Implementation in the FBO blitter - Implementation in the Vulkan blitter
Possibly there's more. For the public API part of this, it may be worth considering storing the resolve format in the wined3d_blt_fx structure, like we do for the colour key.
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=86059
Your paranoid android.
=== w8 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w8adm (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w864 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1507 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064 (32 bit report) ===
d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w864 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1507 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064v1809 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w1064_2qxl (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64 (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_ar (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_he (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_ja (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
=== w10pro64_zh_CN (64 bit report) ===
d3d11: d3d11.c:30376: Test failed: Test 9: expected: 80 19 19 ff, got: 80 1a 1a ff d3d11.c:30376: Test failed: Test 12: expected: 0 19 19 ff, got: 0 1a 1a ff d3d11.c:30376: Test failed: Test 13: expected: 3f c c 7f, got: 40 d d 7f d3d11.c:30376: Test failed: Test 14: expected: 3f 0 0 40, got: 40 0 0 40
Hi Jan,
Henri has asked me to spell out some of the usual style nitpicks :-) . Don't expect any deep understanding of what the test actually does from me...
Am 24.02.21 um 11:40 schrieb Jan Sikorski:
- D3D11_VIEWPORT viewport = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
...
- float clear_color[4] = {0.2f, 0.2f, 0.2f, 1.0f};
You can make data like this static const
- unsigned vertex_buffer_stride = 6 * sizeof(float);
This is ugly, it duplicates data wired into test_multisample_resolve2. Afaics the IASetVertexBuffers can be done once after creating the buffers, which would allow you to simplify run_test_multisample_resolve()
Please use unsigned int instead of unsigned.
- D3D11_MAPPED_SUBRESOURCE staging_mapped = {};
I am not sure if this is valid C, we usually use {0}. If you are assigning all members later on anyway you can also skip the init here. test_state_refcounting() uses a memset, test_create_texture2d() init all fields explicitly. That's a matter of taste IMHO.
A possible idea to trim down the number of boilerplate code is to use just one D3D11_TEXTURE2D_DESC and update only the changed fields between the CreateTexture2D calls.
- hr = ID3D11Device_CreateTexture2D(context->device, &staging_desc, NULL, &staging_texture);
- if (FAILED(hr))
- {
trace("Failed to create staging texture, hr %#x.\n", hr);
return;
- }
Is there a legitimate reason for this to fail? In this case skip() would be appropriate. If you always expect it to succeed just do ok(SUCCEEDED(hr), ...) and let the test fail if CreateTexture2D unexpectedly fails. No need to prevent follow-up failures.
+static void test_multisample_resolve2(void) +{
- D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_0 };
- UINT device_creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
- ID3D11PixelShader *pixel_shader, *pixel_shader_uint;
- struct resolve_test_context context;
- unsigned int i, quality_levels;
- unsigned char result[4];
- HRESULT hr;
- const BYTE vs_code[] =
static const
- {
+#if 0 ... +#endif
68,88,66,67,30,184,39,220,81,141,142,55,98,251,192,170,226,59,
This is different from the way we put the other shader bytecode. Afaics you should be able to tell the MS shader compiler to give you hex dumps.
Personally I can read some stuff out of at least SM <= 3 hex dumps, but with decimal numbers I am lost.
- float vertex_data [] =
- { /* x, y, r, g, b, a */
1.0f, 1.0f, .8f, 0.f, 0.f, 1.f,
1.0f, -1.0f, .8f, 0.f, 0.f, 1.f,
-1.0f, -1.0f, .8f, 0.f, 0.f, 1.f,
- };
We have struct vec2/vec3/vec4 to make the vectorized data types more obvious in the C program.
- hr = ID3D11Device_CreatePixelShader(context.device, ps_code, sizeof(ps_code),
NULL, &pixel_shader);
- if (FAILED(hr))
- {
trace("Failed to create pixel shader, hr %#x.\n", hr);
goto out_2;
- }
- hr = ID3D11Device_CreatePixelShader(context.device, ps_uint_code, sizeof(ps_uint_code),
NULL, &pixel_shader_uint);
- if (FAILED(hr))
- {
trace("Failed to create uint pixel shader, hr %#x.\n", hr);
goto out_3;
- }
Likewise, it's ok to let the test crash if one of those unexpectedly fails. If you do expect failure in some case a skip() is more appropriate, maybe with skipping those tests that need the float/uint pshaders.
As a general rule of thumb, when you init a pile of things and want to gracefully clean them up with a goto, you can init them all to NULL at declaration time, use one goto label and then do an if (pixel_shader_uint) ID3D11PixelShader_Release(pixel_shader_uint). If it's just HeapAlloc'ed then HeapFree will gracefully ignore NULL pointers. This matters more for error handling in the implementation than the tests though.
queue_test(test_multisample_resolve);
- queue_test(test_multisample_resolve2);
This looks unsatisfying :-) . Is it possible to merge them into the existing test_multisample_resolve? Is whatever test_multisample_resolve does already covered by the "new" test? Or, if they are orthogonal, I am sure a better name can be found.
Hi Stefan, Thank you for nitpicking ;) I’ll comply and resend after I get feedback on the other patch too. I don’t love the idea of merging these tests though. They are not fully orthogonal, but don’t exactly do the same thing either, and I don’t see what’s to gain by messing with the old one. I’m flexible on the naming though - how about multisample_resolve_blended? The main difference is that I set it up to take one sample from geometry and the other one from the background. One more thing I’m on the fence about is baking in some tolerance for the results. Right now some of the tests fail because I check the values exactly.
On Wed, 24 Feb 2021 at 13:32, Stefan Dösinger stefandoesinger@gmail.com wrote:
Am 24.02.21 um 11:40 schrieb Jan Sikorski:
- D3D11_MAPPED_SUBRESOURCE staging_mapped = {};
I am not sure if this is valid C, we usually use {0}. If you are assigning all members later on anyway you can also skip the init here. test_state_refcounting() uses a memset, test_create_texture2d() init all fields explicitly. That's a matter of taste IMHO.
More than that, we have existing helpers like get_texture_readback(), get_texture_color(), check_texture_color(), and so on for this kind of thing.
- {
+#if 0 ... +#endif
68,88,66,67,30,184,39,220,81,141,142,55,98,251,192,170,226,59,
This is different from the way we put the other shader bytecode. Afaics you should be able to tell the MS shader compiler to give you hex dumps.
Personally I can read some stuff out of at least SM <= 3 hex dumps, but with decimal numbers I am lost.
Yes, it's much harder to read. Still, I think I can spot most of those shaders don't end with a 0x010003e (ret) token, so they're not stripped. For the tests, you'll want to compile shaders with /Qstrip_reflect, /Qstrip_debug, and /Qstrip_priv for brevity.
Separately, you'll almost always want to use init_test_context() for the initial setup, or at least create_device().
On Wed, 24 Feb 2021 at 15:18, Jan Sikorski jsikorski@codeweavers.com wrote:
One more thing I’m on the fence about is baking in some tolerance for the results. Right now some of the tests fail because I check the values exactly.
Note that we have a compare_color() helper for exactly that purpose. check_texture_color() also uses that internally.