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