diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index fdfcf8a5d4b..879240ae1a4 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -93,6 +93,109 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO IUnknown_Release(unk); } +struct d3d11_resource_readback +{ + ID3D11Resource *resource; + D3D11_MAPPED_SUBRESOURCE map_desc; + ID3D11DeviceContext *immediate_context; + unsigned int width, height, depth, sub_resource_idx; +}; + +static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource, + unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx, + ID3D11Device *device, struct d3d11_resource_readback *rb) +{ + HRESULT hr; + + rb->resource = readback_resource; + rb->width = width; + rb->height = height; + rb->depth = depth; + rb->sub_resource_idx = sub_resource_idx; + + ID3D11Device_GetImmediateContext(device, &rb->immediate_context); + + ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource); + if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context, + rb->resource, sub_resource_idx, D3D11_MAP_READ, 0, &rb->map_desc))) + { + trace("Failed to map resource, hr %#x.\n", hr); + ID3D11Resource_Release(rb->resource); + rb->resource = NULL; + ID3D11DeviceContext_Release(rb->immediate_context); + rb->immediate_context = NULL; + } +} + +static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx, + struct d3d11_resource_readback *rb) +{ + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11Resource *rb_texture; + unsigned int miplevel; + ID3D11Device *device; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + + ID3D11Texture2D_GetDevice(texture, &device); + + ID3D11Texture2D_GetDesc(texture, &texture_desc); + texture_desc.Usage = D3D11_USAGE_STAGING; + texture_desc.BindFlags = 0; + texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + texture_desc.MiscFlags = 0; + if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture))) + { + trace("Failed to create texture, hr %#x.\n", hr); + ID3D11Device_Release(device); + return; + } + + miplevel = sub_resource_idx % texture_desc.MipLevels; + init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture, + max(1, texture_desc.Width >> miplevel), + max(1, texture_desc.Height >> miplevel), + 1, sub_resource_idx, device, rb); + + ID3D11Device_Release(device); +} + +static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb) +{ + ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx); + ID3D11Resource_Release(rb->resource); + ID3D11DeviceContext_Release(rb->immediate_context); +} + +static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb, + unsigned int x, unsigned int y, unsigned int z, unsigned byte_width) +{ + return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width; +} + +static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z) +{ + return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD)); +} + +static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z) +{ + return get_d3d11_readback_u32(rb, x, y, z); +} + +static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y) +{ + struct d3d11_resource_readback rb; + DWORD color; + + get_d3d11_texture2d_readback(texture, 0, &rb); + color = get_d3d11_readback_color(&rb, x, y, 0); + release_d3d11_resource_readback(&rb); + + return color; +} + static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags, const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out, D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context); @@ -6201,6 +6304,7 @@ static ID3D11Device *create_d3d11_device(void) static void test_dxgi_surface_buffer(void) { + DWORD max_length, cur_length, color; IMFDXGIBuffer *dxgi_buffer; D3D11_TEXTURE2D_DESC desc; ID3D11Texture2D *texture; @@ -6280,6 +6384,40 @@ static void test_dxgi_surface_buffer(void) IMFDXGIBuffer_Release(dxgi_buffer); + /* Texture updates. */ + color = get_d3d11_texture_color(texture, 0, 0); + ok(!color, "Unexpected texture color %#x.\n", color); + + max_length = cur_length = 0; + data = NULL; + hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(max_length && max_length == cur_length, "Unexpected length %u.\n", max_length); +} + if (data) *(DWORD *)data = ~0u; + + color = get_d3d11_texture_color(texture, 0, 0); + ok(!color, "Unexpected texture color %#x.\n", color); + + hr = IMFMediaBuffer_Unlock(buffer); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + color = get_d3d11_texture_color(texture, 0, 0); +todo_wine + ok(color == ~0u, "Unexpected texture color %#x.\n", color); + + hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + ok(*(DWORD *)data == ~0u, "Unexpected buffer %#x.\n", *(DWORD *)data); + + hr = IMFMediaBuffer_Unlock(buffer); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFMediaBuffer_Release(buffer); ID3D11Texture2D_Release(texture);