[PATCH] d3dx9: Implement D3DXSHProjectCubeMap().
Zebediah Figura
zfigura at codeweavers.com
Sat Jan 29 19:46:43 CST 2022
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46284
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
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 | 143 ++++++++++++++++++++++++
dlls/d3dx9_36/surface.c | 2 +-
dlls/d3dx9_36/tests/math.c | 199 ++++++++++++++++++++++++++++++++++
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, 366 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..0dde552d45f 100644
--- a/dlls/d3dx9_36/math.c
+++ b/dlls/d3dx9_36/math.c
@@ -2969,6 +2969,149 @@ 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);
+ 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;
+ }
+
+ 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);
+
+ 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..40193f50fcc 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 <math.h>
+#include <stdint.h>
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", "d3d9_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,156 @@ static void test_D3DXSHScale(void)
}
}
+static void test_D3DXSHProjectCubeMap(void)
+{
+ float red[4], green[4], blue[4];
+ IDirect3DCubeTexture9 *texture;
+ unsigned int i, j, face, x, y;
+ 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, 1, 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);
+ }
+
+ 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 +4591,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);
--
2.34.1
More information about the wine-devel
mailing list