From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 59 ++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/surface.c | 49 +++++++++++++---------------- 2 files changed, 80 insertions(+), 28 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index e6ee986dace..a091de45467 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -579,6 +579,13 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix if (FAILED(hr)) goto exit;
+ /* + * Encode 32bpp BGRA format surfaces as 32bpp BGRX for BMP. + * This matches the behavior of native. + */ + if (IsEqualGUID(&GUID_ContainerFormatBmp, container_format) && (fmt_desc->format == D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM)) + pixel_format_guid = wic_guid_from_d3dx_pixel_format_id(D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM); + wic_pixel_format = *pixel_format_guid; hr = IWICBitmapFrameEncode_SetPixelFormat(wic_frame, &wic_pixel_format); if (FAILED(hr)) @@ -653,6 +660,38 @@ static const enum d3dx_pixel_format_id jpg_save_pixel_formats[] = D3DX_PIXEL_FORMAT_B8G8R8_UNORM, };
+static const enum d3dx_pixel_format_id bmp_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_B5G5R5X1_UNORM, + D3DX_PIXEL_FORMAT_B5G6R5_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM, +}; + +static const enum d3dx_pixel_format_id unimplemented_bmp_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_P8_UINT, + D3DX_PIXEL_FORMAT_A8_UNORM, + D3DX_PIXEL_FORMAT_P8_UINT_A8_UNORM, + D3DX_PIXEL_FORMAT_L8A8_UNORM, + D3DX_PIXEL_FORMAT_L16_UNORM, + D3DX_PIXEL_FORMAT_B2G3R3_UNORM, + D3DX_PIXEL_FORMAT_R16_FLOAT, + D3DX_PIXEL_FORMAT_R16G16_FLOAT, + D3DX_PIXEL_FORMAT_R16G16_UNORM, + D3DX_PIXEL_FORMAT_R32_FLOAT, + D3DX_PIXEL_FORMAT_R32G32_FLOAT, + D3DX_PIXEL_FORMAT_B4G4R4X4_UNORM, + D3DX_PIXEL_FORMAT_B4G4R4A4_UNORM, + D3DX_PIXEL_FORMAT_B2G3R3A8_UNORM, + D3DX_PIXEL_FORMAT_B5G5R5A1_UNORM, + D3DX_PIXEL_FORMAT_R8G8B8X8_UNORM, + D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM, + D3DX_PIXEL_FORMAT_B10G10R10A2_UNORM, + D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM, +}; + static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enum d3dx_pixel_format_id *format_ids, uint32_t format_ids_size, enum d3dx_pixel_format_id format_id) { @@ -768,6 +807,23 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const dst_format); break;
+ case D3DXIFF_BMP: + { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(unimplemented_bmp_save_pixel_formats); ++i) + { + if (unimplemented_bmp_save_pixel_formats[i] == dst_format) + { + FIXME("Saving pixel format %d to BMP files is currently unsupported.\n", dst_format); + return E_NOTIMPL; + } + } + dst_format = d3dx_get_closest_d3dx_pixel_format_id(bmp_save_pixel_formats, ARRAY_SIZE(bmp_save_pixel_formats), + dst_format); + break; + } + default: assert(0 && "Unexpected file format."); return E_FAIL; @@ -838,6 +894,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const
case D3DXIFF_PNG: case D3DXIFF_JPG: + case D3DXIFF_BMP: if (src_fmt_desc == dst_fmt_desc) dst_pixels = *src_pixels; else @@ -3275,7 +3332,6 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); switch (file_format) { - case D3DXIFF_BMP: case D3DXIFF_DIB: container_format = &GUID_ContainerFormatBmp; break; @@ -3283,6 +3339,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE case D3DXIFF_TGA: case D3DXIFF_PNG: case D3DXIFF_JPG: + case D3DXIFF_BMP: return save_surface_to_memory(dst_buffer, src_surface, src_palette, src_rect, file_format); case D3DXIFF_HDR: case D3DXIFF_PFM: diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 7a92d01ec50..887c1a793cb 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3932,16 +3932,11 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, /* - * We don't match formats here because we encode our BMP headers - * differently. Native encodes with the same header as - * D3DFMT_X8R8G8B8, it just sets the values in the alpha channel. The - * format is distinguished by checking the image. We encode a bitmap - * V4 header with a dedicated alpha mask, so we'll always report - * D3DFMT_A8R8G8B8, regardless of whether or not any alpha channel - * values are non-zero. + * For BMP/DIB, these encode as D3DFMT_X8R8G8B8. If there's at least + * one pixel with a non-zero alpha channel, it reports as D3DFMT_A8R8G8B8. */ { D3DFMT_A8R8G8B8, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, }, @@ -4100,7 +4095,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A16B16G16R16, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, @@ -4144,7 +4139,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A4L4, NULL, 0x00, - { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A4R4G4B4, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4183,7 +4178,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT1, NULL, 0x00, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4194,7 +4189,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT2, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4205,7 +4200,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT2, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4216,7 +4211,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT3, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4227,7 +4222,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT3, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4238,7 +4233,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT4, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4249,7 +4244,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT4, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4260,7 +4255,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT5, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4271,7 +4266,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT5, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4304,7 +4299,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A16B16G16R16F, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, @@ -4337,7 +4332,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A32B32G32R32F, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, @@ -4348,7 +4343,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_Q8W8V8U8, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4359,7 +4354,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_V8U8, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4370,7 +4365,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_V16U16, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4381,7 +4376,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_X8L8V8U8, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4392,7 +4387,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A2W10V10U10, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4403,7 +4398,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_Q16W16V16U16, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL },