Commit 35fff1ca by Geoff Lang

Handle non-zero base level with mipmapping disabled in D3D9.

BUG=angleproject:970 Change-Id: I33120ec8121dc1265360fbbe61103e03e593af3f Reviewed-on: https://chromium-review.googlesource.com/286550Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 26a6ea08
......@@ -344,10 +344,7 @@ void Renderer9::initializeDevice()
const gl::Caps &rendererCaps = getRendererCaps();
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurVertexTextures.resize(rendererCaps.maxVertexTextureImageUnits);
......@@ -759,46 +756,52 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture)
gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState)
{
std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index]
: mCurVertexSamplerStates[index];
// Make sure to add the level offset for our tiny compressed texture workaround
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0)
TextureStorage *storage = nullptr;
gl::Error error = textureD3D->getNativeTexture(&storage);
if (error.isError())
{
int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
int d3dSampler = index + d3dSamplerOffset;
return error;
}
// Make sure to add the level offset for our tiny compressed texture workaround
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
// Storage should exist, texture should be complete
ASSERT(storage);
TextureStorage *storage = nullptr;
gl::Error error = textureD3D->getNativeTexture(&storage);
if (error.isError())
{
return error;
}
// Storage should exist, texture should be complete
ASSERT(storage);
DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel();
DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel();
if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel ||
memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0)
{
int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
int d3dSampler = index + d3dSamplerOffset;
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy));
D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy);
float lodBias;
gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, &lodBias,
samplerState.maxAnisotropy, baseLevel);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast<DWORD>(lodBias));
if (getRendererExtensions().textureFilterAnisotropic)
{
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
}
}
forceSetSamplers[index] = false;
appliedSamplers[index] = samplerState;
appliedSampler.forceSet = false;
appliedSampler.samplerState = samplerState;
appliedSampler.baseLevel = baseLevel;
return gl::Error(GL_NO_ERROR);
}
......@@ -2229,17 +2232,17 @@ void Renderer9::markAllStateDirty()
mForceSetViewport = true;
mForceSetBlendState = true;
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextures.size());
for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++)
ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
{
mForceSetVertexSamplerStates[i] = true;
mCurVertexSamplerStates[i].forceSet = true;
mCurVertexTextures[i] = DirtyPointer;
}
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextures.size());
for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++)
ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size());
for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++)
{
mForceSetPixelSamplerStates[i] = true;
mCurPixelSamplerStates[i].forceSet = true;
mCurPixelTextures[i] = DirtyPointer;
}
......@@ -2968,4 +2971,11 @@ gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStar
return gl::Error(GL_NO_ERROR);
}
Renderer9::CurSamplerState::CurSamplerState()
: forceSet(true),
baseLevel(std::numeric_limits<size_t>::max()),
samplerState()
{
}
}
......@@ -340,11 +340,16 @@ class Renderer9 : public RendererD3D
GLuint mCurSampleMask;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> mCurVertexSamplerStates;
struct CurSamplerState
{
CurSamplerState();
std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates;
bool forceSet;
size_t baseLevel;
gl::SamplerState samplerState;
};
std::vector<CurSamplerState> mCurVertexSamplerStates;
std::vector<CurSamplerState> mCurPixelSamplerStates;
// Currently applied textures
std::vector<uintptr_t> mCurVertexTextures;
......
......@@ -208,7 +208,8 @@ D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
return d3dMagFilter;
}
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter,
float *d3dLodBias, float maxAnisotropy, size_t baseLevel)
{
switch (minFilter)
{
......@@ -242,6 +243,20 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT
UNREACHABLE();
}
// Disabling mipmapping will always sample from level 0 of the texture. It is possible to work
// around this by modifying D3DSAMP_MAXMIPLEVEL to force a specific mip level to become the
// lowest sampled mip level and using a large negative value for D3DSAMP_MIPMAPLODBIAS to
// ensure that only the base mip level is sampled.
if (baseLevel > 0 && *d3dMipFilter == D3DTEXF_NONE)
{
*d3dMipFilter = D3DTEXF_POINT;
*d3dLodBias = -static_cast<float>(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
}
else
{
*d3dLodBias = 0.0f;
}
if (maxAnisotropy > 1.0f)
{
*d3dMinFilter = D3DTEXF_ANISOTROPIC;
......
......@@ -37,7 +37,8 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter,
float *d3dLodBias, float maxAnisotropy, size_t baseLevel);
D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment