From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/surface.c | 496 ++++++++++++++++++++++++++++++++++ 1 file changed, 496 insertions(+)
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index c618ff6c48a..8d82562f969 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -133,6 +133,46 @@ static HRESULT create_file(const char *filename, const unsigned char *data, cons return D3DERR_INVALIDCALL; }
+static IDirect3DDevice9 *create_device(HWND *window) +{ + D3DPRESENT_PARAMETERS present_parameters = { 0 }; + IDirect3DDevice9 *device; + IDirect3D9 *d3d; + HRESULT hr; + HWND wnd; + + *window = NULL; + + if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, + 640, 480, NULL, NULL, NULL, NULL))) + { + skip("Couldn't create application window.\n"); + return NULL; + } + + if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) + { + skip("Couldn't create IDirect3D9 object.\n"); + DestroyWindow(wnd); + return NULL; + } + + present_parameters.Windowed = TRUE; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, + &present_parameters, &device); + IDirect3D9_Release(d3d); + if (FAILED(hr)) + { + skip("Failed to create IDirect3DDevice9 object %#lx.\n", hr); + DestroyWindow(wnd); + return NULL; + } + + *window = wnd; + return device; +} + /* fills dds_header with reasonable default values */ static void fill_dds_header(struct dds_header *header) { @@ -1150,21 +1190,29 @@ static uint32_t get_bpp_for_d3dformat(D3DFORMAT format) case D3DFMT_Q16W16V16U16: return 8;
+ case D3DFMT_Q8W8V8U8: case D3DFMT_A8B8G8R8: case D3DFMT_A8R8G8B8: case D3DFMT_V16U16: case D3DFMT_G16R16: + case D3DFMT_R32F: return 4;
case D3DFMT_R8G8B8: return 3;
+ case D3DFMT_A4R4G4B4: case D3DFMT_X1R5G5B5: case D3DFMT_A1R5G5B5: + case D3DFMT_R5G6B5: case D3DFMT_V8U8: case D3DFMT_A8P8: return 2;
+ case D3DFMT_R3G3B2: + case D3DFMT_DXT5: + case D3DFMT_DXT4: + case D3DFMT_A4L4: case D3DFMT_L8: case D3DFMT_P8: return 1; @@ -2015,6 +2063,452 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) free(tga); }
+static const uint8_t r8g8b8_4_4[] = +{ + 0xff,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0xff, + 0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff, + 0x00,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0x00,0x80,0x80,0x00, +}; + +static const uint8_t r8g8b8_4_4_expected[] = +{ + 0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff, + 0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0x00,0x00, +}; + +static const uint8_t dxt5_4_4[] = +{ + 0xff,0x00,0x00,0x00,0x00,0x49,0x92,0x24,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,0x00, +}; + +static const uint8_t dxt5_4_4_expected_no_ck[] = +{ + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, +}; + +static const uint8_t dxt5_4_4_expected_ck[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, +}; + +static const uint8_t dxt4_4_4[] = +{ + 0x22,0xcc,0x86,0xc6,0xe6,0x86,0xc6,0xe6,0x10,0x84,0x10,0x84,0x00,0x00,0x00,0x00, +}; + +static const uint8_t dxt4_4_4_expected_no_ck[] = +{ + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x22,0xff,0xff,0xff,0x44,0xff,0xff,0xff,0x66, + 0xf7,0xf3,0xf7,0x88,0xc5,0xc2,0xc5,0xaa,0xa5,0xa2,0xa5,0xcc,0x84,0x82,0x84,0xff, + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x22,0xff,0xff,0xff,0x44,0xff,0xff,0xff,0x66, + 0xf7,0xf3,0xf7,0x88,0xc5,0xc2,0xc5,0xaa,0xa5,0xa2,0xa5,0xcc,0x84,0x82,0x84,0xff, +}; + +static const uint8_t dxt4_4_4_expected_ck[] = +{ + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x22,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x66, + 0xf7,0xf3,0xf7,0x88,0xc5,0xc2,0xc5,0xaa,0xa5,0xa2,0xa5,0xcc,0x84,0x82,0x84,0xff, + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x22,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x66, + 0xf7,0xf3,0xf7,0x88,0xc5,0xc2,0xc5,0xaa,0xa5,0xa2,0xa5,0xcc,0x84,0x82,0x84,0xff, +}; + +static const uint8_t p8_4_4[] = +{ + 0x10,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, +}; + +static const uint8_t p8_4_4_expected[] = +{ + 0x00,0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static const uint8_t a8p8_4_4[] = +{ + 0xff,0x10,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10, +}; + +static const uint8_t a8p8_4_4_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x00,0xc0,0xc0,0x00,0x00,0xc0,0xc0,0x00, + 0x00,0xc0,0xc0,0x00,0x00,0xc0,0xc0,0x00,0x00,0xc0,0xc0,0x00,0x00,0xc0,0xc0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static const uint8_t a32r32g32b32_4_4[] = +{ + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static const uint8_t a32r32g32b32_4_4_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, +}; + +static const uint8_t r32_4_4[] = +{ + 0x00,0x00,0x80,0x3f,0x00,0x00,0x80,0x3f,0x00,0x00,0x80,0x3f,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x80,0x3f,0x00,0x00,0x80,0x3f,0x00,0x00,0x80,0x3f,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f, + 0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f, +}; + +static const uint8_t r32_4_4_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff, + 0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff, +}; + +static const uint8_t q8w8v8u8_4_4[] = +{ + 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0, + 0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x74,0x84,0x94,0xa4,0xb4,0xc4,0xd4,0xe4,0xf4, + 0x00,0x00,0x28,0x38,0x48,0x58,0x68,0x78,0x88,0x98,0xa8,0xb8,0xc8,0xd8,0xe8,0xf8, + 0x0c,0x1c,0x2c,0x3c,0x4c,0x5c,0x6c,0x7c,0x8c,0x9c,0xac,0xbc,0xcc,0xdc,0xec,0xfc, +}; + +static const uint8_t q8w8v8u8_4_4_expected[] = +{ + 0xa0,0x90,0x80,0xb0,0xe0,0xd0,0xc0,0xf0,0x1f,0x0f,0x00,0x2f,0x5f,0x4f,0x3f,0x6f, + 0xa4,0x94,0x84,0xb4,0xe4,0xd4,0xc4,0xf4,0x23,0x13,0x03,0x33,0x63,0x53,0x43,0x73, + 0x80,0x80,0x80,0x80,0xe8,0xd8,0xc8,0xf8,0x27,0x17,0x07,0x37,0x67,0x57,0x47,0x77, + 0xac,0x9c,0x8c,0xbc,0xec,0xdc,0xcc,0xfc,0x2b,0x1b,0x0b,0x3b,0x6b,0x5b,0x4b,0x7b, +}; + +static const uint8_t a8r8g8b8_4_4[] = +{ + 0x00,0xff,0x00,0x80,0x00,0xff,0x00,0x80,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff, + 0x80,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff, +}; + +static const uint8_t a8r8g8b8_4_4_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff, + 0x80,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff, +}; + +static const uint8_t a4r4g4b4_4_4[] = +{ + 0xff,0x00,0x0f,0x00,0x00,0xf0,0x00,0x0f,0xf0,0x00,0xf0,0x00,0xf0,0x00,0xf0,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const uint8_t a4r4g4b4_4_4_expected[] = +{ + 0xff,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static const uint8_t a4r4g4b4_4_4_expected2[] = +{ + 0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88, + 0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88, +}; + +static const uint8_t a4l4_4_4[] = +{ + 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff, +}; + +static const uint8_t a4l4_4_4_expected[] = +{ + 0x00,0x00,0x00,0x00,0x11,0x11,0x11,0x11,0x22,0x22,0x22,0x22,0x33,0x33,0x33,0x33, + 0x44,0x44,0x44,0x44,0x55,0x55,0x55,0x55,0x66,0x66,0x66,0x66,0x77,0x77,0x77,0x77, + 0x00,0x00,0x00,0x00,0x99,0x99,0x99,0x99,0xaa,0xaa,0xaa,0xaa,0xbb,0xbb,0xbb,0xbb, + 0xcc,0xcc,0xcc,0xcc,0xdd,0xdd,0xdd,0xdd,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff, +}; + +static const uint8_t a4l4_4_4_expected2[] = +{ + 0x00,0x00,0x00,0x00,0x11,0x11,0x11,0x11,0x22,0x22,0x22,0x22,0x33,0x33,0x33,0x33, + 0x44,0x44,0x44,0x44,0x55,0x55,0x55,0x55,0x66,0x66,0x66,0x66,0x77,0x77,0x77,0x77, + 0x88,0x88,0x88,0x88,0x99,0x99,0x99,0x99,0xaa,0xaa,0xaa,0xaa,0xbb,0xbb,0xbb,0xbb, + 0xcc,0xcc,0xcc,0xcc,0xdd,0xdd,0xdd,0xdd,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff, +}; + +static const uint8_t a1r5g5b5_4_4[] = +{ + 0x00,0x00,0x42,0x08,0x84,0x10,0xc6,0x18,0x08,0x21,0x4a,0x29,0x8c,0x31,0xce,0x39, + 0x10,0xc2,0x52,0xca,0x94,0xd2,0xd6,0xda,0x18,0xe3,0x5a,0xeb,0x9c,0xf3,0xde,0xfb, +}; + +static const uint8_t a1r5g5b5_4_4_expected[] = +{ + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x00,0x21,0x21,0x21,0x00,0x31,0x31,0x31,0x00, + 0x42,0x42,0x42,0x00,0x52,0x52,0x52,0x00,0x63,0x63,0x63,0x00,0x73,0x73,0x73,0x00, + 0x84,0x84,0x84,0xff,0x94,0x94,0x94,0xff,0x00,0x00,0x00,0x00,0xb5,0xb5,0xb5,0xff, + 0xc5,0xc5,0xc5,0xff,0xd6,0xd6,0xd6,0xff,0xe6,0xe6,0xe6,0xff,0xf7,0xf7,0xf7,0xff, +}; + +static const uint8_t r5g6b5_4_4[] = +{ + 0x00,0x00,0x82,0x10,0x04,0x21,0x86,0x31,0x08,0x42,0x8a,0x52,0x0c,0x63,0x8e,0x73, + 0x10,0x84,0x92,0x94,0x14,0xa5,0x96,0xb5,0x18,0xc6,0x9a,0xd6,0x1c,0xe7,0x9e,0xf7, +}; + +static const uint8_t r5g6b5_4_4_expected[] = +{ + 0x00,0x00,0x00,0xff,0x10,0x10,0x10,0xff,0x21,0x20,0x21,0xff,0x31,0x31,0x31,0xff, + 0x42,0x41,0x42,0xff,0x52,0x51,0x52,0xff,0x63,0x61,0x63,0xff,0x73,0x71,0x73,0xff, + 0x84,0x82,0x84,0xff,0x94,0x92,0x94,0xff,0x00,0x00,0x00,0x00,0xb5,0xb2,0xb5,0xff, + 0xc5,0xc2,0xc5,0xff,0xd6,0xd2,0xd6,0xff,0xe6,0xe3,0xe6,0xff,0xf7,0xf3,0xf7,0xff, +}; + +static const uint8_t r3g3b2_4_4[] = +{ + 0x00,0x00,0x24,0x24,0x49,0x49,0x6d,0x6d,0x92,0x92,0xb6,0xb6,0xdb,0xdb,0xff,0xff, +}; + +static const uint8_t r3g3b2_4_4_expected[] = +{ + 0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x24,0x24,0xff,0x00,0x24,0x24,0xff, + 0x55,0x49,0x49,0xff,0x55,0x49,0x49,0xff,0x55,0x6d,0x6d,0xff,0x55,0x6d,0x6d,0xff, + 0xaa,0x92,0x92,0xff,0xaa,0x92,0x92,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xdb,0xdb,0xff,0xff,0xdb,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +}; + +static BOOL is_dxt_d3dformat(D3DFORMAT fmt); +static void test_color_key(void) +{ + static const struct + { + D3DFORMAT src_format; + const void *src_data; + + const void *expected_dst_data; + D3DCOLOR color_key; + const void *expected_dst_data_32; + BOOL todo; + } tests[] = + { + /* Color key with alpha channel unset. */ + { + D3DFMT_R8G8B8, r8g8b8_4_4, r8g8b8_4_4_expected, 0x00008080, + .todo = TRUE + }, + /* Same color key as before except the alpha channel is set. */ + { + D3DFMT_R8G8B8, r8g8b8_4_4, r8g8b8_4_4_expected, 0xff008080, + .todo = TRUE + }, + /* Color key on a palette. */ + { + D3DFMT_P8, p8_4_4, p8_4_4_expected, 0xf0c0c000, + .todo = TRUE + }, + { + D3DFMT_A8P8, a8p8_4_4, a8p8_4_4_expected, 0x10c0c000, + .todo = TRUE + }, + { + D3DFMT_A32B32G32R32F, a32r32g32b32_4_4, a32r32g32b32_4_4_expected, 0xffff0000, + .todo = TRUE + }, + /* 5. */ + /* + * Only channels that exist in the source format matter for the color + * key, other channels can be set to any value and are ignored. + */ + { + D3DFMT_R32F, r32_4_4, r32_4_4_expected, 0xffff3080, + .todo = TRUE + }, + /* + * Both 0x7f and 0x80 channel values in the color key map to 0x00 in + * 8-bit SNORM. + */ + { + D3DFMT_Q8W8V8U8, q8w8v8u8_4_4, q8w8v8u8_4_4_expected, 0xb87f80a8, + .todo = TRUE + }, + /* Alpha channel factors into the color key check. */ + { + D3DFMT_A8R8G8B8, a8r8g8b8_4_4, a8r8g8b8_4_4_expected, 0x8000ff00, + .todo = TRUE + }, + { + D3DFMT_A8R8G8B8, a8r8g8b8_4_4, a8r8g8b8_4_4, 0x0000ff00, + }, + /* + * 0x80-0x90 color key channel values all match 0x8 in the source + * format. + */ + { + D3DFMT_A4R4G4B4, a4r4g4b4_4_4, a4r4g4b4_4_4_expected, 0x80009000, + .todo = TRUE + }, + /* 10. */ + /* 0xf7-0xff match 0xf in the source format. */ + { + D3DFMT_A4R4G4B4, a4r4g4b4_4_4, a4r4g4b4_4_4_expected2, 0x0000f7ff, + .todo = TRUE + }, + { + D3DFMT_A4L4, a4l4_4_4, a4l4_4_4_expected, 0x88818283, + .todo = TRUE + }, + { + D3DFMT_A4L4, a4l4_4_4, a4l4_4_4_expected2, 0x88818200, + }, + { + D3DFMT_A1R5G5B5, a1r5g5b5_4_4, a1r5g5b5_4_4_expected, 0x80a1a8a4, + .todo = TRUE + }, + { + D3DFMT_R5G6B5, r5g6b5_4_4, r5g6b5_4_4_expected, 0x81a1a0a8, + .todo = TRUE + }, + /* 15. */ + { + D3DFMT_R3G3B2, r3g3b2_4_4, r3g3b2_4_4_expected, 0x81a4c8bf, + .todo = TRUE + }, + /* + * Test color key handling for compressed formats. On 64-bit the color key + * is used, but on 32-bit it is ignored. + */ + { + D3DFMT_DXT5, dxt5_4_4, dxt5_4_4_expected_ck, 0xffff0000, dxt5_4_4_expected_no_ck, + .todo = TRUE + }, + /* + * Test premultiplied alpha handling with a color key - color key applies + * to the value after the premultiplied alpha transformation is undone. + */ + { + D3DFMT_DXT4, dxt4_4_4, dxt4_4_4_expected_ck, 0x44ffffff, dxt4_4_4_expected_no_ck, + .todo = TRUE + }, + /* + * Color key also has the same range of values as R5G6B5 for the color + * channels. + */ + { + D3DFMT_DXT4, dxt4_4_4, dxt4_4_4_expected_ck, 0x44fbfdfb, dxt4_4_4_expected_no_ck, + .todo = TRUE + }, + /* Values out of range for R5G6B5, won't be color keyed. */ + { + D3DFMT_DXT4, dxt4_4_4, dxt4_4_4_expected_no_ck, 0x44fafcfa, + .todo = TRUE + }, + }; + unsigned int i, x, y, mismatch_count; + PALETTEENTRY tmp_palette[256]; + const uint8_t *expected_dst; + IDirect3DDevice9 *device; + D3DLOCKED_RECT lock_rect; + IDirect3DSurface9 *surf; + uint32_t src_pitch; + RECT rect; + HRESULT hr; + HWND hwnd; + + if (!(device = create_device(&hwnd))) + return; + + memcpy(tmp_palette, test_palette, sizeof(test_palette)); + /* Set palette entries 0xf1-0xff to the same value. */ + for (i = 0; i < 0xf; ++i) + tmp_palette[0xf1 + i] = tmp_palette[0xf0]; + + SetRect(&rect, 0, 0, 4, 4); + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surf, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("Test %u", i); + + mismatch_count = 0; + src_pitch = get_bpp_for_d3dformat(tests[i].src_format) * 4; + hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, tests[i].src_data, tests[i].src_format, + src_pitch, tmp_palette, &rect, D3DX_FILTER_NONE, tests[i].color_key); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (sizeof(void *) == 4 && tests[i].expected_dst_data_32) + expected_dst = tests[i].expected_dst_data_32; + else + expected_dst = tests[i].expected_dst_data; + + IDirect3DSurface9_LockRect(surf, &lock_rect, NULL, D3DLOCK_READONLY); + for (y = 0; y < 4; ++y) + { + const uint8_t *dst_expected_row = ((const uint8_t *)expected_dst) + (sizeof(uint32_t) * 4 * y); + const uint8_t *dst_row = ((const uint8_t *)lock_rect.pBits) + (lock_rect.Pitch * y); + + for (x = 0; x < 4; ++x) + { + const uint32_t dst_expected_color = ((const uint32_t *)dst_expected_row)[x]; + const uint32_t dst_color = ((const uint32_t *)dst_row)[x]; + + if (!compare_color_4bpp(dst_color, dst_expected_color, 0)) + mismatch_count++; + } + } + IDirect3DSurface9_UnlockRect(surf); + + todo_wine_if(tests[i].todo) ok(!mismatch_count, "Unexpected number of mismatched pixels %u.\n", mismatch_count); + winetest_pop_context(); + } + + /* + * Trying to use D3DX_FILTER_SRGB_IN with a color key results in + * STATUS_ACCESS_VIOLATION on native. + */ + if (0) + { + const uint32_t src_pitch = get_bpp_for_d3dformat(tests[0].src_format) * 4; + + hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, tests[0].src_data, tests[0].src_format, + src_pitch, NULL, &rect, D3DX_FILTER_NONE | D3DX_FILTER_SRGB_IN, + tests[0].color_key); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + } + + check_release((IUnknown *)surf, 0); + check_release((IUnknown *)device, 0); + DestroyWindow(hwnd); +} + static void test_D3DXLoadSurface(IDirect3DDevice9 *device) { HRESULT hr; @@ -4651,4 +5145,6 @@ START_TEST(surface) check_release((IUnknown*)device, 0); check_release((IUnknown*)d3d, 0); DestroyWindow(wnd); + + test_color_key(); }