Stefan Dösinger : wined3d: Handle per-texture max LOD level.

Alexandre Julliard julliard at winehq.org
Mon Aug 31 10:47:04 CDT 2009


Module: wine
Branch: master
Commit: edf1c50b5419459f6fce604080328ca783b92ffb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=edf1c50b5419459f6fce604080328ca783b92ffb

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sun Aug 30 22:02:17 2009 +0200

wined3d: Handle per-texture max LOD level.

GL_TEXTURE_BASE_LEVEL matches the basetexture::SetLOD functionality.
D3DSAMP_MAXMIPLEVEL essentially does the same as SetLOD. The test included in
this patch shows that the smallest mipmap level is used.

---

 dlls/d3d9/tests/visual.c   |   66 ++++++++++++++++++++++++++++++++++++++++---
 dlls/wined3d/basetexture.c |   23 +++++++++++----
 2 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 48fea06..0fb7899 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -2820,11 +2820,6 @@ static void maxmip_test(IDirect3DDevice9 *device)
         hr = IDirect3DDevice9_EndScene(device);
     }
 
-    hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
-    ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
-    hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
-    ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
-
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
@@ -2839,8 +2834,69 @@ static void maxmip_test(IDirect3DDevice9 *device)
     color = getPixelColor(device, 480, 360);
     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
 
+    hr = IDirect3DDevice9_BeginScene(device);
+    if(SUCCEEDED(hr))
+    {
+        DWORD ret;
+
+        /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        ret = IDirect3DTexture9_SetLOD(texture, 1);
+        ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
+        hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
+        ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+
+        /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        ret = IDirect3DTexture9_SetLOD(texture, 2);
+        ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
+        hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
+        ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+
+        /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        ret = IDirect3DTexture9_SetLOD(texture, 1);
+        ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
+        hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
+        ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+
+        /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
+        ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
+        ret = IDirect3DTexture9_SetLOD(texture, 1);
+        ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
+        hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
+        ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+        hr = IDirect3DDevice9_EndScene(device);
+    }
+
+    hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+    ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
+    /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
+     * samples from the highest level in the texture(level 2)
+     */
+    color = getPixelColor(device, 160, 360);
+    ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
+    color = getPixelColor(device, 160, 120);
+    ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
+    color = getPixelColor(device, 480, 120);
+    ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
+    color = getPixelColor(device, 480, 360);
+    ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
+
     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
+    hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+    ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
     IDirect3DTexture9_Release(texture);
diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c
index a36d993..2bfbcc7 100644
--- a/dlls/wined3d/basetexture.c
+++ b/dlls/wined3d/basetexture.c
@@ -92,11 +92,10 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
     This->baseTexture.srgbDirty = TRUE;
 }
 
-/* There is no OpenGL equivalent of setLOD, getLOD. All they do anyway is prioritize texture loading
- * so just pretend that they work unless something really needs a failure. */
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+    DWORD old = This->baseTexture.LOD;
 
     if (This->resource.pool != WINED3DPOOL_MANAGED) {
         return  WINED3DERR_INVALIDCALL;
@@ -104,11 +103,20 @@ DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
 
     if(LODNew >= This->baseTexture.levels)
         LODNew = This->baseTexture.levels - 1;
-     This->baseTexture.LOD = LODNew;
 
-    TRACE("(%p) : set bogus LOD to %d\n", This, This->baseTexture.LOD);
+    if(This->baseTexture.LOD != LODNew) {
+        This->baseTexture.LOD = LODNew;
 
-    return This->baseTexture.LOD;
+        This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+        This->baseTexture.srgbstates[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+        if(This->baseTexture.bindCount) {
+            IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(This->baseTexture.sampler));
+        }
+    }
+
+    TRACE("(%p) : set LOD to %d\n", This, This->baseTexture.LOD);
+
+    return old;
 }
 
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface)
@@ -426,9 +434,12 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
 
         if(!cond_np2) {
             if(states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
-                glValue = 0;
+                glValue = This->baseTexture.LOD;
             } else if(states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
                 glValue = This->baseTexture.levels - 1;
+            } else if(states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) {
+                /* baseTexture.LOD is already clamped in the setter */
+                glValue = This->baseTexture.LOD;
             } else {
                 glValue = states[WINED3DTEXSTA_MAXMIPLEVEL];
             }




More information about the wine-cvs mailing list