Stefan Dösinger : wined3d: Fix R32F and R16F.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Aug 17 06:30:38 CDT 2007
Module: wine
Branch: master
Commit: 86b991c8515c9da190fdbf95ed0c24685b4b6083
URL: http://source.winehq.org/git/wine.git/?a=commit;h=86b991c8515c9da190fdbf95ed0c24685b4b6083
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Sun Aug 12 16:24:29 2007 +0200
wined3d: Fix R32F and R16F.
---
dlls/d3d9/tests/visual.c | 69 ++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/surface.c | 63 ++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 4 ++-
3 files changed, 135 insertions(+), 1 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index cc13413..6807fc8 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -1564,6 +1564,74 @@ static void release_buffer_test(IDirect3DDevice9 *device)
IDirect3DVertexBuffer9_Release(vb);
}
+static void float_texture_test(IDirect3DDevice9 *device)
+{
+ IDirect3D9 *d3d = NULL;
+ HRESULT hr;
+ IDirect3DTexture9 *texture = NULL;
+ D3DLOCKED_RECT lr;
+ float *data;
+ DWORD color;
+ float quad[] = {
+ -1.0, -1.0, 0.1, 0.0, 0.0,
+ -1.0, 1.0, 0.1, 0.0, 1.0,
+ 1.0, -1.0, 0.1, 1.0, 0.0,
+ 1.0, 1.0, 0.1, 1.0, 1.0,
+ };
+
+ memset(&lr, 0, sizeof(lr));
+ IDirect3DDevice9_GetDirect3D(device, &d3d);
+ if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
+ D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
+ skip("D3DFMT_R32F textures not supported\n");
+ goto out;
+ }
+
+ hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
+ D3DPOOL_MANAGED, &texture, NULL);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
+ if(!texture) {
+ skip("Failed to create R32F texture\n");
+ goto out;
+ }
+
+ hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
+ ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
+ data = lr.pBits;
+ *data = 0.0;
+ hr = IDirect3DTexture9_UnlockRect(texture, 0);
+ ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
+
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
+ if(SUCCEEDED(hr))
+ {
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
+
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
+ }
+ hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
+
+ color = getPixelColor(device, 240, 320);
+ ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
+
+out:
+ if(texture) IDirect3DTexture9_Release(texture);
+ IDirect3D9_Release(d3d);
+}
+
START_TEST(visual)
{
IDirect3DDevice9 *device_ptr;
@@ -1639,6 +1707,7 @@ START_TEST(visual)
}
offscreen_test(device_ptr);
release_buffer_test(device_ptr);
+ float_texture_test(device_ptr);
if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
{
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 5ba1dec..58b4ed6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1607,6 +1607,30 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*target_bpp = 2;
break;
+ case WINED3DFMT_R32F:
+ /* Can be loaded in theory with fmt=GL_RED, type=GL_FLOAT, but this fails. The reason
+ * is that D3D expects the undefined green, blue and alpha channels to return 1.0
+ * when sampling, but OpenGL sets green and blue to 0.0 instead. Thus we have to inject
+ * 1.0 instead.
+ *
+ * The alpha channel defaults to 1.0 in opengl, so nothing has to be done about it.
+ */
+ *convert = CONVERT_R32F;
+ *format = GL_RGB;
+ *internal = GL_RGB32F_ARB;
+ *type = GL_FLOAT;
+ *target_bpp = 12;
+ break;
+
+ case WINED3DFMT_R16F:
+ /* Simmilar to R32F */
+ *convert = CONVERT_R16F;
+ *format = GL_RGB;
+ *internal = GL_RGB16F_ARB;
+ *type = GL_HALF_FLOAT_ARB;
+ *target_bpp = 6;
+ break;
+
default:
break;
}
@@ -1810,6 +1834,45 @@ HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, UINT pitch, UINT width, UIN
}
break;
}
+
+ case CONVERT_R32F:
+ {
+ unsigned int x, y;
+ float *Source;
+ float *Dest;
+ for(y = 0; y < height; y++) {
+ Source = (float *) (src + y * pitch);
+ Dest = (float *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ ) {
+ float color = (*Source++);
+ Dest[0] = color;
+ Dest[1] = 1.0;
+ Dest[2] = 1.0;
+ Dest += 3;
+ }
+ }
+ break;
+ }
+
+ case CONVERT_R16F:
+ {
+ unsigned int x, y;
+ WORD *Source;
+ WORD *Dest;
+ WORD one = 0x3c00;
+ for(y = 0; y < height; y++) {
+ Source = (WORD *) (src + y * pitch);
+ Dest = (WORD *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ ) {
+ WORD color = (*Source++);
+ Dest[0] = color;
+ Dest[1] = one;
+ Dest[2] = one;
+ Dest += 3;
+ }
+ }
+ break;
+ }
default:
ERR("Unsupported conversation type %d\n", convert);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3110ce2..29bd24d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1233,7 +1233,9 @@ typedef enum {
CONVERT_X8L8V8U8,
CONVERT_Q8W8V8U8,
CONVERT_V16U16,
- CONVERT_A4L4
+ CONVERT_A4L4,
+ CONVERT_R32F,
+ CONVERT_R16F
} CONVERT_TYPES;
HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);
More information about the wine-cvs
mailing list