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.
This commit is contained in:
parent
eafc00e173
commit
edf1c50b54
@ -2820,11 +2820,6 @@ static void maxmip_test(IDirect3DDevice9 *device)
|
|||||||
hr = IDirect3DDevice9_EndScene(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);
|
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||||
ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
|
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)
|
/* 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);
|
color = getPixelColor(device, 480, 360);
|
||||||
ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
|
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);
|
hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
|
||||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
|
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);
|
hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
|
||||||
ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
|
ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
|
||||||
IDirect3DTexture9_Release(texture);
|
IDirect3DTexture9_Release(texture);
|
||||||
|
@ -92,11 +92,10 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
|
|||||||
This->baseTexture.srgbDirty = TRUE;
|
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)
|
DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
|
||||||
{
|
{
|
||||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||||
|
DWORD old = This->baseTexture.LOD;
|
||||||
|
|
||||||
if (This->resource.pool != WINED3DPOOL_MANAGED) {
|
if (This->resource.pool != WINED3DPOOL_MANAGED) {
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
@ -104,11 +103,20 @@ DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
|
|||||||
|
|
||||||
if(LODNew >= This->baseTexture.levels)
|
if(LODNew >= This->baseTexture.levels)
|
||||||
LODNew = This->baseTexture.levels - 1;
|
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)
|
DWORD basetexture_get_lod(IWineD3DBaseTexture *iface)
|
||||||
@ -426,9 +434,12 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
|
|||||||
|
|
||||||
if(!cond_np2) {
|
if(!cond_np2) {
|
||||||
if(states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
|
if(states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
|
||||||
glValue = 0;
|
glValue = This->baseTexture.LOD;
|
||||||
} else if(states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
|
} else if(states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
|
||||||
glValue = This->baseTexture.levels - 1;
|
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 {
|
} else {
|
||||||
glValue = states[WINED3DTEXSTA_MAXMIPLEVEL];
|
glValue = states[WINED3DTEXSTA_MAXMIPLEVEL];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user