Matteo Bruni : d3dx9: Implement D3DXFillVolumeTexture function.
Alexandre Julliard
julliard at winehq.org
Thu Nov 18 11:09:32 CST 2010
Module: wine
Branch: master
Commit: 892502479c3acf64257e19ec4aac113024642f4d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=892502479c3acf64257e19ec4aac113024642f4d
Author: Matteo Bruni <mbruni at codeweavers.com>
Date: Mon Nov 15 23:28:09 2010 +0100
d3dx9: Implement D3DXFillVolumeTexture function.
---
dlls/d3dx9_36/d3dx9_36.spec | 2 +-
dlls/d3dx9_36/tests/texture.c | 116 +++++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/texture.c | 98 ++++++++++++++++++++++++++++++++++
3 files changed, 215 insertions(+), 1 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index 327c406..cbb6d20 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -126,7 +126,7 @@
@ stub D3DXFillCubeTextureTX
@ stdcall D3DXFillTexture(ptr ptr ptr)
@ stub D3DXFillTextureTX
-@ stub D3DXFillVolumeTexture
+@ stdcall D3DXFillVolumeTexture(ptr ptr ptr)
@ stub D3DXFillVolumeTextureTX
@ stdcall D3DXFilterTexture(ptr ptr long long)
@ stdcall D3DXFindShaderComment(ptr long ptr ptr)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index 2d5cd72..44e7719 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -932,6 +932,121 @@ static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device)
IDirect3DCubeTexture9_Release(tex);
}
+static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
+ const D3DXVECTOR3 *texelsize, void *data)
+{
+ value->x = texcoord->x;
+ value->y = texcoord->y;
+ value->z = texcoord->z;
+ value->w = texelsize->x;
+}
+
+static void test_D3DXFillVolumeTexture(IDirect3DDevice9 *device)
+{
+ IDirect3DVolumeTexture9 *tex;
+ HRESULT hr;
+ D3DLOCKED_BOX lock_box;
+ DWORD x, y, z, m;
+ DWORD v[4], e[4];
+ DWORD value, expected, size, row_pitch, slice_pitch;
+
+ size = 4;
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
+ ok(hr == D3D_OK, "D3DXFillVolumeTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ for (m = 0; m < 3; m++)
+ {
+ hr = IDirect3DVolumeTexture9_LockBox(tex, m, &lock_box, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ row_pitch = lock_box.RowPitch / sizeof(DWORD);
+ slice_pitch = lock_box.SlicePitch / sizeof(DWORD);
+ for (z = 0; z < size; z++)
+ {
+ for (y = 0; y < size; y++)
+ {
+ for (x = 0; x < size; x++)
+ {
+ value = ((DWORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
+ v[0] = (value >> 24) & 0xff;
+ v[1] = (value >> 16) & 0xff;
+ v[2] = (value >> 8) & 0xff;
+ v[3] = value & 0xff;
+
+ e[0] = 255.0f / size + 0.5f;
+ e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
+ e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
+ e[3] = (z + 0.5f) / size * 255.0f + 0.5f;
+ expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
+ x, y, z, value, expected);
+ }
+ }
+ }
+ IDirect3DVolumeTexture9_UnlockBox(tex, m);
+ }
+ size >>= 1;
+ }
+ }
+ else
+ skip("Failed to create texture\n");
+
+ IDirect3DVolumeTexture9_Release(tex);
+
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = IDirect3DVolumeTexture9_LockBox(tex, 0, &lock_box, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ row_pitch = lock_box.RowPitch / sizeof(WORD);
+ slice_pitch = lock_box.SlicePitch / sizeof(WORD);
+ for (z = 0; z < 4; z++)
+ {
+ for (y = 0; y < 4; y++)
+ {
+ for (x = 0; x < 4; x++)
+ {
+ value = ((WORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
+ v[0] = value >> 15;
+ v[1] = value >> 10 & 0x1f;
+ v[2] = value >> 5 & 0x1f;
+ v[3] = value & 0x1f;
+
+ e[0] = 1;
+ e[1] = (x + 0.5f) / 4 * 31.0f + 0.5f;
+ e[2] = (y + 0.5f) / 4 * 31.0f + 0.5f;
+ e[3] = (z + 0.5f) / 4 * 31.0f + 0.5f;
+ expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
+ x, y, z, value, expected);
+ }
+ }
+ }
+ IDirect3DVolumeTexture9_UnlockBox(tex, 0);
+ }
+ }
+ else
+ skip("Failed to create texture\n");
+
+ IDirect3DVolumeTexture9_Release(tex);
+}
+
START_TEST(texture)
{
HWND wnd;
@@ -970,6 +1085,7 @@ START_TEST(texture)
test_D3DXFilterTexture(device);
test_D3DXFillTexture(device);
test_D3DXFillCubeTexture(device);
+ test_D3DXFillVolumeTexture(device);
IDirect3DDevice9_Release(device);
IDirect3D9_Release(d3d);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index 550f61f..c6e2273 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -1163,3 +1163,101 @@ HRESULT WINAPI D3DXFillCubeTexture(LPDIRECT3DCUBETEXTURE9 texture,
return D3D_OK;
}
+
+HRESULT WINAPI D3DXFillVolumeTexture(LPDIRECT3DVOLUMETEXTURE9 texture,
+ LPD3DXFILL3D function,
+ LPVOID funcdata)
+{
+ DWORD miplevels;
+ DWORD m, i, x, y, z, c, v;
+ D3DVOLUME_DESC desc;
+ D3DLOCKED_BOX lock_box;
+ D3DXVECTOR4 value;
+ D3DXVECTOR3 coord, size;
+ const PixelFormatDesc *format;
+ BYTE *data, *pos;
+ BYTE byte, mask;
+ float comp_value;
+
+ if (texture == NULL || function == NULL)
+ return D3DERR_INVALIDCALL;
+
+ miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
+
+ for (m = 0; m < miplevels; m++)
+ {
+ if (FAILED(IDirect3DVolumeTexture9_GetLevelDesc(texture, m, &desc)))
+ return D3DERR_INVALIDCALL;
+
+ format = get_format_info(desc.Format);
+ if (format->format == D3DFMT_UNKNOWN)
+ {
+ FIXME("Unsupported texture format %#x\n", desc.Format);
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (FAILED(IDirect3DVolumeTexture9_LockBox(texture, m, &lock_box, NULL, D3DLOCK_DISCARD)))
+ return D3DERR_INVALIDCALL;
+
+ size.x = 1.0f / desc.Width;
+ size.y = 1.0f / desc.Height;
+ size.z = 1.0f / desc.Depth;
+
+ data = lock_box.pBits;
+
+ for (z = 0; z < desc.Depth; z++)
+ {
+ /* The callback function expects the coordinates of the center
+ of the texel */
+ coord.z = (z + 0.5f) / desc.Depth;
+
+ for (y = 0; y < desc.Height; y++)
+ {
+ coord.y = (y + 0.5f) / desc.Height;
+
+ for (x = 0; x < desc.Width; x++)
+ {
+ coord.x = (x + 0.5f) / desc.Width;
+
+ function(&value, &coord, &size, funcdata);
+
+ pos = data + z * lock_box.SlicePitch + y * lock_box.RowPitch + x * format->bytes_per_pixel;
+
+ for (i = 0; i < format->bytes_per_pixel; i++)
+ pos[i] = 0;
+
+ for (c = 0; c < 4; c++)
+ {
+ switch (c)
+ {
+ case 0: /* Alpha */
+ comp_value = value.w;
+ break;
+ case 1: /* Red */
+ comp_value = value.x;
+ break;
+ case 2: /* Green */
+ comp_value = value.y;
+ break;
+ case 3: /* Blue */
+ comp_value = value.z;
+ break;
+ }
+
+ v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
+
+ for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
+ {
+ mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
+ byte = (v << format->shift[c] >> i) & mask;
+ pos[i / 8] |= byte;
+ }
+ }
+ }
+ }
+ }
+ IDirect3DVolumeTexture9_UnlockBox(texture, m);
+ }
+
+ return D3D_OK;
+}
More information about the wine-cvs
mailing list