Module: wine Branch: master Commit: edf1c50b5419459f6fce604080328ca783b92ffb URL: http://source.winehq.org/git/wine.git/?a=commit;h=edf1c50b5419459f6fce604080...
Author: Stefan Dösinger stefan@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]; }