[1/4] d3dx9: Implement pixel format conversion for volume textures.
Józef Kucia
joseph.kucia at gmail.com
Fri Jul 13 10:21:52 CDT 2012
---
dlls/d3dx9_36/d3dx9_36_private.h | 4 +
dlls/d3dx9_36/surface.c | 121 ++++++++++++++++++++-----------------
dlls/d3dx9_36/tests/volume.c | 17 +++++-
dlls/d3dx9_36/volume.c | 39 ++++++++++++-
4 files changed, 122 insertions(+), 59 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index d10cea0..fec9ede 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -64,6 +64,10 @@ HRESULT write_buffer_to_file(const WCHAR *filename, ID3DXBuffer *buffer) DECLSPE
const PixelFormatDesc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN;
const PixelFormatDesc *get_format_info_idx(int idx) DECLSPEC_HIDDEN;
+void copy_simple_data(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, SIZE src_size, UINT src_depth, const PixelFormatDesc *src_format,
+ BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, SIZE dst_size, UINT dst_depth, const PixelFormatDesc *dst_format,
+ D3DCOLOR color_key) DECLSPEC_HIDDEN;
+
HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette,
DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index c1835b7..433c251 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -1255,85 +1255,94 @@ static void format_from_vec4(const PixelFormatDesc *format, const struct vec4 *s
* Pixels outsize the source rect are blacked out.
* Works only for ARGB formats with 1 - 4 bytes per pixel.
*/
-static void copy_simple_data(const BYTE *src, UINT srcpitch, SIZE src_size, const PixelFormatDesc *srcformat,
- BYTE *dest, UINT destpitch, SIZE dst_size, const PixelFormatDesc *destformat, D3DCOLOR colorkey)
+void copy_simple_data(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, SIZE src_size, UINT src_depth, const PixelFormatDesc *src_format,
+ BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, SIZE dst_size, UINT dst_depth, const PixelFormatDesc *dst_format, D3DCOLOR color_key)
{
struct argb_conversion_info conv_info, ck_conv_info;
const PixelFormatDesc *ck_format = NULL;
DWORD channels[4], pixel;
- UINT minwidth, minheight;
- UINT x, y;
+ UINT min_width, min_height, min_depth;
+ UINT x, y, z;
ZeroMemory(channels, sizeof(channels));
- init_argb_conversion_info(srcformat, destformat, &conv_info);
+ init_argb_conversion_info(src_format, dst_format, &conv_info);
- minwidth = (src_size.cx < dst_size.cx) ? src_size.cx : dst_size.cx;
- minheight = (src_size.cy < dst_size.cy) ? src_size.cy : dst_size.cy;
+ min_width = min(src_size.cx, dst_size.cx);
+ min_height = min(src_size.cy, dst_size.cy);
+ min_depth = min(src_depth, dst_depth);
- if (colorkey)
+ if (color_key)
{
/* Color keys are always represented in D3DFMT_A8R8G8B8 format. */
ck_format = get_format_info(D3DFMT_A8R8G8B8);
- init_argb_conversion_info(srcformat, ck_format, &ck_conv_info);
+ init_argb_conversion_info(src_format, ck_format, &ck_conv_info);
}
- for(y = 0;y < minheight;y++) {
- const BYTE *srcptr = src + y * srcpitch;
- BYTE *destptr = dest + y * destpitch;
- DWORD val;
+ for (z = 0; z < min_depth; z++) {
+ const BYTE *src_slice_ptr = src + z * src_slice_pitch;
+ BYTE *dst_slice_ptr = dst + z * dst_slice_pitch;
- for(x = 0;x < minwidth;x++) {
- /* extract source color components */
- pixel = dword_from_bytes(srcptr, srcformat->bytes_per_pixel);
+ for (y = 0; y < min_height; y++) {
+ const BYTE *src_ptr = src_slice_ptr + y * src_row_pitch;
+ BYTE *dst_ptr = dst_slice_ptr + y * dst_row_pitch;
+ DWORD val;
- if (!srcformat->to_rgba && !destformat->from_rgba)
- {
- get_relevant_argb_components(&conv_info, pixel, channels);
- val = make_argb_color(&conv_info, channels);
+ for (x = 0; x < min_width; x++) {
+ /* extract source color components */
+ pixel = dword_from_bytes(src_ptr, src_format->bytes_per_pixel);
- if (colorkey)
+ if (!src_format->to_rgba && !dst_format->from_rgba)
{
- get_relevant_argb_components(&ck_conv_info, pixel, channels);
- pixel = make_argb_color(&ck_conv_info, channels);
- if (pixel == colorkey)
- val &= ~conv_info.destmask[0];
+ get_relevant_argb_components(&conv_info, pixel, channels);
+ val = make_argb_color(&conv_info, channels);
+
+ if (color_key)
+ {
+ get_relevant_argb_components(&ck_conv_info, pixel, channels);
+ pixel = make_argb_color(&ck_conv_info, channels);
+ if (pixel == color_key)
+ val &= ~conv_info.destmask[0];
+ }
}
- }
- else
- {
- struct vec4 color, tmp;
-
- format_to_vec4(srcformat, &pixel, &color);
- if (srcformat->to_rgba)
- srcformat->to_rgba(&color, &tmp);
else
- tmp = color;
-
- if (ck_format)
{
- format_from_vec4(ck_format, &tmp, &pixel);
- if (pixel == colorkey)
- tmp.w = 0.0f;
- }
+ struct vec4 color, tmp;
+
+ format_to_vec4(src_format, &pixel, &color);
+ if (src_format->to_rgba)
+ src_format->to_rgba(&color, &tmp);
+ else
+ tmp = color;
+
+ if (ck_format)
+ {
+ format_from_vec4(ck_format, &tmp, &pixel);
+ if (pixel == color_key)
+ tmp.w = 0.0f;
+ }
- if (destformat->from_rgba)
- destformat->from_rgba(&tmp, &color);
- else
- color = tmp;
+ if (dst_format->from_rgba)
+ dst_format->from_rgba(&tmp, &color);
+ else
+ color = tmp;
- format_from_vec4(destformat, &color, &val);
+ format_from_vec4(dst_format, &color, &val);
+ }
+
+ dword_to_bytes(dst_ptr, val, dst_format->bytes_per_pixel);
+ src_ptr += src_format->bytes_per_pixel;
+ dst_ptr += dst_format->bytes_per_pixel;
}
- dword_to_bytes(destptr, val, destformat->bytes_per_pixel);
- srcptr += srcformat->bytes_per_pixel;
- destptr += destformat->bytes_per_pixel;
+ if (src_size.cx < dst_size.cx) /* black out remaining pixels */
+ memset(dst_ptr, 0, dst_format->bytes_per_pixel * (dst_size.cx - src_size.cx));
}
- if (src_size.cx < dst_size.cx) /* black out remaining pixels */
- memset(destptr, 0, destformat->bytes_per_pixel * (dst_size.cx - src_size.cx));
+ if (src_size.cy < dst_size.cy) /* black out remaining pixels */
+ memset(dst + src_size.cy * dst_row_pitch, 0, dst_row_pitch * (dst_size.cy - src_size.cy));
}
- if (src_size.cy < dst_size.cy) /* black out remaining pixels */
- memset(dest + src_size.cy * destpitch, 0, destpitch * (dst_size.cy - src_size.cy));
+ if (src_depth < dst_depth) /* black out remaining pixels */
+ memset(dst + src_depth * dst_slice_pitch, 0, dst_slice_pitch * (dst_depth - src_depth));
}
/************************************************************
@@ -1562,8 +1571,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
if ((filter & 0xf) == D3DX_FILTER_NONE)
{
- copy_simple_data(src_memory, src_pitch, src_size, srcformatdesc,
- lockrect.pBits, lockrect.Pitch, dst_size, destformatdesc, color_key);
+ copy_simple_data(src_memory, src_pitch, 0, src_size, 1, srcformatdesc,
+ lockrect.pBits, lockrect.Pitch, 0, dst_size, 1, destformatdesc, color_key);
}
else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */
{
@@ -1854,8 +1863,8 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
hr = IDirect3DSurface9_LockRect(src_surface, &locked_rect, src_rect, D3DLOCK_READONLY);
if (SUCCEEDED(hr))
{
- copy_simple_data(locked_rect.pBits, locked_rect.Pitch, size, src_format_desc,
- dst_data, dst_pitch, size, dst_format_desc, 0);
+ copy_simple_data(locked_rect.pBits, locked_rect.Pitch, 0, size, 1, src_format_desc,
+ dst_data, dst_pitch, 0, size, 1, dst_format_desc, 0);
IDirect3DSurface9_UnlockRect(src_surface);
}
diff --git a/dlls/d3dx9_36/tests/volume.c b/dlls/d3dx9_36/tests/volume.c
index a4c9431..f49a634 100644
--- a/dlls/d3dx9_36/tests/volume.c
+++ b/dlls/d3dx9_36/tests/volume.c
@@ -58,7 +58,7 @@ static inline void set_box(D3DBOX *box, UINT left, UINT top, UINT right, UINT bo
static void test_D3DXLoadVolumeFromMemory(IDirect3DDevice9 *device)
{
- int i;
+ int i, x, y, z;
HRESULT hr;
D3DBOX src_box, dst_box;
D3DLOCKED_BOX locked_box;
@@ -110,6 +110,21 @@ static void test_D3DXLoadVolumeFromMemory(IDirect3DDevice9 *device)
for (i = 0; i < 16; i++) check_pixel_4bpp(&locked_box, i % 4, i / 4, 0, pixels[i]);
IDirect3DVolume9_UnlockBox(volume);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, NULL, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels), NULL, &src_box, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DVolume9_LockBox(volume, &locked_box, NULL, D3DLOCK_READONLY);
+ for (i = 0; i < 16; i++) check_pixel_4bpp(&locked_box, i % 4, i / 4, 0, pixels[i]);
+ for (z = 0; z < 4; z++)
+ {
+ for (y = 0; y < 256; y++)
+ {
+ for (x = 0; x < 256; x++)
+ if (z != 0 || y >= 4 || x >= 4) check_pixel_4bpp(&locked_box, x, y, z, 0);
+ }
+ }
+ IDirect3DVolume9_UnlockBox(volume);
+
set_box(&src_box, 0, 0, 2, 2, 1, 2);
set_box(&dst_box, 0, 0, 2, 2, 0, 1);
hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 8, 16, NULL, &src_box, D3DX_DEFAULT, 0);
diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c
index 6164cc3..90dbd29 100644
--- a/dlls/d3dx9_36/volume.c
+++ b/dlls/d3dx9_36/volume.c
@@ -194,8 +194,43 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
}
else
{
- FIXME("Stretching or format conversion not implemented\n");
- return E_NOTIMPL;
+ const BYTE *src_addr;
+ SIZE src_size, dst_size;
+
+ if (src_format_desc->bytes_per_pixel > 4 || dst_format_desc->bytes_per_pixel > 4
+ || src_format_desc->block_height != 1 || src_format_desc->block_width != 1
+ || dst_format_desc->block_height != 1 || dst_format_desc->block_width != 1)
+ {
+ FIXME("Pixel format conversion not implemented %#x -> %#x\n",
+ src_format_desc->format, dst_format_desc->format);
+ return E_NOTIMPL;
+ }
+
+ src_size.cx = src_width;
+ src_size.cy = src_height;
+ dst_size.cx = dst_width;
+ dst_size.cy = dst_height;
+
+ src_addr = src_memory;
+ src_addr += src_box->Front * src_slice_pitch;
+ src_addr += src_box->Top * src_row_pitch;
+ src_addr += src_box->Left * src_format_desc->bytes_per_pixel;
+
+ hr = IDirect3DVolume9_LockBox(dst_volume, &locked_box, dst_box, 0);
+ if (FAILED(hr)) return hr;
+
+ if ((filter & 0xf) == D3DX_FILTER_NONE)
+ {
+ copy_simple_data(src_memory, src_row_pitch, src_slice_pitch, src_size, src_depth, src_format_desc,
+ locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, dst_size, dst_depth, dst_format_desc, color_key);
+ }
+ else
+ {
+ FIXME("Filtering for volume textures not implemented\n");
+ return E_NOTIMPL;
+ }
+
+ IDirect3DVolume9_UnlockBox(dst_volume);
}
return D3D_OK;
--
1.7.8.6
More information about the wine-patches
mailing list