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() ...@@ -344,10 +344,7 @@ void Renderer9::initializeDevice()
const gl::Caps &rendererCaps = getRendererCaps(); const gl::Caps &rendererCaps = getRendererCaps();
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurVertexTextures.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexTextures.resize(rendererCaps.maxVertexTextureImageUnits);
...@@ -759,46 +756,52 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture) ...@@ -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) 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; CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index]
std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; : 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; return error;
int d3dSampler = index + d3dSamplerOffset; }
// Make sure to add the level offset for our tiny compressed texture workaround // Storage should exist, texture should be complete
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture); ASSERT(storage);
TextureStorage *storage = nullptr; DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel();
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(); 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_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy));
D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; 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_MINFILTER, d3dMinFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast<DWORD>(lodBias));
if (getRendererExtensions().textureFilterAnisotropic) if (getRendererExtensions().textureFilterAnisotropic)
{ {
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
} }
} }
forceSetSamplers[index] = false; appliedSampler.forceSet = false;
appliedSamplers[index] = samplerState; appliedSampler.samplerState = samplerState;
appliedSampler.baseLevel = baseLevel;
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
...@@ -2229,17 +2232,17 @@ void Renderer9::markAllStateDirty() ...@@ -2229,17 +2232,17 @@ void Renderer9::markAllStateDirty()
mForceSetViewport = true; mForceSetViewport = true;
mForceSetBlendState = true; mForceSetBlendState = true;
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextures.size()); ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++) for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
{ {
mForceSetVertexSamplerStates[i] = true; mCurVertexSamplerStates[i].forceSet = true;
mCurVertexTextures[i] = DirtyPointer; mCurVertexTextures[i] = DirtyPointer;
} }
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextures.size()); ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size());
for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++) for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++)
{ {
mForceSetPixelSamplerStates[i] = true; mCurPixelSamplerStates[i].forceSet = true;
mCurPixelTextures[i] = DirtyPointer; mCurPixelTextures[i] = DirtyPointer;
} }
...@@ -2968,4 +2971,11 @@ gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStar ...@@ -2968,4 +2971,11 @@ gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStar
return gl::Error(GL_NO_ERROR); 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 ...@@ -340,11 +340,16 @@ class Renderer9 : public RendererD3D
GLuint mCurSampleMask; GLuint mCurSampleMask;
// Currently applied sampler states // Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates; struct CurSamplerState
std::vector<gl::SamplerState> mCurVertexSamplerStates; {
CurSamplerState();
std::vector<bool> mForceSetPixelSamplerStates; bool forceSet;
std::vector<gl::SamplerState> mCurPixelSamplerStates; size_t baseLevel;
gl::SamplerState samplerState;
};
std::vector<CurSamplerState> mCurVertexSamplerStates;
std::vector<CurSamplerState> mCurPixelSamplerStates;
// Currently applied textures // Currently applied textures
std::vector<uintptr_t> mCurVertexTextures; std::vector<uintptr_t> mCurVertexTextures;
......
...@@ -208,7 +208,8 @@ D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) ...@@ -208,7 +208,8 @@ D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
return d3dMagFilter; 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) switch (minFilter)
{ {
...@@ -242,6 +243,20 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT ...@@ -242,6 +243,20 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT
UNREACHABLE(); 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) if (maxAnisotropy > 1.0f)
{ {
*d3dMinFilter = D3DTEXF_ANISOTROPIC; *d3dMinFilter = D3DTEXF_ANISOTROPIC;
......
...@@ -37,7 +37,8 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); ...@@ -37,7 +37,8 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace); D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); 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); 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