The last of the saving patches for d3dx9. :)
-- v3: d3dx9: Add support for saving IDirect3DVolumeTexture9 textures to DDS files in D3DXSaveTextureToFileInMemory(). d3dx9: Add support for saving IDirect3DCubeTexture9 textures to DDS files in D3DXSaveTextureToFileInMemory(). d3dx9: Add support for saving IDirect3DTexture9 textures to DDS files in D3DXSaveTextureToFileInMemory(). d3dx9/tests: Add more tests for saving textures to DDS files.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 3 + dlls/d3dx9_36/tests/texture.c | 116 +++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 3813461bc9b..e5a9207ad91 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -580,6 +580,9 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix if (FAILED(hr)) goto exit;
+ if (image_file_format == D3DXIFF_JPG) + FIXME("JPEG saving quality adjustment currently unimplemented, expect lower quality JPEG.\n"); + hr = IWICBitmapFrameEncode_SetSize(wic_frame, pixels->size.width, pixels->size.height); if (FAILED(hr)) goto exit; diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 1c8ba0507b3..b6ca3b2738f 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -176,6 +176,23 @@ static BOOL compare_color(DWORD c1, DWORD c2, BYTE max_diff) && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); }
+static uint8_t pixel_4bpp_max_channel_diff(uint32_t c1, uint32_t c2) +{ + uint8_t max_diff = 0; + unsigned int i; + + for (i = 0; i < 4; ++i) + { + uint8_t x, y; + + x = (c1 >> (i * 8)) & 0xff; + y = (c2 >> (i * 8)) & 0xff; + max_diff = max(max_diff, (x > y ? x - y : y - x)); + } + + return max_diff; +} + struct surface_readback { IDirect3DSurface9 *surface; @@ -3089,8 +3106,42 @@ static void WINAPI fill_cube_positive_x(D3DXVECTOR4 *out, const D3DXVECTOR3 *tex out->x = 1; }
+static void set_vec2(D3DXVECTOR2 *v, float x, float y) +{ + v->x = x; + v->y = y; +} + +static const D3DXVECTOR4 quadrant_color[] = +{ + { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, +}; + +static void WINAPI fill_func(D3DXVECTOR4 *value, const D3DXVECTOR2 *coord, const D3DXVECTOR2 *size, void *data) +{ + D3DXVECTOR2 vec = *coord; + unsigned int idx; + + if (data) + { + *value = *(D3DXVECTOR4 *)data; + return; + } + + set_vec2(&vec, (vec.x / size->x) - 0.5f, (vec.y / size->y) - 0.5f); + if (vec.x < 8.0f) + idx = vec.y < 8.0f ? 0 : 2; + else + idx = vec.y < 8.0f ? 1 : 3; + + *value = quadrant_color[idx]; +} + static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) { + const D3DXVECTOR4 clear_val = { 0.0f, 0.0f, 0.0f, 0.0f }; + IDirect3DSurface9 *surface; + struct surface_readback rb; HRESULT hr; IDirect3DTexture9 *texture; IDirect3DCubeTexture9 *cube_texture; @@ -3165,8 +3216,6 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); if (SUCCEEDED(hr)) { - IDirect3DSurface9 *surface; - buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); buffer_size = ID3DXBuffer_GetBufferSize(buffer); hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); @@ -3269,6 +3318,69 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) }
IDirect3DVolumeTexture9_Release(volume_texture); + + /* Test JPEG compression quality. */ + hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXFillTexture(texture, fill_func, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_JPG, (IDirect3DBaseTexture9 *)texture, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXFillTexture(texture, fill_func, (void *)&clear_val); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, ID3DXBuffer_GetBufferPointer(buffer), + ID3DXBuffer_GetBufferSize(buffer), NULL, D3DX_FILTER_NONE, 0, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_Release(surface); + ID3DXBuffer_Release(buffer); + + /* + * Wine's JPEG compression quality is worse than native. Native uses 4:2:0 + * subsampling which is the same as what we use, but whatever compression + * settings they're using results in a JPEG image that is much closer to + * the original uncompressed surface. This is most apparent in 16x16 + * blocks with multiple colors. + */ + get_texture_surface_readback(device, texture, 0, &rb); + /* 64-bit Windows has worse JPEG compression. */ + if (sizeof(void *) == 8) + { + todo_wine ok(compare_color(get_readback_color(&rb, 0, 0), 0xffff0000, 5), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 0, 0), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 0, 0), 0xffff0000)); + todo_wine ok(compare_color(get_readback_color(&rb, 15, 0), 0xff00ff00, 3), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 15, 0), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 15, 0), 0xff00ff00)); + todo_wine ok(compare_color(get_readback_color(&rb, 0, 15), 0xff0000ff, 6), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 0, 15), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 0, 15), 0xff0000ff)); + } + else + { + todo_wine ok(compare_color(get_readback_color(&rb, 0, 0), 0xffff0000, 1), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 0, 0), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 0, 0), 0xffff0000)); + todo_wine ok(compare_color(get_readback_color(&rb, 15, 0), 0xff00ff00, 1), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 15, 0), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 15, 0), 0xff00ff00)); + todo_wine ok(compare_color(get_readback_color(&rb, 0, 15), 0xff0000ff, 2), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 0, 15), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 0, 15), 0xff0000ff)); + } + todo_wine ok(compare_color(get_readback_color(&rb, 15, 15), 0xffffffff, 1), + "Unexpected color %#x, max_diff %d.\n", get_readback_color(&rb, 15, 15), + pixel_4bpp_max_channel_diff(get_readback_color(&rb, 15, 15), 0xffffffff)); + release_surface_readback(&rb); + + IDirect3DTexture9_Release(texture); }
static void test_texture_shader(void)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/d3dx9_test_images.h | 86 +++++++++++ dlls/d3dx9_36/tests/surface.c | 83 ----------- dlls/d3dx9_36/tests/texture.c | 181 ++++++++++++++++++++++++ 3 files changed, 267 insertions(+), 83 deletions(-)
diff --git a/dlls/d3dx9_36/tests/d3dx9_test_images.h b/dlls/d3dx9_36/tests/d3dx9_test_images.h index f79e9f68894..3ed5373c705 100644 --- a/dlls/d3dx9_36/tests/d3dx9_test_images.h +++ b/dlls/d3dx9_36/tests/d3dx9_test_images.h @@ -72,6 +72,9 @@ struct dds_header DWORD reserved2; };
+#define DDS_FILE_HEADER_SIZE (sizeof(uint32_t) + sizeof(struct dds_header)) +#define PALETTED_DDS_FILE_HEADER_SIZE (DDS_FILE_HEADER_SIZE + (sizeof(PALETTEENTRY) * 256)) + static const struct { uint32_t filter; @@ -91,6 +94,89 @@ test_filter_values[] = { 0xff800001, D3DERR_INVALIDCALL }, };
+static const PALETTEENTRY test_palette[256] = +{ + {0x00,0x00,0x00,0x00}, {0x00,0x00,0x80,0x01}, {0x00,0x80,0x00,0x02}, {0x00,0x80,0x80,0x03}, + {0x80,0x00,0x00,0x04}, {0x80,0x00,0x80,0x05}, {0x80,0x80,0x00,0x06}, {0xc0,0xc0,0xc0,0x07}, + {0xc0,0xdc,0xc0,0x08}, {0xf0,0xca,0xa6,0x09}, {0x00,0x20,0x40,0x0a}, {0x00,0x20,0x60,0x0b}, + {0x00,0x20,0x80,0x0c}, {0x00,0x20,0xa0,0x0d}, {0x00,0x20,0xc0,0x0e}, {0x00,0x20,0xe0,0x0f}, + + {0x00,0x40,0x00,0x10}, {0x00,0x40,0x20,0x11}, {0x00,0x40,0x40,0x12}, {0x00,0x40,0x60,0x13}, + {0x00,0x40,0x80,0x14}, {0x00,0x40,0xa0,0x15}, {0x00,0x40,0xc0,0x16}, {0x00,0x40,0xe0,0x17}, + {0x00,0x60,0x00,0x18}, {0x00,0x60,0x20,0x19}, {0x00,0x60,0x40,0x1a}, {0x00,0x60,0x60,0x1b}, + {0x00,0x60,0x80,0x1c}, {0x00,0x60,0xa0,0x1d}, {0x00,0x60,0xc0,0x1e}, {0x00,0x60,0xe0,0x1f}, + + {0x00,0x80,0x00,0x20}, {0x00,0x80,0x20,0x21}, {0x00,0x80,0x40,0x22}, {0x00,0x80,0x60,0x23}, + {0x00,0x80,0x80,0x24}, {0x00,0x80,0xa0,0x25}, {0x00,0x80,0xc0,0x26}, {0x00,0x80,0xe0,0x27}, + {0x00,0xa0,0x00,0x28}, {0x00,0xa0,0x20,0x29}, {0x00,0xa0,0x40,0x2a}, {0x00,0xa0,0x60,0x2b}, + {0x00,0xa0,0x80,0x2c}, {0x00,0xa0,0xa0,0x2d}, {0x00,0xa0,0xc0,0x2e}, {0x00,0xa0,0xe0,0x2f}, + + {0x00,0xc0,0x00,0x30}, {0x00,0xc0,0x20,0x31}, {0x00,0xc0,0x40,0x32}, {0x00,0xc0,0x60,0x33}, + {0x00,0xc0,0x80,0x34}, {0x00,0xc0,0xa0,0x35}, {0x00,0xc0,0xc0,0x36}, {0x00,0xc0,0xe0,0x37}, + {0x00,0xe0,0x00,0x38}, {0x00,0xe0,0x20,0x39}, {0x00,0xe0,0x40,0x3a}, {0x00,0xe0,0x60,0x3b}, + {0x00,0xe0,0x80,0x3c}, {0x00,0xe0,0xa0,0x3d}, {0x00,0xe0,0xc0,0x3e}, {0x00,0xe0,0xe0,0x3f}, + + {0x40,0x00,0x00,0x40}, {0x40,0x00,0x20,0x41}, {0x40,0x00,0x40,0x42}, {0x40,0x00,0x60,0x43}, + {0x40,0x00,0x80,0x44}, {0x40,0x00,0xa0,0x45}, {0x40,0x00,0xc0,0x46}, {0x40,0x00,0xe0,0x47}, + {0x40,0x20,0x00,0x48}, {0x40,0x20,0x20,0x49}, {0x40,0x20,0x40,0x4a}, {0x40,0x20,0x60,0x4b}, + {0x40,0x20,0x80,0x4c}, {0x40,0x20,0xa0,0x4d}, {0x40,0x20,0xc0,0x4e}, {0x40,0x20,0xe0,0x4f}, + + {0x40,0x40,0x00,0x50}, {0x40,0x40,0x20,0x51}, {0x40,0x40,0x40,0x52}, {0x40,0x40,0x60,0x53}, + {0x40,0x40,0x80,0x54}, {0x40,0x40,0xa0,0x55}, {0x40,0x40,0xc0,0x56}, {0x40,0x40,0xe0,0x57}, + {0x40,0x60,0x00,0x58}, {0x40,0x60,0x20,0x59}, {0x40,0x60,0x40,0x5a}, {0x40,0x60,0x60,0x5b}, + {0x40,0x60,0x80,0x5c}, {0x40,0x60,0xa0,0x5d}, {0x40,0x60,0xc0,0x5e}, {0x40,0x60,0xe0,0x5f}, + + {0x40,0x80,0x00,0x60}, {0x40,0x80,0x20,0x61}, {0x40,0x80,0x40,0x62}, {0x40,0x80,0x60,0x63}, + {0x40,0x80,0x80,0x64}, {0x40,0x80,0xa0,0x65}, {0x40,0x80,0xc0,0x66}, {0x40,0x80,0xe0,0x67}, + {0x40,0xa0,0x00,0x68}, {0x40,0xa0,0x20,0x69}, {0x40,0xa0,0x40,0x6a}, {0x40,0xa0,0x60,0x6b}, + {0x40,0xa0,0x80,0x6c}, {0x40,0xa0,0xa0,0x6d}, {0x40,0xa0,0xc0,0x6e}, {0x40,0xa0,0xe0,0x6f}, + + {0x40,0xc0,0x00,0x70}, {0x40,0xc0,0x20,0x71}, {0x40,0xc0,0x40,0x72}, {0x40,0xc0,0x60,0x73}, + {0x40,0xc0,0x80,0x74}, {0x40,0xc0,0xa0,0x75}, {0x40,0xc0,0xc0,0x76}, {0x40,0xc0,0xe0,0x77}, + {0x40,0xe0,0x00,0x78}, {0x40,0xe0,0x20,0x79}, {0x40,0xe0,0x40,0x7a}, {0x40,0xe0,0x60,0x7b}, + {0x40,0xe0,0x80,0x7c}, {0x40,0xe0,0xa0,0x7d}, {0x40,0xe0,0xc0,0x7e}, {0x40,0xe0,0xe0,0x7f}, + + {0x80,0x00,0x00,0x80}, {0x80,0x00,0x20,0x81}, {0x80,0x00,0x40,0x82}, {0x80,0x00,0x60,0x83}, + {0x80,0x00,0x80,0x84}, {0x80,0x00,0xa0,0x85}, {0x80,0x00,0xc0,0x86}, {0x80,0x00,0xe0,0x87}, + {0x80,0x20,0x00,0x88}, {0x80,0x20,0x20,0x89}, {0x80,0x20,0x40,0x8a}, {0x80,0x20,0x60,0x8b}, + {0x80,0x20,0x80,0x8c}, {0x80,0x20,0xa0,0x8d}, {0x80,0x20,0xc0,0x8e}, {0x80,0x20,0xe0,0x8f}, + + {0x80,0x40,0x00,0x90}, {0x80,0x40,0x20,0x91}, {0x80,0x40,0x40,0x92}, {0x80,0x40,0x60,0x93}, + {0x80,0x40,0x80,0x94}, {0x80,0x40,0xa0,0x95}, {0x80,0x40,0xc0,0x96}, {0x80,0x40,0xe0,0x97}, + {0x80,0x60,0x00,0x98}, {0x80,0x60,0x20,0x99}, {0x80,0x60,0x40,0x9a}, {0x80,0x60,0x60,0x9b}, + {0x80,0x60,0x80,0x9c}, {0x80,0x60,0xa0,0x9d}, {0x80,0x60,0xc0,0x9e}, {0x80,0x60,0xe0,0x9f}, + + {0x80,0x80,0x00,0xa0}, {0x80,0x80,0x20,0xa1}, {0x80,0x80,0x40,0xa2}, {0x80,0x80,0x60,0xa3}, + {0x80,0x80,0x80,0xa4}, {0x80,0x80,0xa0,0xa5}, {0x80,0x80,0xc0,0xa6}, {0x80,0x80,0xe0,0xa7}, + {0x80,0xa0,0x00,0xa8}, {0x80,0xa0,0x20,0xa9}, {0x80,0xa0,0x40,0xaa}, {0x80,0xa0,0x60,0xab}, + {0x80,0xa0,0x80,0xac}, {0x80,0xa0,0xa0,0xad}, {0x80,0xa0,0xc0,0xae}, {0x80,0xa0,0xe0,0xaf}, + + {0x80,0xc0,0x00,0xb0}, {0x80,0xc0,0x20,0xb1}, {0x80,0xc0,0x40,0xb2}, {0x80,0xc0,0x60,0xb3}, + {0x80,0xc0,0x80,0xb4}, {0x80,0xc0,0xa0,0xb5}, {0x80,0xc0,0xc0,0xb6}, {0x80,0xc0,0xe0,0xb7}, + {0x80,0xe0,0x00,0xb8}, {0x80,0xe0,0x20,0xb9}, {0x80,0xe0,0x40,0xba}, {0x80,0xe0,0x60,0xbb}, + {0x80,0xe0,0x80,0xbc}, {0x80,0xe0,0xa0,0xbd}, {0x80,0xe0,0xc0,0xbe}, {0x80,0xe0,0xe0,0xbf}, + + {0xc0,0x00,0x00,0xc0}, {0xc0,0x00,0x20,0xc1}, {0xc0,0x00,0x40,0xc2}, {0xc0,0x00,0x60,0xc3}, + {0xc0,0x00,0x80,0xc4}, {0xc0,0x00,0xa0,0xc5}, {0xc0,0x00,0xc0,0xc6}, {0xc0,0x00,0xe0,0xc7}, + {0xc0,0x20,0x00,0xc8}, {0xc0,0x20,0x20,0xc9}, {0xc0,0x20,0x40,0xca}, {0xc0,0x20,0x60,0xcb}, + {0xc0,0x20,0x80,0xcc}, {0xc0,0x20,0xa0,0xcd}, {0xc0,0x20,0xc0,0xce}, {0xc0,0x20,0xe0,0xcf}, + + {0xc0,0x40,0x00,0xd0}, {0xc0,0x40,0x20,0xd1}, {0xc0,0x40,0x40,0xd2}, {0xc0,0x40,0x60,0xd3}, + {0xc0,0x40,0x80,0xd4}, {0xc0,0x40,0xa0,0xd5}, {0xc0,0x40,0xc0,0xd6}, {0xc0,0x40,0xe0,0xd7}, + {0xc0,0x60,0x00,0xd8}, {0xc0,0x60,0x20,0xd9}, {0xc0,0x60,0x40,0xda}, {0xc0,0x60,0x60,0xdb}, + {0xc0,0x60,0x80,0xdc}, {0xc0,0x60,0xa0,0xdd}, {0xc0,0x60,0xc0,0xde}, {0xc0,0x60,0xe0,0xdf}, + + {0xc0,0x80,0x00,0xe0}, {0xc0,0x80,0x20,0xe1}, {0xc0,0x80,0x40,0xe2}, {0xc0,0x80,0x60,0xe3}, + {0xc0,0x80,0x80,0xe4}, {0xc0,0x80,0xa0,0xe5}, {0xc0,0x80,0xc0,0xe6}, {0xc0,0x80,0xe0,0xe7}, + {0xc0,0xa0,0x00,0xe8}, {0xc0,0xa0,0x20,0xe9}, {0xc0,0xa0,0x40,0xea}, {0xc0,0xa0,0x60,0xeb}, + {0xc0,0xa0,0x80,0xec}, {0xc0,0xa0,0xa0,0xed}, {0xc0,0xa0,0xc0,0xee}, {0xc0,0xa0,0xe0,0xef}, + + {0xc0,0xc0,0x00,0xf0}, {0xc0,0xc0,0x20,0xf1}, {0xc0,0xc0,0x40,0xf2}, {0xc0,0xc0,0x60,0xf3}, + {0xc0,0xc0,0x80,0xf4}, {0xc0,0xc0,0xa0,0xf5}, {0xf0,0xfb,0xff,0xf6}, {0xa4,0xa0,0xa0,0xf7}, + {0x80,0x80,0x80,0xf8}, {0x00,0x00,0xff,0xf9}, {0x00,0xff,0x00,0xfa}, {0x00,0xff,0xff,0xfb}, + {0xff,0x00,0x00,0xfc}, {0xff,0x00,0xff,0xfd}, {0xff,0xff,0x00,0xfe}, {0xff,0xff,0xff,0xff}, +}; + /* 1x1 bmp (1 bpp) */ static const uint8_t bmp_1bpp[] = { diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 38e328f58c5..c618ff6c48a 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1060,89 +1060,6 @@ static inline void _check_readback_pixel_4bpp(unsigned int line, struct surface_ todo_wine_if(todo) ok_(__FILE__, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x.\n", color, expected_color); }
-static const PALETTEENTRY test_palette[256] = -{ - {0x00,0x00,0x00,0x00}, {0x00,0x00,0x80,0x01}, {0x00,0x80,0x00,0x02}, {0x00,0x80,0x80,0x03}, - {0x80,0x00,0x00,0x04}, {0x80,0x00,0x80,0x05}, {0x80,0x80,0x00,0x06}, {0xc0,0xc0,0xc0,0x07}, - {0xc0,0xdc,0xc0,0x08}, {0xf0,0xca,0xa6,0x09}, {0x00,0x20,0x40,0x0a}, {0x00,0x20,0x60,0x0b}, - {0x00,0x20,0x80,0x0c}, {0x00,0x20,0xa0,0x0d}, {0x00,0x20,0xc0,0x0e}, {0x00,0x20,0xe0,0x0f}, - - {0x00,0x40,0x00,0x10}, {0x00,0x40,0x20,0x11}, {0x00,0x40,0x40,0x12}, {0x00,0x40,0x60,0x13}, - {0x00,0x40,0x80,0x14}, {0x00,0x40,0xa0,0x15}, {0x00,0x40,0xc0,0x16}, {0x00,0x40,0xe0,0x17}, - {0x00,0x60,0x00,0x18}, {0x00,0x60,0x20,0x19}, {0x00,0x60,0x40,0x1a}, {0x00,0x60,0x60,0x1b}, - {0x00,0x60,0x80,0x1c}, {0x00,0x60,0xa0,0x1d}, {0x00,0x60,0xc0,0x1e}, {0x00,0x60,0xe0,0x1f}, - - {0x00,0x80,0x00,0x20}, {0x00,0x80,0x20,0x21}, {0x00,0x80,0x40,0x22}, {0x00,0x80,0x60,0x23}, - {0x00,0x80,0x80,0x24}, {0x00,0x80,0xa0,0x25}, {0x00,0x80,0xc0,0x26}, {0x00,0x80,0xe0,0x27}, - {0x00,0xa0,0x00,0x28}, {0x00,0xa0,0x20,0x29}, {0x00,0xa0,0x40,0x2a}, {0x00,0xa0,0x60,0x2b}, - {0x00,0xa0,0x80,0x2c}, {0x00,0xa0,0xa0,0x2d}, {0x00,0xa0,0xc0,0x2e}, {0x00,0xa0,0xe0,0x2f}, - - {0x00,0xc0,0x00,0x30}, {0x00,0xc0,0x20,0x31}, {0x00,0xc0,0x40,0x32}, {0x00,0xc0,0x60,0x33}, - {0x00,0xc0,0x80,0x34}, {0x00,0xc0,0xa0,0x35}, {0x00,0xc0,0xc0,0x36}, {0x00,0xc0,0xe0,0x37}, - {0x00,0xe0,0x00,0x38}, {0x00,0xe0,0x20,0x39}, {0x00,0xe0,0x40,0x3a}, {0x00,0xe0,0x60,0x3b}, - {0x00,0xe0,0x80,0x3c}, {0x00,0xe0,0xa0,0x3d}, {0x00,0xe0,0xc0,0x3e}, {0x00,0xe0,0xe0,0x3f}, - - {0x40,0x00,0x00,0x40}, {0x40,0x00,0x20,0x41}, {0x40,0x00,0x40,0x42}, {0x40,0x00,0x60,0x43}, - {0x40,0x00,0x80,0x44}, {0x40,0x00,0xa0,0x45}, {0x40,0x00,0xc0,0x46}, {0x40,0x00,0xe0,0x47}, - {0x40,0x20,0x00,0x48}, {0x40,0x20,0x20,0x49}, {0x40,0x20,0x40,0x4a}, {0x40,0x20,0x60,0x4b}, - {0x40,0x20,0x80,0x4c}, {0x40,0x20,0xa0,0x4d}, {0x40,0x20,0xc0,0x4e}, {0x40,0x20,0xe0,0x4f}, - - {0x40,0x40,0x00,0x50}, {0x40,0x40,0x20,0x51}, {0x40,0x40,0x40,0x52}, {0x40,0x40,0x60,0x53}, - {0x40,0x40,0x80,0x54}, {0x40,0x40,0xa0,0x55}, {0x40,0x40,0xc0,0x56}, {0x40,0x40,0xe0,0x57}, - {0x40,0x60,0x00,0x58}, {0x40,0x60,0x20,0x59}, {0x40,0x60,0x40,0x5a}, {0x40,0x60,0x60,0x5b}, - {0x40,0x60,0x80,0x5c}, {0x40,0x60,0xa0,0x5d}, {0x40,0x60,0xc0,0x5e}, {0x40,0x60,0xe0,0x5f}, - - {0x40,0x80,0x00,0x60}, {0x40,0x80,0x20,0x61}, {0x40,0x80,0x40,0x62}, {0x40,0x80,0x60,0x63}, - {0x40,0x80,0x80,0x64}, {0x40,0x80,0xa0,0x65}, {0x40,0x80,0xc0,0x66}, {0x40,0x80,0xe0,0x67}, - {0x40,0xa0,0x00,0x68}, {0x40,0xa0,0x20,0x69}, {0x40,0xa0,0x40,0x6a}, {0x40,0xa0,0x60,0x6b}, - {0x40,0xa0,0x80,0x6c}, {0x40,0xa0,0xa0,0x6d}, {0x40,0xa0,0xc0,0x6e}, {0x40,0xa0,0xe0,0x6f}, - - {0x40,0xc0,0x00,0x70}, {0x40,0xc0,0x20,0x71}, {0x40,0xc0,0x40,0x72}, {0x40,0xc0,0x60,0x73}, - {0x40,0xc0,0x80,0x74}, {0x40,0xc0,0xa0,0x75}, {0x40,0xc0,0xc0,0x76}, {0x40,0xc0,0xe0,0x77}, - {0x40,0xe0,0x00,0x78}, {0x40,0xe0,0x20,0x79}, {0x40,0xe0,0x40,0x7a}, {0x40,0xe0,0x60,0x7b}, - {0x40,0xe0,0x80,0x7c}, {0x40,0xe0,0xa0,0x7d}, {0x40,0xe0,0xc0,0x7e}, {0x40,0xe0,0xe0,0x7f}, - - {0x80,0x00,0x00,0x80}, {0x80,0x00,0x20,0x81}, {0x80,0x00,0x40,0x82}, {0x80,0x00,0x60,0x83}, - {0x80,0x00,0x80,0x84}, {0x80,0x00,0xa0,0x85}, {0x80,0x00,0xc0,0x86}, {0x80,0x00,0xe0,0x87}, - {0x80,0x20,0x00,0x88}, {0x80,0x20,0x20,0x89}, {0x80,0x20,0x40,0x8a}, {0x80,0x20,0x60,0x8b}, - {0x80,0x20,0x80,0x8c}, {0x80,0x20,0xa0,0x8d}, {0x80,0x20,0xc0,0x8e}, {0x80,0x20,0xe0,0x8f}, - - {0x80,0x40,0x00,0x90}, {0x80,0x40,0x20,0x91}, {0x80,0x40,0x40,0x92}, {0x80,0x40,0x60,0x93}, - {0x80,0x40,0x80,0x94}, {0x80,0x40,0xa0,0x95}, {0x80,0x40,0xc0,0x96}, {0x80,0x40,0xe0,0x97}, - {0x80,0x60,0x00,0x98}, {0x80,0x60,0x20,0x99}, {0x80,0x60,0x40,0x9a}, {0x80,0x60,0x60,0x9b}, - {0x80,0x60,0x80,0x9c}, {0x80,0x60,0xa0,0x9d}, {0x80,0x60,0xc0,0x9e}, {0x80,0x60,0xe0,0x9f}, - - {0x80,0x80,0x00,0xa0}, {0x80,0x80,0x20,0xa1}, {0x80,0x80,0x40,0xa2}, {0x80,0x80,0x60,0xa3}, - {0x80,0x80,0x80,0xa4}, {0x80,0x80,0xa0,0xa5}, {0x80,0x80,0xc0,0xa6}, {0x80,0x80,0xe0,0xa7}, - {0x80,0xa0,0x00,0xa8}, {0x80,0xa0,0x20,0xa9}, {0x80,0xa0,0x40,0xaa}, {0x80,0xa0,0x60,0xab}, - {0x80,0xa0,0x80,0xac}, {0x80,0xa0,0xa0,0xad}, {0x80,0xa0,0xc0,0xae}, {0x80,0xa0,0xe0,0xaf}, - - {0x80,0xc0,0x00,0xb0}, {0x80,0xc0,0x20,0xb1}, {0x80,0xc0,0x40,0xb2}, {0x80,0xc0,0x60,0xb3}, - {0x80,0xc0,0x80,0xb4}, {0x80,0xc0,0xa0,0xb5}, {0x80,0xc0,0xc0,0xb6}, {0x80,0xc0,0xe0,0xb7}, - {0x80,0xe0,0x00,0xb8}, {0x80,0xe0,0x20,0xb9}, {0x80,0xe0,0x40,0xba}, {0x80,0xe0,0x60,0xbb}, - {0x80,0xe0,0x80,0xbc}, {0x80,0xe0,0xa0,0xbd}, {0x80,0xe0,0xc0,0xbe}, {0x80,0xe0,0xe0,0xbf}, - - {0xc0,0x00,0x00,0xc0}, {0xc0,0x00,0x20,0xc1}, {0xc0,0x00,0x40,0xc2}, {0xc0,0x00,0x60,0xc3}, - {0xc0,0x00,0x80,0xc4}, {0xc0,0x00,0xa0,0xc5}, {0xc0,0x00,0xc0,0xc6}, {0xc0,0x00,0xe0,0xc7}, - {0xc0,0x20,0x00,0xc8}, {0xc0,0x20,0x20,0xc9}, {0xc0,0x20,0x40,0xca}, {0xc0,0x20,0x60,0xcb}, - {0xc0,0x20,0x80,0xcc}, {0xc0,0x20,0xa0,0xcd}, {0xc0,0x20,0xc0,0xce}, {0xc0,0x20,0xe0,0xcf}, - - {0xc0,0x40,0x00,0xd0}, {0xc0,0x40,0x20,0xd1}, {0xc0,0x40,0x40,0xd2}, {0xc0,0x40,0x60,0xd3}, - {0xc0,0x40,0x80,0xd4}, {0xc0,0x40,0xa0,0xd5}, {0xc0,0x40,0xc0,0xd6}, {0xc0,0x40,0xe0,0xd7}, - {0xc0,0x60,0x00,0xd8}, {0xc0,0x60,0x20,0xd9}, {0xc0,0x60,0x40,0xda}, {0xc0,0x60,0x60,0xdb}, - {0xc0,0x60,0x80,0xdc}, {0xc0,0x60,0xa0,0xdd}, {0xc0,0x60,0xc0,0xde}, {0xc0,0x60,0xe0,0xdf}, - - {0xc0,0x80,0x00,0xe0}, {0xc0,0x80,0x20,0xe1}, {0xc0,0x80,0x40,0xe2}, {0xc0,0x80,0x60,0xe3}, - {0xc0,0x80,0x80,0xe4}, {0xc0,0x80,0xa0,0xe5}, {0xc0,0x80,0xc0,0xe6}, {0xc0,0x80,0xe0,0xe7}, - {0xc0,0xa0,0x00,0xe8}, {0xc0,0xa0,0x20,0xe9}, {0xc0,0xa0,0x40,0xea}, {0xc0,0xa0,0x60,0xeb}, - {0xc0,0xa0,0x80,0xec}, {0xc0,0xa0,0xa0,0xed}, {0xc0,0xa0,0xc0,0xee}, {0xc0,0xa0,0xe0,0xef}, - - {0xc0,0xc0,0x00,0xf0}, {0xc0,0xc0,0x20,0xf1}, {0xc0,0xc0,0x40,0xf2}, {0xc0,0xc0,0x60,0xf3}, - {0xc0,0xc0,0x80,0xf4}, {0xc0,0xc0,0xa0,0xf5}, {0xf0,0xfb,0xff,0xf6}, {0xa4,0xa0,0xa0,0xf7}, - {0x80,0x80,0x80,0xf8}, {0x00,0x00,0xff,0xf9}, {0x00,0xff,0x00,0xfa}, {0x00,0xff,0xff,0xfb}, - {0xff,0x00,0x00,0xfc}, {0xff,0x00,0xff,0xfd}, {0xff,0xff,0x00,0xfe}, {0xff,0xff,0xff,0xff}, -}; - static const uint16_t v16u16_2_2[] = { 0x0000, 0x3000, 0x4000, 0x7fff, 0x8000, 0x8001, 0xc000, 0xffff, diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index b6ca3b2738f..21c9533b5fd 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -25,6 +25,7 @@ #include "d3dx9tex.h" #include "resources.h" #include <stdint.h> +#include <assert.h> #include "d3dx9_test_images.h"
static int has_2d_dxt1, has_2d_dxt3, has_2d_dxt5, has_cube_dxt5, has_3d_dxt3; @@ -3137,6 +3138,184 @@ static void WINAPI fill_func(D3DXVECTOR4 *value, const D3DXVECTOR2 *coord, const *value = quadrant_color[idx]; }
+static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) +{ + static const struct + { + D3DRESOURCETYPE type; + D3DFORMAT format; + D3DPOOL pool; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t mip_levels; + const PALETTEENTRY *palette; + + HRESULT expected_hr; + struct dds_pixel_format expected_pixel_format; + uint32_t expected_flags; + uint32_t expected_width; + uint32_t expected_height; + uint32_t expected_pitch; + uint32_t expected_depth; + uint32_t expected_mip_levels; + uint32_t expected_caps; + uint32_t expected_caps2; + uint32_t expected_buffer_size; + BOOL todo_hr; + } tests[] = + { + /* Paletted format tests. */ + { D3DRTYPE_TEXTURE, D3DFMT_P8, D3DPOOL_SCRATCH, 4, 4, 0, 3, test_palette, D3D_OK, + { 32, DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, + (DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX), + 0, PALETTED_DDS_FILE_HEADER_SIZE + 21, + .todo_hr = TRUE + }, + { D3DRTYPE_CUBETEXTURE, D3DFMT_P8, D3DPOOL_SCRATCH, 4, 0, 0, 3, test_palette, D3D_OK, + { 32, DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, + (DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX), + (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES), PALETTED_DDS_FILE_HEADER_SIZE + 126, + .todo_hr = TRUE + }, + { D3DRTYPE_VOLUMETEXTURE, D3DFMT_P8, D3DPOOL_SCRATCH, 4, 4, 4, 3, test_palette, D3D_OK, + { 32, DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT | DDSD_DEPTH), 4, 4, 0, 4, 3, + (DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX), + DDSCAPS2_VOLUME, PALETTED_DDS_FILE_HEADER_SIZE + 73, + .todo_hr = TRUE + }, + /* D3DFMT_A8R8G8B8 textures with multiple levels. */ + { D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 0, 3, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, + (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | DDSCAPS_ALPHA), + 0, DDS_FILE_HEADER_SIZE + 84, + .todo_hr = TRUE + }, + { D3DRTYPE_CUBETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 0, 0, 3, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, + (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_ALPHA | DDSCAPS_COMPLEX), + (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES), DDS_FILE_HEADER_SIZE + 504, + .todo_hr = TRUE + }, + /* 5 */ + /* + * Volume texture with D3DPOOL default. Can't be mapped for read, + * can't be saved. + */ + { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 4, 3, NULL, D3DERR_INVALIDCALL, + .todo_hr = TRUE + }, + /* D3DPOOL_SYSTEMMEM can be saved. */ + { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, 4, 4, 4, 3, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_DEPTH | DDSD_MIPMAPCOUNT), 4, 4, 0, 4, 3, + (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_ALPHA | DDSCAPS_COMPLEX), + DDSCAPS2_VOLUME, DDS_FILE_HEADER_SIZE + 292, + .todo_hr = TRUE + }, + /* Single mip level, no mip flags. */ + { D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 0, 1, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT), 4, 4, 0, 0, 0, + (DDSCAPS_TEXTURE | DDSCAPS_ALPHA), + 0, DDS_FILE_HEADER_SIZE + 64, + .todo_hr = TRUE + }, + { D3DRTYPE_CUBETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 0, 0, 1, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT), 4, 4, 0, 0, 0, + (DDSCAPS_TEXTURE | DDSCAPS_ALPHA | DDSCAPS_COMPLEX), + (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES), DDS_FILE_HEADER_SIZE + 384, + .todo_hr = TRUE + }, + { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, 4, 4, 4, 1, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_DEPTH), 4, 4, 0, 4, 0, + (DDSCAPS_TEXTURE | DDSCAPS_ALPHA), + DDSCAPS2_VOLUME, DDS_FILE_HEADER_SIZE + 256, + .todo_hr = TRUE + }, + /* 10. */ + /* Volume texture with a depth of 1. */ + { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, 4, 4, 1, 1, NULL, D3D_OK, + { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT), 4, 4, 0, 0, 0, + (DDSCAPS_TEXTURE | DDSCAPS_ALPHA), + 0, DDS_FILE_HEADER_SIZE + 64, + .todo_hr = TRUE + }, + }; + struct + { + DWORD magic; + struct dds_header header; + BYTE *data; + } *dds; + IDirect3DVolumeTexture9 *volume_texture; + IDirect3DCubeTexture9 *cube_texture; + IDirect3DBaseTexture9 *save_tex; + IDirect3DTexture9 *texture; + ID3DXBuffer *buffer; + unsigned int i; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("Test %u", i); + + switch (tests[i].type) + { + case D3DRTYPE_TEXTURE: + hr = IDirect3DDevice9_CreateTexture(device, tests[i].width, tests[i].height, tests[i].mip_levels, 0, + tests[i].format, tests[i].pool, &texture, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + save_tex = (IDirect3DBaseTexture9 *)texture; + break; + + case D3DRTYPE_CUBETEXTURE: + hr = IDirect3DDevice9_CreateCubeTexture(device, tests[i].width, tests[i].mip_levels, 0, + tests[i].format, tests[i].pool, &cube_texture, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + save_tex = (IDirect3DBaseTexture9 *)cube_texture; + break; + + case D3DRTYPE_VOLUMETEXTURE: + hr = IDirect3DDevice9_CreateVolumeTexture(device, tests[i].width, tests[i].height, tests[i].depth, + tests[i].mip_levels, 0, tests[i].format, tests[i].pool, &volume_texture, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + save_tex = (IDirect3DBaseTexture9 *)volume_texture; + break; + + default: + assert(0); + break; + } + + hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, save_tex, tests[i].palette); + todo_wine_if(tests[i].todo_hr) ok(hr == tests[i].expected_hr, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(ID3DXBuffer_GetBufferSize(buffer) == tests[i].expected_buffer_size, "Unexpected buffer size %lu.\n", + ID3DXBuffer_GetBufferSize(buffer)); + + dds = ID3DXBuffer_GetBufferPointer(buffer); + check_dds_header(&dds->header, tests[i].expected_flags, tests[i].expected_height, tests[i].expected_width, + tests[i].expected_pitch, tests[i].expected_depth, tests[i].expected_mip_levels, + &tests[i].expected_pixel_format, tests[i].expected_caps, tests[i].expected_caps2, + FALSE); + ID3DXBuffer_Release(buffer); + } + + IDirect3DBaseTexture9_Release(save_tex); + winetest_pop_context(); + } +} + static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) { const D3DXVECTOR4 clear_val = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -3381,6 +3560,8 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) release_surface_readback(&rb);
IDirect3DTexture9_Release(texture); + + test_save_texture_to_dds_file(device); }
static void test_texture_shader(void)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 78 +++++++++++++++++++ dlls/d3dx9_36/surface.c | 86 +++------------------ dlls/d3dx9_36/tests/texture.c | 29 +++----- dlls/d3dx9_36/texture.c | 136 ++++++++++++++++++++++++++++------ 4 files changed, 214 insertions(+), 115 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 7da9f9dd788..0e965eb6017 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -50,6 +50,80 @@ static inline HRESULT d3dx9_handle_load_filter(DWORD *filter) return d3dx9_validate_filter(*filter); }
+#define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256) + +/* dds_header.flags */ +#define DDS_CAPS 0x1 +#define DDS_HEIGHT 0x2 +#define DDS_WIDTH 0x4 +#define DDS_PITCH 0x8 +#define DDS_PIXELFORMAT 0x1000 +#define DDS_MIPMAPCOUNT 0x20000 +#define DDS_LINEARSIZE 0x80000 +#define DDS_DEPTH 0x800000 + +/* dds_header.caps */ +#define DDSCAPS_ALPHA 0x2 +#define DDS_CAPS_COMPLEX 0x8 +#define DDSCAPS_PALETTE 0x100 +#define DDS_CAPS_TEXTURE 0x1000 +#define DDS_CAPS_MIPMAP 0x400000 + +/* dds_header.caps2 */ +#define DDS_CAPS2_CUBEMAP 0x200 +#define DDS_CAPS2_CUBEMAP_POSITIVEX 0x400 +#define DDS_CAPS2_CUBEMAP_NEGATIVEX 0x800 +#define DDS_CAPS2_CUBEMAP_POSITIVEY 0x1000 +#define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x2000 +#define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x4000 +#define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x8000 +#define DDS_CAPS2_CUBEMAP_ALL_FACES ( DDS_CAPS2_CUBEMAP_POSITIVEX | DDS_CAPS2_CUBEMAP_NEGATIVEX \ + | DDS_CAPS2_CUBEMAP_POSITIVEY | DDS_CAPS2_CUBEMAP_NEGATIVEY \ + | DDS_CAPS2_CUBEMAP_POSITIVEZ | DDS_CAPS2_CUBEMAP_NEGATIVEZ ) +#define DDS_CAPS2_VOLUME 0x200000 + +/* dds_pixel_format.flags */ +#define DDS_PF_ALPHA 0x1 +#define DDS_PF_ALPHA_ONLY 0x2 +#define DDS_PF_FOURCC 0x4 +#define DDS_PF_INDEXED 0x20 +#define DDS_PF_RGB 0x40 +#define DDS_PF_YUV 0x200 +#define DDS_PF_LUMINANCE 0x20000 +#define DDS_PF_BUMPLUMINANCE 0x40000 +#define DDS_PF_BUMPDUDV 0x80000 + +struct dds_pixel_format +{ + DWORD size; + DWORD flags; + DWORD fourcc; + DWORD bpp; + DWORD rmask; + DWORD gmask; + DWORD bmask; + DWORD amask; +}; + +struct dds_header +{ + DWORD signature; + DWORD size; + DWORD flags; + DWORD height; + DWORD width; + DWORD pitch_or_linear_size; + DWORD depth; + DWORD miplevels; + DWORD reserved[11]; + struct dds_pixel_format pixel_format; + DWORD caps; + DWORD caps2; + DWORD caps3; + DWORD caps4; + DWORD reserved2; +}; + struct vec4 { float x, y, z, w; @@ -316,6 +390,10 @@ HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLO IDirect3DSurface9 **temp_surface, BOOL write); HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, IDirect3DSurface9 *temp_surface, BOOL update); +uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height, + uint32_t depth, uint32_t mip_levels); +HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource_type, + enum d3dx_pixel_format_id format, const struct volume *size, uint32_t mip_levels); HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer); const char *debug_d3dx_image_file_format(D3DXIMAGE_FILEFORMAT format); diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index e5a9207ad91..3af573fb0e9 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -78,80 +78,6 @@ static const GUID *wic_guid_from_d3dx_pixel_format_id(enum d3dx_pixel_format_id return NULL; }
-#define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256) - -/* dds_header.flags */ -#define DDS_CAPS 0x1 -#define DDS_HEIGHT 0x2 -#define DDS_WIDTH 0x4 -#define DDS_PITCH 0x8 -#define DDS_PIXELFORMAT 0x1000 -#define DDS_MIPMAPCOUNT 0x20000 -#define DDS_LINEARSIZE 0x80000 -#define DDS_DEPTH 0x800000 - -/* dds_header.caps */ -#define DDSCAPS_ALPHA 0x2 -#define DDS_CAPS_COMPLEX 0x8 -#define DDSCAPS_PALETTE 0x100 -#define DDS_CAPS_TEXTURE 0x1000 -#define DDS_CAPS_MIPMAP 0x400000 - -/* dds_header.caps2 */ -#define DDS_CAPS2_CUBEMAP 0x200 -#define DDS_CAPS2_CUBEMAP_POSITIVEX 0x400 -#define DDS_CAPS2_CUBEMAP_NEGATIVEX 0x800 -#define DDS_CAPS2_CUBEMAP_POSITIVEY 0x1000 -#define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x2000 -#define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x4000 -#define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x8000 -#define DDS_CAPS2_CUBEMAP_ALL_FACES ( DDS_CAPS2_CUBEMAP_POSITIVEX | DDS_CAPS2_CUBEMAP_NEGATIVEX \ - | DDS_CAPS2_CUBEMAP_POSITIVEY | DDS_CAPS2_CUBEMAP_NEGATIVEY \ - | DDS_CAPS2_CUBEMAP_POSITIVEZ | DDS_CAPS2_CUBEMAP_NEGATIVEZ ) -#define DDS_CAPS2_VOLUME 0x200000 - -/* dds_pixel_format.flags */ -#define DDS_PF_ALPHA 0x1 -#define DDS_PF_ALPHA_ONLY 0x2 -#define DDS_PF_FOURCC 0x4 -#define DDS_PF_INDEXED 0x20 -#define DDS_PF_RGB 0x40 -#define DDS_PF_YUV 0x200 -#define DDS_PF_LUMINANCE 0x20000 -#define DDS_PF_BUMPLUMINANCE 0x40000 -#define DDS_PF_BUMPDUDV 0x80000 - -struct dds_pixel_format -{ - DWORD size; - DWORD flags; - DWORD fourcc; - DWORD bpp; - DWORD rmask; - DWORD gmask; - DWORD bmask; - DWORD amask; -}; - -struct dds_header -{ - DWORD signature; - DWORD size; - DWORD flags; - DWORD height; - DWORD width; - DWORD pitch_or_linear_size; - DWORD depth; - DWORD miplevels; - DWORD reserved[11]; - struct dds_pixel_format pixel_format; - DWORD caps; - DWORD caps2; - DWORD caps3; - DWORD caps4; - DWORD reserved2; -}; - #define TGA_IMAGETYPE_COLORMAPPED 1 #define TGA_IMAGETYPE_TRUECOLOR 2 #define TGA_IMAGETYPE_GRAYSCALE 3 @@ -473,7 +399,7 @@ static HRESULT d3dx_calculate_pixels_size(enum d3dx_pixel_format_id format, uint return D3D_OK; }
-static uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height, uint32_t depth, +uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height, uint32_t depth, uint32_t mip_levels) { uint32_t layer_size, row_pitch, slice_pitch, i; @@ -491,7 +417,7 @@ static uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id forma return layer_size; }
-static HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource_type, +HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource_type, enum d3dx_pixel_format_id format, const struct volume *size, uint32_t mip_levels) { HRESULT hr; @@ -514,6 +440,14 @@ static HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE r header->depth = size->depth; header->caps2 |= DDS_CAPS2_VOLUME; } + + if (mip_levels > 1) + { + header->flags |= DDS_MIPMAPCOUNT; + header->caps |= (DDS_CAPS_MIPMAP | DDS_CAPS_COMPLEX); + header->miplevels = mip_levels; + } + if (header->pixel_format.flags & DDS_PF_ALPHA || header->pixel_format.flags & DDS_PF_ALPHA_ONLY) header->caps |= DDSCAPS_ALPHA; if (header->pixel_format.flags & DDS_PF_INDEXED) diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 21c9533b5fd..35d52117dd9 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -3171,7 +3171,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, (DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX), 0, PALETTED_DDS_FILE_HEADER_SIZE + 21, - .todo_hr = TRUE }, { D3DRTYPE_CUBETEXTURE, D3DFMT_P8, D3DPOOL_SCRATCH, 4, 0, 0, 3, test_palette, D3D_OK, { 32, DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0 }, @@ -3193,7 +3192,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | DDSCAPS_ALPHA), 0, DDS_FILE_HEADER_SIZE + 84, - .todo_hr = TRUE }, { D3DRTYPE_CUBETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 0, 0, 3, NULL, D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, @@ -3224,7 +3222,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT), 4, 4, 0, 0, 0, (DDSCAPS_TEXTURE | DDSCAPS_ALPHA), 0, DDS_FILE_HEADER_SIZE + 64, - .todo_hr = TRUE }, { D3DRTYPE_CUBETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 0, 0, 1, NULL, D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, @@ -3359,24 +3356,20 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) } }
- todo_wine { hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)texture, NULL); ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); - if (SUCCEEDED(hr)) - { - buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); - buffer_size = ID3DXBuffer_GetBufferSize(buffer); - hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); - ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK);
- ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256); - ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256); - ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9); - ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE); - ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS); - ID3DXBuffer_Release(buffer); - } - } + buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); + buffer_size = ID3DXBuffer_GetBufferSize(buffer); + hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); + ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); + + ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256); + ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256); + ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9); + ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE); + ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS); + ID3DXBuffer_Release(buffer);
IDirect3DTexture9_Release(texture);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 4b4192dc8b6..00309904206 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1856,25 +1856,39 @@ HRESULT WINAPI D3DXSaveTextureToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEF HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format, IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette) { - HRESULT hr; + const struct pixel_format_desc *fmt_desc = NULL; + unsigned int levels, file_size, i; + struct d3dx_image image; D3DRESOURCETYPE type; + ID3DXBuffer *buffer; + struct volume size; + HRESULT hr;
TRACE("dst_buffer %p, file_format %u, src_texture %p, src_palette %p.\n", dst_buffer, file_format, src_texture, src_palette);
- if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL; - - if (file_format == D3DXIFF_DDS) - { - FIXME("DDS file format isn't supported yet\n"); - return E_NOTIMPL; - } + if (!dst_buffer || !src_texture || file_format > D3DXIFF_PFM) + return D3DERR_INVALIDCALL;
+ *dst_buffer = buffer = NULL; type = IDirect3DBaseTexture9_GetType(src_texture); - switch (type) + if (type < D3DRTYPE_TEXTURE || type > D3DRTYPE_CUBETEXTURE) + return D3DERR_INVALIDCALL; + + if (file_format != D3DXIFF_DDS) { - case D3DRTYPE_TEXTURE: - case D3DRTYPE_CUBETEXTURE: + if (type == D3DRTYPE_VOLUMETEXTURE) + { + IDirect3DVolume9 *volume; + + hr = IDirect3DVolumeTexture9_GetVolumeLevel((IDirect3DVolumeTexture9 *)src_texture, 0, &volume); + if (SUCCEEDED(hr)) + { + hr = D3DXSaveVolumeToFileInMemory(dst_buffer, file_format, volume, src_palette, NULL); + IDirect3DVolume9_Release(volume); + } + } + else { IDirect3DSurface9 *surface;
@@ -1884,26 +1898,106 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL); IDirect3DSurface9_Release(surface); } - break; }
- case D3DRTYPE_VOLUMETEXTURE: + return hr; + } + + levels = IDirect3DBaseTexture9_GetLevelCount(src_texture); + switch (type) + { + case D3DRTYPE_TEXTURE: { - IDirect3DVolume9 *volume; + IDirect3DTexture9 *texture = (IDirect3DTexture9 *)src_texture; + D3DSURFACE_DESC desc;
- hr = IDirect3DVolumeTexture9_GetVolumeLevel((IDirect3DVolumeTexture9 *)src_texture, 0, &volume); - if (SUCCEEDED(hr)) - { - hr = D3DXSaveVolumeToFileInMemory(dst_buffer, file_format, volume, src_palette, NULL); - IDirect3DVolume9_Release(volume); - } + hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc); + if (FAILED(hr)) + break; + + fmt_desc = get_format_info(desc.Format); + if (is_unknown_format(fmt_desc)) + return E_NOTIMPL; + + set_volume_struct(&size, desc.Width, desc.Height, 1); break; }
default: - return D3DERR_INVALIDCALL; + return E_NOTIMPL; + } + + if (is_index_format(fmt_desc) && !src_palette) + return E_NOTIMPL; + + file_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, size.width, size.height, size.depth, levels); + file_size += is_index_format(fmt_desc) ? sizeof(struct dds_header) + DDS_PALETTE_SIZE : sizeof(struct dds_header); + + hr = D3DXCreateBuffer(file_size, &buffer); + if (FAILED(hr)) + return hr; + + hr = d3dx_init_dds_header((struct dds_header *)ID3DXBuffer_GetBufferPointer(buffer), type, fmt_desc->format, &size, + levels); + if (FAILED(hr)) + goto exit; + + if (is_index_format(fmt_desc)) + memcpy((uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + sizeof(struct dds_header), src_palette, + DDS_PALETTE_SIZE); + + hr = d3dx_image_init(ID3DXBuffer_GetBufferPointer(buffer), ID3DXBuffer_GetBufferSize(buffer), &image, 0, 0); + if (FAILED(hr)) + goto exit; + + for (i = 0; i < levels; ++i) + { + IDirect3DSurface9 *src_surface, *tmp_surface; + struct d3dx_pixels src_pixels, dst_pixels; + D3DSURFACE_DESC src_surface_desc; + D3DLOCKED_RECT src_locked_rect; + RECT src_rect; + + hr = d3dx_image_get_pixels(&image, 0, i, &dst_pixels); + if (FAILED(hr)) + goto exit; + + hr = get_surface(type, src_texture, 0, i, &src_surface); + if (FAILED(hr)) + goto exit; + + hr = lock_surface(src_surface, NULL, &src_locked_rect, &tmp_surface, FALSE); + if (FAILED(hr)) + { + IDirect3DSurface9_Release(src_surface); + goto exit; + } + + IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9 *)src_texture, i, &src_surface_desc); + SetRect(&src_rect, 0, 0, src_surface_desc.Width, src_surface_desc.Height); + set_d3dx_pixels(&src_pixels, src_locked_rect.pBits, src_locked_rect.Pitch, 0, src_palette, + src_surface_desc.Width, src_surface_desc.Height, 1, &src_rect); + + hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, D3DX_FILTER_NONE, 0); + if (FAILED(hr)) + { + unlock_surface(src_surface, NULL, tmp_surface, FALSE); + IDirect3DSurface9_Release(src_surface); + goto exit; + } + + hr = unlock_surface(src_surface, NULL, tmp_surface, FALSE); + IDirect3DSurface9_Release(src_surface); + if (FAILED(hr)) + goto exit; }
+ *dst_buffer = buffer; + +exit: + if (buffer && (buffer != *dst_buffer)) + ID3DXBuffer_Release(buffer); + return hr; }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 6 +++ dlls/d3dx9_36/tests/texture.c | 29 +++++------- dlls/d3dx9_36/texture.c | 89 ++++++++++++++++++++++------------- 3 files changed, 73 insertions(+), 51 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 3af573fb0e9..e3bc77bd52e 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -448,6 +448,12 @@ HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource header->miplevels = mip_levels; }
+ if (resource_type == D3DRTYPE_CUBETEXTURE) + { + header->caps |= DDS_CAPS_COMPLEX; + header->caps2 |= (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES); + } + if (header->pixel_format.flags & DDS_PF_ALPHA || header->pixel_format.flags & DDS_PF_ALPHA_ONLY) header->caps |= DDSCAPS_ALPHA; if (header->pixel_format.flags & DDS_PF_INDEXED) diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 35d52117dd9..e0150584ef8 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -3177,7 +3177,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, (DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX), (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES), PALETTED_DDS_FILE_HEADER_SIZE + 126, - .todo_hr = TRUE }, { D3DRTYPE_VOLUMETEXTURE, D3DFMT_P8, D3DPOOL_SCRATCH, 4, 4, 4, 3, test_palette, D3D_OK, { 32, DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0 }, @@ -3198,7 +3197,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT), 4, 4, 0, 0, 3, (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_ALPHA | DDSCAPS_COMPLEX), (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES), DDS_FILE_HEADER_SIZE + 504, - .todo_hr = TRUE }, /* 5 */ /* @@ -3228,7 +3226,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT), 4, 4, 0, 0, 0, (DDSCAPS_TEXTURE | DDSCAPS_ALPHA | DDSCAPS_COMPLEX), (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES), DDS_FILE_HEADER_SIZE + 384, - .todo_hr = TRUE }, { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, 4, 4, 4, 1, NULL, D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, @@ -3422,24 +3419,20 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) ID3DXBuffer_Release(buffer); }
- todo_wine { hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)cube_texture, NULL); ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); - if (SUCCEEDED(hr)) - { - buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); - buffer_size = ID3DXBuffer_GetBufferSize(buffer); - hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); - ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK);
- ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256); - ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256); - ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9); - ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE); - ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS); - ID3DXBuffer_Release(buffer); - } - } + buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); + buffer_size = ID3DXBuffer_GetBufferSize(buffer); + hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); + ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); + + ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256); + ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256); + ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9); + ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE); + ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS); + ID3DXBuffer_Release(buffer);
IDirect3DCubeTexture9_Release(cube_texture);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 00309904206..25f8ef6c6b4 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1857,7 +1857,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette) { const struct pixel_format_desc *fmt_desc = NULL; - unsigned int levels, file_size, i; + unsigned int levels, file_size, i, j; struct d3dx_image image; D3DRESOURCETYPE type; ID3DXBuffer *buffer; @@ -1923,6 +1923,24 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE break; }
+ case D3DRTYPE_CUBETEXTURE: + { + IDirect3DCubeTexture9 *texture = (IDirect3DCubeTexture9 *)src_texture; + D3DSURFACE_DESC desc; + + hr = IDirect3DCubeTexture9_GetLevelDesc(texture, 0, &desc); + if (FAILED(hr)) + break; + + fmt_desc = get_format_info(desc.Format); + if (is_unknown_format(fmt_desc)) + return E_NOTIMPL; + + set_volume_struct(&size, desc.Width, desc.Height, 1); + break; + } + + default: return E_NOTIMPL; } @@ -1931,6 +1949,8 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE return E_NOTIMPL;
file_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, size.width, size.height, size.depth, levels); + if (type == D3DRTYPE_CUBETEXTURE) + file_size *= 6; file_size += is_index_format(fmt_desc) ? sizeof(struct dds_header) + DDS_PALETTE_SIZE : sizeof(struct dds_header);
hr = D3DXCreateBuffer(file_size, &buffer); @@ -1950,46 +1970,49 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE if (FAILED(hr)) goto exit;
- for (i = 0; i < levels; ++i) + for (j = 0; j < image.layer_count; ++j) { - IDirect3DSurface9 *src_surface, *tmp_surface; - struct d3dx_pixels src_pixels, dst_pixels; - D3DSURFACE_DESC src_surface_desc; - D3DLOCKED_RECT src_locked_rect; - RECT src_rect; + for (i = 0; i < levels; ++i) + { + IDirect3DSurface9 *src_surface, *tmp_surface; + struct d3dx_pixels src_pixels, dst_pixels; + D3DSURFACE_DESC src_surface_desc; + D3DLOCKED_RECT src_locked_rect; + RECT src_rect;
- hr = d3dx_image_get_pixels(&image, 0, i, &dst_pixels); - if (FAILED(hr)) - goto exit; + hr = d3dx_image_get_pixels(&image, j, i, &dst_pixels); + if (FAILED(hr)) + goto exit;
- hr = get_surface(type, src_texture, 0, i, &src_surface); - if (FAILED(hr)) - goto exit; + hr = get_surface(type, src_texture, j, i, &src_surface); + if (FAILED(hr)) + goto exit;
- hr = lock_surface(src_surface, NULL, &src_locked_rect, &tmp_surface, FALSE); - if (FAILED(hr)) - { - IDirect3DSurface9_Release(src_surface); - goto exit; - } + hr = lock_surface(src_surface, NULL, &src_locked_rect, &tmp_surface, FALSE); + if (FAILED(hr)) + { + IDirect3DSurface9_Release(src_surface); + goto exit; + }
- IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9 *)src_texture, i, &src_surface_desc); - SetRect(&src_rect, 0, 0, src_surface_desc.Width, src_surface_desc.Height); - set_d3dx_pixels(&src_pixels, src_locked_rect.pBits, src_locked_rect.Pitch, 0, src_palette, - src_surface_desc.Width, src_surface_desc.Height, 1, &src_rect); + IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); + SetRect(&src_rect, 0, 0, src_surface_desc.Width, src_surface_desc.Height); + set_d3dx_pixels(&src_pixels, src_locked_rect.pBits, src_locked_rect.Pitch, 0, src_palette, + src_surface_desc.Width, src_surface_desc.Height, 1, &src_rect);
- hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, D3DX_FILTER_NONE, 0); - if (FAILED(hr)) - { - unlock_surface(src_surface, NULL, tmp_surface, FALSE); + hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, D3DX_FILTER_NONE, 0); + if (FAILED(hr)) + { + unlock_surface(src_surface, NULL, tmp_surface, FALSE); + IDirect3DSurface9_Release(src_surface); + goto exit; + } + + hr = unlock_surface(src_surface, NULL, tmp_surface, FALSE); IDirect3DSurface9_Release(src_surface); - goto exit; + if (FAILED(hr)) + goto exit; } - - hr = unlock_surface(src_surface, NULL, tmp_surface, FALSE); - IDirect3DSurface9_Release(src_surface); - if (FAILED(hr)) - goto exit; }
*dst_buffer = buffer;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 39 +++++-------- dlls/d3dx9_36/texture.c | 105 +++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 53 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index e0150584ef8..7ee4156711d 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -3162,7 +3162,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) uint32_t expected_caps; uint32_t expected_caps2; uint32_t expected_buffer_size; - BOOL todo_hr; } tests[] = { /* Paletted format tests. */ @@ -3183,7 +3182,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT | DDSD_DEPTH), 4, 4, 0, 4, 3, (DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX), DDSCAPS2_VOLUME, PALETTED_DDS_FILE_HEADER_SIZE + 73, - .todo_hr = TRUE }, /* D3DFMT_A8R8G8B8 textures with multiple levels. */ { D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 0, 3, NULL, D3D_OK, @@ -3203,16 +3201,13 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) * Volume texture with D3DPOOL default. Can't be mapped for read, * can't be saved. */ - { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 4, 3, NULL, D3DERR_INVALIDCALL, - .todo_hr = TRUE - }, + { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 4, 3, NULL, D3DERR_INVALIDCALL }, /* D3DPOOL_SYSTEMMEM can be saved. */ { D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, 4, 4, 4, 3, NULL, D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_DEPTH | DDSD_MIPMAPCOUNT), 4, 4, 0, 4, 3, (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_ALPHA | DDSCAPS_COMPLEX), DDSCAPS2_VOLUME, DDS_FILE_HEADER_SIZE + 292, - .todo_hr = TRUE }, /* Single mip level, no mip flags. */ { D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 4, 4, 0, 1, NULL, D3D_OK, @@ -3232,7 +3227,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_DEPTH), 4, 4, 0, 4, 0, (DDSCAPS_TEXTURE | DDSCAPS_ALPHA), DDSCAPS2_VOLUME, DDS_FILE_HEADER_SIZE + 256, - .todo_hr = TRUE }, /* 10. */ /* Volume texture with a depth of 1. */ @@ -3241,7 +3235,6 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT), 4, 4, 0, 0, 0, (DDSCAPS_TEXTURE | DDSCAPS_ALPHA), 0, DDS_FILE_HEADER_SIZE + 64, - .todo_hr = TRUE }, }; struct @@ -3291,7 +3284,7 @@ static void test_save_texture_to_dds_file(IDirect3DDevice9 *device) }
hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, save_tex, tests[i].palette); - todo_wine_if(tests[i].todo_hr) ok(hr == tests[i].expected_hr, "Unexpected hr %#lx.\n", hr); + ok(hr == tests[i].expected_hr, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { ok(ID3DXBuffer_GetBufferSize(buffer) == tests[i].expected_buffer_size, "Unexpected buffer size %lu.\n", @@ -3462,25 +3455,21 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) ID3DXBuffer_Release(buffer); }
- todo_wine { hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)volume_texture, NULL); ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); - if (SUCCEEDED(hr)) - { - buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); - buffer_size = ID3DXBuffer_GetBufferSize(buffer); - hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); - ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK);
- ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256); - ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256); - ok(info.Depth == 256, "Got depth %u, expected %u\n", info.Depth, 256); - ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9); - ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE); - ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS); - ID3DXBuffer_Release(buffer); - } - } + buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); + buffer_size = ID3DXBuffer_GetBufferSize(buffer); + hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info); + ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); + + ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256); + ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256); + ok(info.Depth == 256, "Got depth %u, expected %u\n", info.Depth, 256); + ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9); + ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE); + ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS); + ID3DXBuffer_Release(buffer);
IDirect3DVolumeTexture9_Release(volume_texture);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 25f8ef6c6b4..9464cae6fa2 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1940,9 +1940,26 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE break; }
+ case D3DRTYPE_VOLUMETEXTURE: + { + IDirect3DVolumeTexture9 *texture = (IDirect3DVolumeTexture9 *)src_texture; + D3DVOLUME_DESC desc; + + hr = IDirect3DVolumeTexture9_GetLevelDesc(texture, 0, &desc); + if (FAILED(hr)) + break; + + fmt_desc = get_format_info(desc.Format); + if (is_unknown_format(fmt_desc)) + return E_NOTIMPL; + + set_volume_struct(&size, desc.Width, desc.Height, desc.Depth); + break; + }
default: - return E_NOTIMPL; + assert(0); /* Should not happen. */ + return E_FAIL; }
if (is_index_format(fmt_desc) && !src_palette) @@ -1970,51 +1987,83 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE if (FAILED(hr)) goto exit;
- for (j = 0; j < image.layer_count; ++j) + if (type != D3DRTYPE_VOLUMETEXTURE) { + for (j = 0; j < image.layer_count; ++j) + { + for (i = 0; i < levels; ++i) + { + IDirect3DSurface9 *src_surface, *tmp_surface; + struct d3dx_pixels src_pixels, dst_pixels; + D3DSURFACE_DESC src_surface_desc; + D3DLOCKED_RECT src_locked_rect; + RECT src_rect; + + hr = d3dx_image_get_pixels(&image, j, i, &dst_pixels); + if (FAILED(hr)) + goto exit; + + hr = get_surface(type, src_texture, j, i, &src_surface); + if (FAILED(hr)) + goto exit; + + hr = lock_surface(src_surface, NULL, &src_locked_rect, &tmp_surface, FALSE); + if (FAILED(hr)) + { + IDirect3DSurface9_Release(src_surface); + goto exit; + } + + IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); + SetRect(&src_rect, 0, 0, src_surface_desc.Width, src_surface_desc.Height); + set_d3dx_pixels(&src_pixels, src_locked_rect.pBits, src_locked_rect.Pitch, 0, src_palette, + src_surface_desc.Width, src_surface_desc.Height, 1, &src_rect); + + hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, D3DX_FILTER_NONE, 0); + if (FAILED(hr)) + { + unlock_surface(src_surface, NULL, tmp_surface, FALSE); + IDirect3DSurface9_Release(src_surface); + goto exit; + } + + hr = unlock_surface(src_surface, NULL, tmp_surface, FALSE); + IDirect3DSurface9_Release(src_surface); + if (FAILED(hr)) + goto exit; + } + } + } + else + { + IDirect3DVolumeTexture9 *volume_tex = (IDirect3DVolumeTexture9 *)src_texture; + for (i = 0; i < levels; ++i) { - IDirect3DSurface9 *src_surface, *tmp_surface; struct d3dx_pixels src_pixels, dst_pixels; - D3DSURFACE_DESC src_surface_desc; - D3DLOCKED_RECT src_locked_rect; + D3DVOLUME_DESC src_volume_desc; + D3DLOCKED_BOX src_locked_box; RECT src_rect;
- hr = d3dx_image_get_pixels(&image, j, i, &dst_pixels); + hr = d3dx_image_get_pixels(&image, 0, i, &dst_pixels); if (FAILED(hr)) goto exit;
- hr = get_surface(type, src_texture, j, i, &src_surface); + hr = IDirect3DVolumeTexture9_LockBox(volume_tex, i, &src_locked_box, NULL, D3DLOCK_READONLY); if (FAILED(hr)) goto exit;
- hr = lock_surface(src_surface, NULL, &src_locked_rect, &tmp_surface, FALSE); - if (FAILED(hr)) - { - IDirect3DSurface9_Release(src_surface); - goto exit; - } - - IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); - SetRect(&src_rect, 0, 0, src_surface_desc.Width, src_surface_desc.Height); - set_d3dx_pixels(&src_pixels, src_locked_rect.pBits, src_locked_rect.Pitch, 0, src_palette, - src_surface_desc.Width, src_surface_desc.Height, 1, &src_rect); + IDirect3DVolumeTexture9_GetLevelDesc(volume_tex, i, &src_volume_desc); + SetRect(&src_rect, 0, 0, src_volume_desc.Width, src_volume_desc.Height); + set_d3dx_pixels(&src_pixels, src_locked_box.pBits, src_locked_box.RowPitch, src_locked_box.SlicePitch, + src_palette, src_volume_desc.Width, src_volume_desc.Height, src_volume_desc.Depth, &src_rect);
hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, D3DX_FILTER_NONE, 0); - if (FAILED(hr)) - { - unlock_surface(src_surface, NULL, tmp_surface, FALSE); - IDirect3DSurface9_Release(src_surface); - goto exit; - } - - hr = unlock_surface(src_surface, NULL, tmp_surface, FALSE); - IDirect3DSurface9_Release(src_surface); + IDirect3DVolumeTexture9_UnlockBox(volume_tex, i); if (FAILED(hr)) goto exit; } } - *dst_buffer = buffer;
exit:
On Mon Mar 24 12:22:57 2025 +0000, Matteo Bruni wrote:
What happened here? I guess you originally had `21 * 6`, then replaced it with the result and the (unnecessary either way) parentheses remained? Same issue below.
Yeah I think you're right on having had `(21 * 6)` in a bunch of parentheses. Sorry for the mess, usually I'm pretty good at checking these things before pushing them out...
Would you prefer the parentheses around the flags being removed as well? I feel like it makes them more readable to me, but if you'd prefer I can remove them as well.
On Mon Mar 24 12:22:58 2025 +0000, Matteo Bruni wrote:
This is a bit awkward. For cube textures, this should be `IDirect3DCubeTexture9_GetLevelDesc((IDirect3DCubeTexture9 *)src_texture, ...` In practice the two `GetLevelDesc()` methods match in position in the respective vtbls and signature, so this works, but it's still technically a "bad" cast and it looks suspicious at first glance. I'd prefer to do this "by the book" and duplicate the `GetLevelDesc()` call for the two cases.
I just used `IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);` here on the surface instead of doing a separate call for each texture type, hopefully that's fine as well. I can change if it doing the separate calls makes the code clearer.
On Mon Mar 24 15:34:46 2025 +0000, Connor McAdams wrote:
Yeah doesn't seem at all related to native using higher chroma subsampling like I suspected :/ I encoded a 4:4:4 image with libjpeg to confirm `identify -verbose` could actually identify a 4:4:4 JPEG, which resulted in:
jpeg:colorspace: 2 jpeg:sampling-factor: 1x1,1x1,1x1
I then checked a JPEG produced by native which has:
jpeg:colorspace: 2 jpeg:sampling-factor: 2x2,1x1,1x1
And similarly, by default we produce:
jpeg:colorspace: 2 jpeg:sampling-factor: 2x2,1x1,1x1
It does give the `quality` value of native, which is 95 compared to what we have at 76. As I noticed before, upping the quality value does get us closer, but still further than I'd expect with a max_diff of 14. Really not sure why libjpeg is encoding images that are worse, must come down to some internal encoder conversion differences...
Alright, at least with that we get a significant improvement. Does the file size also roughly fall in the same range as native?
On Mon Mar 24 15:41:08 2025 +0000, Connor McAdams wrote:
I checked the difference between JPEG files encoded on 32-bit d3dx9 and 64-bit d3dx9, the files are identical. That makes me even more confused :D somehow the decoder behaves differently between the two.
:exploding_head:
Oh well. It sounds like we're in "nothing can depend on this, we shouldn't care" territory. The test might still need some tweaks, to update the comments and possibly merge the 32 and 64-bit checks. Up to you though.
P.S.: any obvious difference in JPEG file format handling with d3dx10 or 11?
On Mon Mar 24 22:24:53 2025 +0000, Connor McAdams wrote:
Yeah I think you're right on having had `(21 * 6)` in a bunch of parentheses. Sorry for the mess, usually I'm pretty good at checking these things before pushing them out... Would you prefer the parentheses around the flags being removed as well? I feel like it makes them more readable to me, but if you'd prefer I can remove them as well.
I don't find them useful, but I guess they don't look as jarring as the bare operand in parentheses.
On Mon Mar 24 12:22:58 2025 +0000, Matteo Bruni wrote:
Please fix indentation and get rid of those redundant parentheses.
To be clear, here I was referring to the 2-space indentation, which I don't think we normally use elsewhere in d3d-style code.
On Mon Mar 24 22:24:53 2025 +0000, Connor McAdams wrote:
I just used `IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);` here on the surface instead of doing a separate call for each texture type, hopefully that's fine as well. I can change if it doing the separate calls makes the code clearer.
That certainly works, even better :thumbsup: