From d049e5dc1cfc3ad54fbac7ed53d808f5177c1994 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 3 Feb 2022 20:03:21 -0600 Subject: [PATCH] d3dx9: Implement D3DXSHProjectCubeMap(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46284 Signed-off-by: Zebediah Figura Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3dx9_24/d3dx9_24.spec | 2 +- dlls/d3dx9_25/d3dx9_25.spec | 2 +- dlls/d3dx9_26/d3dx9_26.spec | 2 +- dlls/d3dx9_27/d3dx9_27.spec | 2 +- dlls/d3dx9_28/d3dx9_28.spec | 2 +- dlls/d3dx9_29/d3dx9_29.spec | 2 +- dlls/d3dx9_30/d3dx9_30.spec | 2 +- dlls/d3dx9_31/d3dx9_31.spec | 2 +- dlls/d3dx9_32/d3dx9_32.spec | 2 +- dlls/d3dx9_33/d3dx9_33.spec | 2 +- dlls/d3dx9_34/d3dx9_34.spec | 2 +- dlls/d3dx9_35/d3dx9_35.spec | 2 +- dlls/d3dx9_36/d3dx9_36.spec | 2 +- dlls/d3dx9_36/d3dx9_private.h | 2 + dlls/d3dx9_36/math.c | 147 ++++++++++++++++++++++++ dlls/d3dx9_36/surface.c | 2 +- dlls/d3dx9_36/tests/math.c | 208 ++++++++++++++++++++++++++++++++++ dlls/d3dx9_37/d3dx9_37.spec | 2 +- dlls/d3dx9_38/d3dx9_38.spec | 2 +- dlls/d3dx9_39/d3dx9_39.spec | 2 +- dlls/d3dx9_40/d3dx9_40.spec | 2 +- dlls/d3dx9_41/d3dx9_41.spec | 2 +- dlls/d3dx9_42/d3dx9_42.spec | 2 +- dlls/d3dx9_43/d3dx9_43.spec | 2 +- include/d3dx9math.h | 1 + 25 files changed, 379 insertions(+), 21 deletions(-) diff --git a/dlls/d3dx9_24/d3dx9_24.spec b/dlls/d3dx9_24/d3dx9_24.spec index d617d766f85..8791e4ec044 100644 --- a/dlls/d3dx9_24/d3dx9_24.spec +++ b/dlls/d3dx9_24/d3dx9_24.spec @@ -256,7 +256,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_25/d3dx9_25.spec b/dlls/d3dx9_25/d3dx9_25.spec index f13923dcb3a..0431a9f7f75 100644 --- a/dlls/d3dx9_25/d3dx9_25.spec +++ b/dlls/d3dx9_25/d3dx9_25.spec @@ -256,7 +256,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_26/d3dx9_26.spec b/dlls/d3dx9_26/d3dx9_26.spec index 286a9a094a0..5ab0a1d9fea 100644 --- a/dlls/d3dx9_26/d3dx9_26.spec +++ b/dlls/d3dx9_26/d3dx9_26.spec @@ -260,7 +260,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_27/d3dx9_27.spec b/dlls/d3dx9_27/d3dx9_27.spec index 286a9a094a0..5ab0a1d9fea 100644 --- a/dlls/d3dx9_27/d3dx9_27.spec +++ b/dlls/d3dx9_27/d3dx9_27.spec @@ -260,7 +260,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_28/d3dx9_28.spec b/dlls/d3dx9_28/d3dx9_28.spec index 06ced20df61..af5b6077202 100644 --- a/dlls/d3dx9_28/d3dx9_28.spec +++ b/dlls/d3dx9_28/d3dx9_28.spec @@ -265,7 +265,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_29/d3dx9_29.spec b/dlls/d3dx9_29/d3dx9_29.spec index 06ced20df61..af5b6077202 100644 --- a/dlls/d3dx9_29/d3dx9_29.spec +++ b/dlls/d3dx9_29/d3dx9_29.spec @@ -265,7 +265,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_30/d3dx9_30.spec b/dlls/d3dx9_30/d3dx9_30.spec index 06ced20df61..af5b6077202 100644 --- a/dlls/d3dx9_30/d3dx9_30.spec +++ b/dlls/d3dx9_30/d3dx9_30.spec @@ -265,7 +265,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_31/d3dx9_31.spec b/dlls/d3dx9_31/d3dx9_31.spec index c9aca309a35..8f77dc666a2 100644 --- a/dlls/d3dx9_31/d3dx9_31.spec +++ b/dlls/d3dx9_31/d3dx9_31.spec @@ -262,7 +262,7 @@ @ stdcall D3DXSHEvalSphericalLight(long ptr float float float float ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_32/d3dx9_32.spec b/dlls/d3dx9_32/d3dx9_32.spec index f541f6f2ef1..2fdd2a00615 100644 --- a/dlls/d3dx9_32/d3dx9_32.spec +++ b/dlls/d3dx9_32/d3dx9_32.spec @@ -267,7 +267,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_33/d3dx9_33.spec b/dlls/d3dx9_33/d3dx9_33.spec index f541f6f2ef1..2fdd2a00615 100644 --- a/dlls/d3dx9_33/d3dx9_33.spec +++ b/dlls/d3dx9_33/d3dx9_33.spec @@ -267,7 +267,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_34/d3dx9_34.spec b/dlls/d3dx9_34/d3dx9_34.spec index f541f6f2ef1..2fdd2a00615 100644 --- a/dlls/d3dx9_34/d3dx9_34.spec +++ b/dlls/d3dx9_34/d3dx9_34.spec @@ -267,7 +267,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_35/d3dx9_35.spec b/dlls/d3dx9_35/d3dx9_35.spec index f541f6f2ef1..2fdd2a00615 100644 --- a/dlls/d3dx9_35/d3dx9_35.spec +++ b/dlls/d3dx9_35/d3dx9_35.spec @@ -267,7 +267,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index e1f44261610..5b7070145de 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -269,7 +269,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index c3308b04d44..2d286b04694 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -100,6 +100,8 @@ HRESULT write_buffer_to_file(const WCHAR *filename, ID3DXBuffer *buffer) DECLSPE const struct pixel_format_desc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN; const struct pixel_format_desc *get_format_info_idx(int idx) DECLSPEC_HIDDEN; +void format_to_vec4(const struct pixel_format_desc *format, const BYTE *src, struct vec4 *dst); + void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size, const struct pixel_format_desc *format) DECLSPEC_HIDDEN; diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c index a7b0a018680..80f357e00e9 100644 --- a/dlls/d3dx9_36/math.c +++ b/dlls/d3dx9_36/math.c @@ -2969,6 +2969,153 @@ static void rotate_X(FLOAT *out, UINT order, FLOAT a, FLOAT *in) out[35] = 0.9057110548f * in[31] - 0.4192627370f * in[33] + 0.0624999329f * in[35]; } +static void set_vec3(D3DXVECTOR3 *v, float x, float y, float z) +{ + v->x = x; + v->y = y; + v->z = z; +} + +/* + * The following implementation of D3DXSHProjectCubeMap is based on the + * SHProjectCubeMap() implementation from Microsoft's DirectXMath library, + * covered under the following copyright: + * + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + */ +HRESULT WINAPI D3DXSHProjectCubeMap(unsigned int order, IDirect3DCubeTexture9 *texture, float *red, float *green, float *blue) +{ + const unsigned int order_square = order * order; + const struct pixel_format_desc *format; + unsigned int x, y, i, face; + float B, S, proj_normal; + D3DSURFACE_DESC desc; + float Wt = 0.0f; + float *temp; + HRESULT hr; + + TRACE("order %u, texture %p, red %p, green %p, blue %p.\n", order, texture, red, green, blue); + + if (!texture || !red || order < D3DXSH_MINORDER || order > D3DXSH_MAXORDER) + return D3DERR_INVALIDCALL; + + memset(red, 0, order_square * sizeof(float)); + if (green) + memset(green, 0, order_square * sizeof(float)); + if (blue) + memset(blue, 0, order_square * sizeof(float)); + + if (FAILED(hr = IDirect3DCubeTexture9_GetLevelDesc(texture, 0, &desc))) + { + ERR("Failed to get level desc, hr %#x.\n", hr); + return hr; + } + + format = get_format_info(desc.Format); + if (format->type != FORMAT_ARGB && format->type != FORMAT_ARGBF16 && format->type != FORMAT_ARGBF) + { + FIXME("Unsupported texture format %#x.\n", desc.Format); + return D3DERR_INVALIDCALL; + } + + if (!(temp = malloc(order_square * sizeof(*temp)))) + return E_OUTOFMEMORY; + + B = -1.0f + 1.0f / desc.Width; + if (desc.Width > 1) + S = 2.0f * (1.0f - 1.0f / desc.Width) / (desc.Width - 1.0f); + else + S = 0.0f; + + for (face = 0; face < 6; ++face) + { + D3DLOCKED_RECT map_desc; + + if (FAILED(hr = IDirect3DCubeTexture9_LockRect(texture, face, 0, &map_desc, NULL, D3DLOCK_READONLY))) + { + ERR("Failed to map texture, hr %#x.\n", hr); + free(temp); + return hr; + } + + for (y = 0; y < desc.Height; ++y) + { + const BYTE *row = (const BYTE *)map_desc.pBits + y * map_desc.Pitch; + + for (x = 0; x < desc.Width; ++x) + { + float diff_solid, x_3d, y_3d; + const float u = x * S + B; + const float v = y * S + B; + struct vec4 colour; + D3DXVECTOR3 dir; + + x_3d = (x * 2.0f + 1.0f) / desc.Width - 1.0f; + y_3d = (y * 2.0f + 1.0f) / desc.Width - 1.0f; + + switch (face) + { + case D3DCUBEMAP_FACE_POSITIVE_X: + set_vec3(&dir, 1.0f, -y_3d, -x_3d); + break; + + case D3DCUBEMAP_FACE_NEGATIVE_X: + set_vec3(&dir, -1.0f, -y_3d, x_3d); + break; + + case D3DCUBEMAP_FACE_POSITIVE_Y: + set_vec3(&dir, x_3d, 1.0f, y_3d); + break; + + case D3DCUBEMAP_FACE_NEGATIVE_Y: + set_vec3(&dir, x_3d, -1.0f, -y_3d); + break; + + case D3DCUBEMAP_FACE_POSITIVE_Z: + set_vec3(&dir, x_3d, -y_3d, 1.0f); + break; + + case D3DCUBEMAP_FACE_NEGATIVE_Z: + set_vec3(&dir, -x_3d, -y_3d, -1.0f); + break; + } + + /* This is more complex than powf(..., 1.5f), but also happens + * to be slightly more accurate, and slightly faster as well. */ + diff_solid = 4.0f / ((1.0f + u * u + v * v) * sqrtf(1.0f + u * u + v * v)); + Wt += diff_solid; + + D3DXVec3Normalize(&dir, &dir); + D3DXSHEvalDirection(temp, order, &dir); + + format_to_vec4(format, &row[x * format->block_byte_count], &colour); + + for (i = 0; i < order_square; ++i) + { + red[i] += temp[i] * colour.x * diff_solid; + if (green) + green[i] += temp[i] * colour.y * diff_solid; + if (blue) + blue[i] += temp[i] * colour.z * diff_solid; + } + } + } + + IDirect3DCubeTexture9_UnlockRect(texture, face, 0); + } + + proj_normal = (4.0f * M_PI) / Wt; + D3DXSHScale(red, order, red, proj_normal); + if (green) + D3DXSHScale(green, order, green, proj_normal); + if (blue) + D3DXSHScale(blue, order, blue, proj_normal); + + free(temp); + return D3D_OK; +} + FLOAT* WINAPI D3DXSHRotate(FLOAT *out, UINT order, const D3DXMATRIX *matrix, const FLOAT *in) { FLOAT alpha, beta, gamma, sinb, temp[36], temp1[36]; diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index c3f9f84a789..2ca6f093b55 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1564,7 +1564,7 @@ static DWORD make_argb_color(const struct argb_conversion_info *info, const DWOR } /* It doesn't work for components bigger than 32 bits (or somewhat smaller but unaligned). */ -static void format_to_vec4(const struct pixel_format_desc *format, const BYTE *src, struct vec4 *dst) +void format_to_vec4(const struct pixel_format_desc *format, const BYTE *src, struct vec4 *dst) { DWORD mask, tmp; unsigned int c; diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c index 6f64e25d200..62f4eaec124 100644 --- a/dlls/d3dx9_36/tests/math.c +++ b/dlls/d3dx9_36/tests/math.c @@ -22,6 +22,7 @@ #include "wine/test.h" #include "d3dx9.h" #include +#include static BOOL compare_float(float f, float g, unsigned int ulps) { @@ -205,6 +206,53 @@ static void set_matrix(D3DXMATRIX* mat, U(mat)->m[3][0] = m30; U(mat)->m[3][1] = m31; U(mat)->m[3][2] = m32; U(mat)->m[3][3] = m33; } +static HWND create_window(void) +{ + RECT r = {0, 0, 640, 480}; + + AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + + return CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); +} + +static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window) +{ + D3DPRESENT_PARAMETERS present_parameters = {0}; + unsigned int adapter_ordinal; + IDirect3DDevice9 *device; + DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING; + + adapter_ordinal = D3DADAPTER_DEFAULT; + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.hDeviceWindow = focus_window; + present_parameters.Windowed = TRUE; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + + if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, adapter_ordinal, D3DDEVTYPE_HAL, focus_window, + behavior_flags, &present_parameters, &device))) + return device; + + present_parameters.AutoDepthStencilFormat = D3DFMT_D16; + if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, adapter_ordinal, D3DDEVTYPE_HAL, focus_window, + behavior_flags, &present_parameters, &device))) + return device; + + behavior_flags = (behavior_flags + & ~(D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING)) + | D3DCREATE_HARDWARE_VERTEXPROCESSING; + + if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, adapter_ordinal, D3DDEVTYPE_HAL, focus_window, + behavior_flags, &present_parameters, &device))) + return device; + + return NULL; +} + static void D3DXColorTest(void) { D3DXCOLOR color, color1, color2, expected, got; @@ -4364,6 +4412,165 @@ static void test_D3DXSHScale(void) } } +static void test_D3DXSHProjectCubeMap(void) +{ + unsigned int i, j, level, face, x, y; + float red[4], green[4], blue[4]; + IDirect3DCubeTexture9 *texture; + IDirect3DDevice9 *device; + D3DLOCKED_RECT map_desc; + IDirect3D9 *d3d; + ULONG refcount; + HWND window; + HRESULT hr; + + static const struct + { + D3DFORMAT format; + float red[4]; + float green[4]; + float blue[4]; + } + tests[] = + { + {D3DFMT_A8R8G8B8, + {1.77656245f, -1.11197047e-2f, 2.08763797e-2f, -2.10229922e-2f}, + {1.75811982f, -4.82511893e-2f, 1.67397819e-2f, -1.71497762e-2f}, + {1.75515056f, -4.07523997e-2f, 1.05397226e-2f, -2.46812664e-2f}}, + {D3DFMT_X8R8G8B8, + {1.77656245f, -1.11197047e-2f, 2.08763797e-2f, -2.10229922e-2f}, + {1.75811982f, -4.82511893e-2f, 1.67397819e-2f, -1.71497762e-2f}, + {1.75515056f, -4.07523997e-2f, 1.05397226e-2f, -2.46812664e-2f}}, + {D3DFMT_A8B8G8R8, + {1.75515056f, -4.07523997e-2f, 1.05397226e-2f, -2.46812664e-2f}, + {1.75811982f, -4.82511893e-2f, 1.67397819e-2f, -1.71497762e-2f}, + {1.77656245f, -1.11197047e-2f, 2.08763797e-2f, -2.10229922e-2f}}, + {D3DFMT_R5G6B5, + {1.77099848f, -3.88867334e-2f, 6.73775524e-2f, -1.26888147e-2f}, + {1.77244151f, -5.64723741e-4f, -2.77878426e-4f, -9.10691451e-3f}, + {1.78902030f, 2.79005636e-2f, 1.62461456e-2f, 2.21668324e-3f}}, + {D3DFMT_A1R5G5B5, + {1.78022826f, 1.46923587e-2f, 3.58058624e-2f, 2.51076911e-2f}, + {1.77233493f, -7.58088892e-4f, -2.03727093e-3f, -1.34809706e-2f}, + {1.78902030f, 2.79005636e-2f, 1.62461456e-2f, 2.21668324e-3f}}, + {D3DFMT_X1R5G5B5, + {1.78022826f, 1.46923587e-2f, 3.58058624e-2f, 2.51076911e-2f}, + {1.77233493f, -7.58088892e-4f, -2.03727093e-3f, -1.34809706e-2f}, + {1.78902030f, 2.79005636e-2f, 1.62461456e-2f, 2.21668324e-3f}}, + {D3DFMT_A2R10G10B10, + {1.79359019f, -7.74506712e-4f, 8.65613017e-3f, 5.75336441e-3f}, + {1.77067971f, 6.42523961e-3f, 1.35379164e-2f, 2.24088971e-3f}, + {1.76601243f, -4.94002625e-2f, 1.28124524e-2f, -7.69229094e-3f}}, + {D3DFMT_A2B10G10R10, + {1.76601243f, -4.94002625e-2f, 1.28124524e-2f, -7.69229094e-3f}, + {1.77067971f, 6.42523961e-3f, 1.35379164e-2f, 2.24088971e-3f}, + {1.79359019f, -7.74506712e-4f, 8.65613017e-3f, 5.75336441e-3f}}, + {D3DFMT_A16B16G16R16, + {1.75979614f, 1.44450525e-2f, -3.25212209e-3f, 2.98178056e-3f}, + {1.78080165f, -2.63770130e-2f, 6.31967233e-3f, 3.66022950e-3f}, + {1.77588308f, -1.93727610e-3f, -3.22831096e-3f, -6.18841546e-3f}}, + {D3DFMT_A16B16G16R16F, + { 5.17193642e+1f, -3.41681671e+2f, -8.82221741e+2f, 7.77049316e+2f}, + {-2.08198950e+3f, 5.24323584e+3f, -3.42663379e+3f, 3.80999243e+3f}, + {-1.10743945e+3f, -9.43649292e+2f, 5.48424316e+2f, 1.65352710e+3f}}, + }; + + window = create_window(); + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d, window))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D9_Release(d3d); + DestroyWindow(window); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("Format %#x", tests[i].format); + + hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 4, D3DUSAGE_DYNAMIC, + tests[i].format, D3DPOOL_DEFAULT, &texture, NULL); + if (FAILED(hr)) + { + skip("Failed to create cube texture.\n"); + winetest_pop_context(); + continue; + } + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (face = 0; face < 6; ++face) + { + hr = IDirect3DCubeTexture9_LockRect(texture, face, 0, &map_desc, NULL, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (y = 0; y < 8; ++y) + { + uint8_t *row = (uint8_t *)map_desc.pBits + y * map_desc.Pitch; + + for (x = 0; x < map_desc.Pitch; ++x) + row[x] = face * 111 + y * 39 + x * 7; + } + + hr = IDirect3DCubeTexture9_UnlockRect(texture, face, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (level = 1; level < 4; ++level) + { + hr = IDirect3DCubeTexture9_LockRect(texture, face, level, &map_desc, NULL, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + memset(map_desc.pBits, 0xcc, 4 * map_desc.Pitch); + hr = IDirect3DCubeTexture9_UnlockRect(texture, face, level); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + } + } + + hr = D3DXSHProjectCubeMap(1, texture, red, green, blue); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + hr = D3DXSHProjectCubeMap(7, texture, red, green, blue); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + hr = D3DXSHProjectCubeMap(2, NULL, red, green, blue); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + memset(red, 0, sizeof(red)); + memset(green, 0, sizeof(green)); + memset(blue, 0, sizeof(blue)); + hr = D3DXSHProjectCubeMap(2, texture, red, green, blue); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (j = 0; j < 4; ++j) + { + ok(compare_float(red[j], tests[i].red[j], 1024), + "Got unexpected value %.8e for red coefficient %u.\n", red[j], j); + ok(compare_float(green[j], tests[i].green[j], 1024), + "Got unexpected value %.8e for green coefficient %u.\n", green[j], j); + ok(compare_float(blue[j], tests[i].blue[j], 1024), + "Got unexpected value %.8e for blue coefficient %u.\n", blue[j], j); + } + + hr = D3DXSHProjectCubeMap(2, texture, red, NULL, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = D3DXSHProjectCubeMap(2, texture, NULL, green, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + hr = D3DXSHProjectCubeMap(2, texture, NULL, NULL, blue); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + IDirect3DCubeTexture9_Release(texture); + + winetest_pop_context(); + } + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + START_TEST(math) { D3DXColorTest(); @@ -4393,4 +4600,5 @@ START_TEST(math) test_D3DXSHRotate(); test_D3DXSHRotateZ(); test_D3DXSHScale(); + test_D3DXSHProjectCubeMap(); } diff --git a/dlls/d3dx9_37/d3dx9_37.spec b/dlls/d3dx9_37/d3dx9_37.spec index e1f44261610..5b7070145de 100644 --- a/dlls/d3dx9_37/d3dx9_37.spec +++ b/dlls/d3dx9_37/d3dx9_37.spec @@ -269,7 +269,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_38/d3dx9_38.spec b/dlls/d3dx9_38/d3dx9_38.spec index e1f44261610..5b7070145de 100644 --- a/dlls/d3dx9_38/d3dx9_38.spec +++ b/dlls/d3dx9_38/d3dx9_38.spec @@ -269,7 +269,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_39/d3dx9_39.spec b/dlls/d3dx9_39/d3dx9_39.spec index e1f44261610..5b7070145de 100644 --- a/dlls/d3dx9_39/d3dx9_39.spec +++ b/dlls/d3dx9_39/d3dx9_39.spec @@ -269,7 +269,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_40/d3dx9_40.spec b/dlls/d3dx9_40/d3dx9_40.spec index e1f44261610..5b7070145de 100644 --- a/dlls/d3dx9_40/d3dx9_40.spec +++ b/dlls/d3dx9_40/d3dx9_40.spec @@ -269,7 +269,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_41/d3dx9_41.spec b/dlls/d3dx9_41/d3dx9_41.spec index e1f44261610..5b7070145de 100644 --- a/dlls/d3dx9_41/d3dx9_41.spec +++ b/dlls/d3dx9_41/d3dx9_41.spec @@ -269,7 +269,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_42/d3dx9_42.spec b/dlls/d3dx9_42/d3dx9_42.spec index 0851945d36b..4a418d1508a 100644 --- a/dlls/d3dx9_42/d3dx9_42.spec +++ b/dlls/d3dx9_42/d3dx9_42.spec @@ -262,7 +262,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/dlls/d3dx9_43/d3dx9_43.spec b/dlls/d3dx9_43/d3dx9_43.spec index 0851945d36b..4a418d1508a 100644 --- a/dlls/d3dx9_43/d3dx9_43.spec +++ b/dlls/d3dx9_43/d3dx9_43.spec @@ -262,7 +262,7 @@ @ stub D3DXSHMultiply6(ptr ptr ptr) @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr) @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr) -@ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr) +@ stdcall D3DXSHProjectCubeMap(long ptr ptr ptr ptr) @ stdcall D3DXSHRotate(ptr long ptr ptr) @ stdcall D3DXSHRotateZ(ptr long float ptr) @ stdcall D3DXSHScale(ptr long ptr float) diff --git a/include/d3dx9math.h b/include/d3dx9math.h index bf03ca3abaa..32d894f9fed 100644 --- a/include/d3dx9math.h +++ b/include/d3dx9math.h @@ -396,6 +396,7 @@ HRESULT WINAPI D3DXSHEvalSphericalLight(UINT order, const D3DXVECTOR3 *dir, FLOA FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, const FLOAT *a, const FLOAT *b); FLOAT* WINAPI D3DXSHMultiply3(FLOAT *out, const FLOAT *a, const FLOAT *b); FLOAT* WINAPI D3DXSHMultiply4(FLOAT *out, const FLOAT *a, const FLOAT *b); +HRESULT WINAPI D3DXSHProjectCubeMap(UINT order, IDirect3DCubeTexture9 *texture, FLOAT *red, FLOAT *green, FLOAT *blue); FLOAT* WINAPI D3DXSHRotate(FLOAT *out, UINT order, const D3DXMATRIX *matrix, const FLOAT *in); FLOAT* WINAPI D3DXSHRotateZ(FLOAT *out, UINT order, FLOAT angle, const FLOAT *in); FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, const FLOAT *a, const FLOAT scale);