Commit 77ae8d57 by Olli Etuaho Committed by Commit Bot

Share TextureState structure with TextureImpl

This refactoring patch removes the need to pass texture state to methods of TextureImpl in some cases. It also adds target value to TextureState, and moves TextureState definition to Texture.h. The effective base level can now also be queried from TextureState, which reduces the need to pass it around. Two different code paths that dealt with the TextureStorage11 SRV cache are combined into one. Besides refactoring, this patch fixes applying mTopLevel twice when determining the amount of mip levels TextureStorage11. BUG=angleproject:596 TEST=angle_end2end_tests, angle_unittests Change-Id: I1add3d9ad847bec56774e394125156cf9cb0fc2a Reviewed-on: https://chromium-review.googlesource.com/342940Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent bc7b7ab0
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
using namespace rx; using namespace rx;
using namespace gl; using namespace gl;
using ::testing::_;
namespace namespace
{ {
...@@ -37,7 +39,7 @@ class ResourceManagerTest : public testing::Test ...@@ -37,7 +39,7 @@ class ResourceManagerTest : public testing::Test
TEST_F(ResourceManagerTest, ReallocateBoundTexture) TEST_F(ResourceManagerTest, ReallocateBoundTexture)
{ {
EXPECT_CALL(mMockFactory, createTexture(GL_TEXTURE_2D)).Times(1).RetiresOnSaturation(); EXPECT_CALL(mMockFactory, createTexture(_)).Times(1).RetiresOnSaturation();
mResourceManager->checkTextureAllocation(1, GL_TEXTURE_2D); mResourceManager->checkTextureAllocation(1, GL_TEXTURE_2D);
GLuint newTexture = mResourceManager->createTexture(); GLuint newTexture = mResourceManager->createTexture();
......
...@@ -22,6 +22,22 @@ ...@@ -22,6 +22,22 @@
namespace gl namespace gl
{ {
namespace
{
bool IsPointSampled(const gl::SamplerState &samplerState)
{
return (samplerState.magFilter == GL_NEAREST &&
(samplerState.minFilter == GL_NEAREST ||
samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
}
size_t GetImageDescIndex(GLenum target, size_t level)
{
return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target))
: level;
}
} // namespace
bool IsMipmapFiltered(const gl::SamplerState &samplerState) bool IsMipmapFiltered(const gl::SamplerState &samplerState)
{ {
switch (samplerState.minFilter) switch (samplerState.minFilter)
...@@ -39,23 +55,45 @@ bool IsMipmapFiltered(const gl::SamplerState &samplerState) ...@@ -39,23 +55,45 @@ bool IsMipmapFiltered(const gl::SamplerState &samplerState)
} }
} }
bool IsPointSampled(const gl::SamplerState &samplerState) TextureState::TextureState(GLenum target)
: target(target),
swizzleRed(GL_RED),
swizzleGreen(GL_GREEN),
swizzleBlue(GL_BLUE),
swizzleAlpha(GL_ALPHA),
samplerState(),
baseLevel(0),
maxLevel(1000),
immutableFormat(false),
immutableLevels(0),
usage(GL_NONE)
{ {
return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
} }
static size_t GetImageDescIndex(GLenum target, size_t level) bool TextureState::swizzleRequired() const
{ {
return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target)) : level; return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || swizzleBlue != GL_BLUE ||
swizzleAlpha != GL_ALPHA;
}
GLuint TextureState::getEffectiveBaseLevel() const
{
if (immutableFormat)
{
return std::min(baseLevel, immutableLevels - 1);
}
// Some classes use the effective base level to index arrays with level data. By clamping the
// effective base level to max levels these arrays need just one extra item to store properties
// that should be returned for all out-of-range base level values, instead of needing special
// handling for out-of-range base levels.
return std::min(baseLevel, static_cast<GLuint>(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
} }
Texture::Texture(rx::GLImplFactory *factory, GLuint id, GLenum target) Texture::Texture(rx::GLImplFactory *factory, GLuint id, GLenum target)
: egl::ImageSibling(id), : egl::ImageSibling(id),
mTexture(factory->createTexture(target)), mState(target),
mTexture(factory->createTexture(mState)),
mLabel(), mLabel(),
mTextureState(),
mEffectiveBaseLevel(0),
mTarget(target),
mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) *
(target == GL_TEXTURE_CUBE_MAP ? 6 : 1)), (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)),
mCompletenessCache(), mCompletenessCache(),
...@@ -91,259 +129,241 @@ const std::string &Texture::getLabel() const ...@@ -91,259 +129,241 @@ const std::string &Texture::getLabel() const
GLenum Texture::getTarget() const GLenum Texture::getTarget() const
{ {
return mTarget; return mState.target;
} }
void Texture::setSwizzleRed(GLenum swizzleRed) void Texture::setSwizzleRed(GLenum swizzleRed)
{ {
mTextureState.swizzleRed = swizzleRed; mState.swizzleRed = swizzleRed;
} }
GLenum Texture::getSwizzleRed() const GLenum Texture::getSwizzleRed() const
{ {
return mTextureState.swizzleRed; return mState.swizzleRed;
} }
void Texture::setSwizzleGreen(GLenum swizzleGreen) void Texture::setSwizzleGreen(GLenum swizzleGreen)
{ {
mTextureState.swizzleGreen = swizzleGreen; mState.swizzleGreen = swizzleGreen;
} }
GLenum Texture::getSwizzleGreen() const GLenum Texture::getSwizzleGreen() const
{ {
return mTextureState.swizzleGreen; return mState.swizzleGreen;
} }
void Texture::setSwizzleBlue(GLenum swizzleBlue) void Texture::setSwizzleBlue(GLenum swizzleBlue)
{ {
mTextureState.swizzleBlue = swizzleBlue; mState.swizzleBlue = swizzleBlue;
} }
GLenum Texture::getSwizzleBlue() const GLenum Texture::getSwizzleBlue() const
{ {
return mTextureState.swizzleBlue; return mState.swizzleBlue;
} }
void Texture::setSwizzleAlpha(GLenum swizzleAlpha) void Texture::setSwizzleAlpha(GLenum swizzleAlpha)
{ {
mTextureState.swizzleAlpha = swizzleAlpha; mState.swizzleAlpha = swizzleAlpha;
} }
GLenum Texture::getSwizzleAlpha() const GLenum Texture::getSwizzleAlpha() const
{ {
return mTextureState.swizzleAlpha; return mState.swizzleAlpha;
} }
void Texture::setMinFilter(GLenum minFilter) void Texture::setMinFilter(GLenum minFilter)
{ {
mTextureState.samplerState.minFilter = minFilter; mState.samplerState.minFilter = minFilter;
} }
GLenum Texture::getMinFilter() const GLenum Texture::getMinFilter() const
{ {
return mTextureState.samplerState.minFilter; return mState.samplerState.minFilter;
} }
void Texture::setMagFilter(GLenum magFilter) void Texture::setMagFilter(GLenum magFilter)
{ {
mTextureState.samplerState.magFilter = magFilter; mState.samplerState.magFilter = magFilter;
} }
GLenum Texture::getMagFilter() const GLenum Texture::getMagFilter() const
{ {
return mTextureState.samplerState.magFilter; return mState.samplerState.magFilter;
} }
void Texture::setWrapS(GLenum wrapS) void Texture::setWrapS(GLenum wrapS)
{ {
mTextureState.samplerState.wrapS = wrapS; mState.samplerState.wrapS = wrapS;
} }
GLenum Texture::getWrapS() const GLenum Texture::getWrapS() const
{ {
return mTextureState.samplerState.wrapS; return mState.samplerState.wrapS;
} }
void Texture::setWrapT(GLenum wrapT) void Texture::setWrapT(GLenum wrapT)
{ {
mTextureState.samplerState.wrapT = wrapT; mState.samplerState.wrapT = wrapT;
} }
GLenum Texture::getWrapT() const GLenum Texture::getWrapT() const
{ {
return mTextureState.samplerState.wrapT; return mState.samplerState.wrapT;
} }
void Texture::setWrapR(GLenum wrapR) void Texture::setWrapR(GLenum wrapR)
{ {
mTextureState.samplerState.wrapR = wrapR; mState.samplerState.wrapR = wrapR;
} }
GLenum Texture::getWrapR() const GLenum Texture::getWrapR() const
{ {
return mTextureState.samplerState.wrapR; return mState.samplerState.wrapR;
} }
void Texture::setMaxAnisotropy(float maxAnisotropy) void Texture::setMaxAnisotropy(float maxAnisotropy)
{ {
mTextureState.samplerState.maxAnisotropy = maxAnisotropy; mState.samplerState.maxAnisotropy = maxAnisotropy;
} }
float Texture::getMaxAnisotropy() const float Texture::getMaxAnisotropy() const
{ {
return mTextureState.samplerState.maxAnisotropy; return mState.samplerState.maxAnisotropy;
} }
void Texture::setMinLod(GLfloat minLod) void Texture::setMinLod(GLfloat minLod)
{ {
mTextureState.samplerState.minLod = minLod; mState.samplerState.minLod = minLod;
} }
GLfloat Texture::getMinLod() const GLfloat Texture::getMinLod() const
{ {
return mTextureState.samplerState.minLod; return mState.samplerState.minLod;
} }
void Texture::setMaxLod(GLfloat maxLod) void Texture::setMaxLod(GLfloat maxLod)
{ {
mTextureState.samplerState.maxLod = maxLod; mState.samplerState.maxLod = maxLod;
} }
GLfloat Texture::getMaxLod() const GLfloat Texture::getMaxLod() const
{ {
return mTextureState.samplerState.maxLod; return mState.samplerState.maxLod;
} }
void Texture::setCompareMode(GLenum compareMode) void Texture::setCompareMode(GLenum compareMode)
{ {
mTextureState.samplerState.compareMode = compareMode; mState.samplerState.compareMode = compareMode;
} }
GLenum Texture::getCompareMode() const GLenum Texture::getCompareMode() const
{ {
return mTextureState.samplerState.compareMode; return mState.samplerState.compareMode;
} }
void Texture::setCompareFunc(GLenum compareFunc) void Texture::setCompareFunc(GLenum compareFunc)
{ {
mTextureState.samplerState.compareFunc = compareFunc; mState.samplerState.compareFunc = compareFunc;
} }
GLenum Texture::getCompareFunc() const GLenum Texture::getCompareFunc() const
{ {
return mTextureState.samplerState.compareFunc; return mState.samplerState.compareFunc;
} }
const SamplerState &Texture::getSamplerState() const const SamplerState &Texture::getSamplerState() const
{ {
return mTextureState.samplerState; return mState.samplerState;
} }
void Texture::setBaseLevel(GLuint baseLevel) void Texture::setBaseLevel(GLuint baseLevel)
{ {
if (mTextureState.baseLevel != baseLevel) if (mState.baseLevel != baseLevel)
{ {
mTextureState.baseLevel = baseLevel; mState.baseLevel = baseLevel;
mCompletenessCache.cacheValid = false; mCompletenessCache.cacheValid = false;
updateEffectiveBaseLevel(); mTexture->setBaseLevel(mState.getEffectiveBaseLevel());
mTexture->setBaseLevel(mEffectiveBaseLevel);
}
}
void Texture::updateEffectiveBaseLevel()
{
mEffectiveBaseLevel = mTextureState.baseLevel;
if (mTextureState.immutableFormat && mEffectiveBaseLevel > mTextureState.immutableLevels - 1)
{
mEffectiveBaseLevel = mTextureState.immutableLevels - 1;
}
// Ensure that this class doesn't access out-of-range memory when querying effective base level
// properties.
if (mEffectiveBaseLevel > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS is still an out-of-range level, but the arrays
// for level data have an extra dummy level for querying out-of-range base level properties.
mEffectiveBaseLevel = gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS;
} }
} }
GLuint Texture::getBaseLevel() const GLuint Texture::getBaseLevel() const
{ {
return mTextureState.baseLevel; return mState.baseLevel;
}
GLuint Texture::getEffectiveBaseLevel() const
{
return mEffectiveBaseLevel;
} }
void Texture::setMaxLevel(GLuint maxLevel) void Texture::setMaxLevel(GLuint maxLevel)
{ {
if (mTextureState.maxLevel != maxLevel) if (mState.maxLevel != maxLevel)
{ {
mTextureState.maxLevel = maxLevel; mState.maxLevel = maxLevel;
mCompletenessCache.cacheValid = false; mCompletenessCache.cacheValid = false;
} }
} }
GLuint Texture::getMaxLevel() const GLuint Texture::getMaxLevel() const
{ {
return mTextureState.maxLevel; return mState.maxLevel;
} }
bool Texture::getImmutableFormat() const bool Texture::getImmutableFormat() const
{ {
return mTextureState.immutableFormat; return mState.immutableFormat;
} }
GLuint Texture::getImmutableLevels() const GLuint Texture::getImmutableLevels() const
{ {
return mTextureState.immutableLevels; return mState.immutableLevels;
} }
void Texture::setUsage(GLenum usage) void Texture::setUsage(GLenum usage)
{ {
mTextureState.usage = usage; mState.usage = usage;
getImplementation()->setUsage(usage); getImplementation()->setUsage(usage);
} }
GLenum Texture::getUsage() const GLenum Texture::getUsage() const
{ {
return mTextureState.usage; return mState.usage;
} }
const TextureState &Texture::getTextureState() const const TextureState &Texture::getTextureState() const
{ {
return mTextureState; return mState;
} }
size_t Texture::getWidth(GLenum target, size_t level) const size_t Texture::getWidth(GLenum target, size_t level) const
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return getImageDesc(target, level).size.width; return getImageDesc(target, level).size.width;
} }
size_t Texture::getHeight(GLenum target, size_t level) const size_t Texture::getHeight(GLenum target, size_t level) const
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return getImageDesc(target, level).size.height; return getImageDesc(target, level).size.height;
} }
size_t Texture::getDepth(GLenum target, size_t level) const size_t Texture::getDepth(GLenum target, size_t level) const
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return getImageDesc(target, level).size.depth; return getImageDesc(target, level).size.depth;
} }
GLenum Texture::getInternalFormat(GLenum target, size_t level) const GLenum Texture::getInternalFormat(GLenum target, size_t level) const
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return getImageDesc(target, level).internalFormat; return getImageDesc(target, level).internalFormat;
} }
bool Texture::isSamplerComplete(const SamplerState &samplerState, const ContextState &data) const bool Texture::isSamplerComplete(const SamplerState &samplerState, const ContextState &data) const
{ {
const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mEffectiveBaseLevel); const ImageDesc &baseImageDesc =
getImageDesc(getBaseImageTarget(), mState.getEffectiveBaseLevel());
const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat); const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat);
if (!mCompletenessCache.cacheValid || if (!mCompletenessCache.cacheValid ||
mCompletenessCache.samplerState != samplerState || mCompletenessCache.samplerState != samplerState ||
...@@ -369,7 +389,7 @@ bool Texture::isMipmapComplete() const ...@@ -369,7 +389,7 @@ bool Texture::isMipmapComplete() const
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool Texture::isCubeComplete() const bool Texture::isCubeComplete() const
{ {
ASSERT(mTarget == GL_TEXTURE_CUBE_MAP); ASSERT(mState.target == GL_TEXTURE_CUBE_MAP);
const ImageDesc &baseImageDesc = getImageDesc(FirstCubeMapTextureTarget, 0); const ImageDesc &baseImageDesc = getImageDesc(FirstCubeMapTextureTarget, 0);
if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height) if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height)
...@@ -394,7 +414,7 @@ bool Texture::isCubeComplete() const ...@@ -394,7 +414,7 @@ bool Texture::isCubeComplete() const
size_t Texture::getMipCompleteLevels() const size_t Texture::getMipCompleteLevels() const
{ {
const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), 0); const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), 0);
if (mTarget == GL_TEXTURE_3D) if (mState.target == GL_TEXTURE_3D)
{ {
const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height),
baseImageDesc.size.depth); baseImageDesc.size.depth);
...@@ -425,7 +445,8 @@ Error Texture::setImage(const PixelUnpackState &unpackState, ...@@ -425,7 +445,8 @@ Error Texture::setImage(const PixelUnpackState &unpackState,
GLenum type, GLenum type,
const uint8_t *pixels) const uint8_t *pixels)
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal(); releaseTexImageInternal();
...@@ -451,7 +472,8 @@ Error Texture::setSubImage(const PixelUnpackState &unpackState, ...@@ -451,7 +472,8 @@ Error Texture::setSubImage(const PixelUnpackState &unpackState,
GLenum type, GLenum type,
const uint8_t *pixels) const uint8_t *pixels)
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mTexture->setSubImage(target, level, area, format, type, unpackState, pixels); return mTexture->setSubImage(target, level, area, format, type, unpackState, pixels);
} }
...@@ -463,7 +485,8 @@ Error Texture::setCompressedImage(const PixelUnpackState &unpackState, ...@@ -463,7 +485,8 @@ Error Texture::setCompressedImage(const PixelUnpackState &unpackState,
size_t imageSize, size_t imageSize,
const uint8_t *pixels) const uint8_t *pixels)
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal(); releaseTexImageInternal();
...@@ -489,7 +512,8 @@ Error Texture::setCompressedSubImage(const PixelUnpackState &unpackState, ...@@ -489,7 +512,8 @@ Error Texture::setCompressedSubImage(const PixelUnpackState &unpackState,
size_t imageSize, size_t imageSize,
const uint8_t *pixels) const uint8_t *pixels)
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mTexture->setCompressedSubImage(target, level, area, format, unpackState, imageSize, return mTexture->setCompressedSubImage(target, level, area, format, unpackState, imageSize,
pixels); pixels);
...@@ -498,7 +522,8 @@ Error Texture::setCompressedSubImage(const PixelUnpackState &unpackState, ...@@ -498,7 +522,8 @@ Error Texture::setCompressedSubImage(const PixelUnpackState &unpackState,
Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat, Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat,
const Framebuffer *source) const Framebuffer *source)
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal(); releaseTexImageInternal();
...@@ -519,14 +544,15 @@ Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceAre ...@@ -519,14 +544,15 @@ Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceAre
Error Texture::copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea, Error Texture::copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea,
const Framebuffer *source) const Framebuffer *source)
{ {
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); ASSERT(target == mState.target ||
(mState.target == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mTexture->copySubImage(target, level, destOffset, sourceArea, source); return mTexture->copySubImage(target, level, destOffset, sourceArea, source);
} }
Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size) Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size)
{ {
ASSERT(target == mTarget); ASSERT(target == mState.target);
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal(); releaseTexImageInternal();
...@@ -538,9 +564,8 @@ Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, c ...@@ -538,9 +564,8 @@ Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, c
return error; return error;
} }
mTextureState.immutableFormat = true; mState.immutableFormat = true;
mTextureState.immutableLevels = static_cast<GLuint>(levels); mState.immutableLevels = static_cast<GLuint>(levels);
updateEffectiveBaseLevel();
clearImageDescs(); clearImageDescs();
setImageDescChain(levels, size, internalFormat); setImageDescChain(levels, size, internalFormat);
...@@ -559,7 +584,7 @@ Error Texture::generateMipmaps() ...@@ -559,7 +584,7 @@ Error Texture::generateMipmaps()
orphanImages(); orphanImages();
} }
Error error = mTexture->generateMipmaps(mTextureState); Error error = mTexture->generateMipmaps();
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -578,11 +603,11 @@ void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInt ...@@ -578,11 +603,11 @@ void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInt
{ {
Extents levelSize( Extents levelSize(
std::max<int>(baseSize.width >> level, 1), std::max<int>(baseSize.height >> level, 1), std::max<int>(baseSize.width >> level, 1), std::max<int>(baseSize.height >> level, 1),
(mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth (mState.target == GL_TEXTURE_2D_ARRAY) ? baseSize.depth
: std::max<int>(baseSize.depth >> level, 1)); : std::max<int>(baseSize.depth >> level, 1));
ImageDesc levelInfo(levelSize, sizedInternalFormat); ImageDesc levelInfo(levelSize, sizedInternalFormat);
if (mTarget == GL_TEXTURE_CUBE_MAP) if (mState.target == GL_TEXTURE_CUBE_MAP)
{ {
for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
{ {
...@@ -591,7 +616,7 @@ void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInt ...@@ -591,7 +616,7 @@ void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInt
} }
else else
{ {
setImageDesc(mTarget, level, levelInfo); setImageDesc(mState.target, level, levelInfo);
} }
} }
} }
...@@ -649,10 +674,10 @@ void Texture::bindTexImageFromSurface(egl::Surface *surface) ...@@ -649,10 +674,10 @@ void Texture::bindTexImageFromSurface(egl::Surface *surface)
mBoundSurface = surface; mBoundSurface = surface;
// Set the image info to the size and format of the surface // Set the image info to the size and format of the surface
ASSERT(mTarget == GL_TEXTURE_2D); ASSERT(mState.target == GL_TEXTURE_2D);
Extents size(surface->getWidth(), surface->getHeight(), 1); Extents size(surface->getWidth(), surface->getHeight(), 1);
ImageDesc desc(size, surface->getConfig()->renderTargetFormat); ImageDesc desc(size, surface->getConfig()->renderTargetFormat);
setImageDesc(mTarget, 0, desc); setImageDesc(mState.target, 0, desc);
} }
void Texture::releaseTexImageFromSurface() void Texture::releaseTexImageFromSurface()
...@@ -662,8 +687,8 @@ void Texture::releaseTexImageFromSurface() ...@@ -662,8 +687,8 @@ void Texture::releaseTexImageFromSurface()
mTexture->releaseTexImage(); mTexture->releaseTexImage();
// Erase the image info for level 0 // Erase the image info for level 0
ASSERT(mTarget == GL_TEXTURE_2D); ASSERT(mState.target == GL_TEXTURE_2D);
clearImageDesc(mTarget, 0); clearImageDesc(mState.target, 0);
} }
void Texture::bindStream(egl::Stream *stream) void Texture::bindStream(egl::Stream *stream)
...@@ -675,7 +700,7 @@ void Texture::bindStream(egl::Stream *stream) ...@@ -675,7 +700,7 @@ void Texture::bindStream(egl::Stream *stream)
mBoundStream = stream; mBoundStream = stream;
ASSERT(mTarget == GL_TEXTURE_EXTERNAL_OES); ASSERT(mState.target == GL_TEXTURE_EXTERNAL_OES);
} }
void Texture::releaseStream() void Texture::releaseStream()
...@@ -687,19 +712,19 @@ void Texture::releaseStream() ...@@ -687,19 +712,19 @@ void Texture::releaseStream()
void Texture::acquireImageFromStream(const egl::Stream::GLTextureDescription &desc) void Texture::acquireImageFromStream(const egl::Stream::GLTextureDescription &desc)
{ {
ASSERT(mBoundStream != nullptr); ASSERT(mBoundStream != nullptr);
mTexture->setImageExternal(mTarget, mBoundStream, desc); mTexture->setImageExternal(mState.target, mBoundStream, desc);
Extents size(desc.width, desc.height, 1); Extents size(desc.width, desc.height, 1);
setImageDesc(mTarget, 0, ImageDesc(size, desc.internalFormat)); setImageDesc(mState.target, 0, ImageDesc(size, desc.internalFormat));
} }
void Texture::releaseImageFromStream() void Texture::releaseImageFromStream()
{ {
ASSERT(mBoundStream != nullptr); ASSERT(mBoundStream != nullptr);
mTexture->setImageExternal(mTarget, nullptr, egl::Stream::GLTextureDescription()); mTexture->setImageExternal(mState.target, nullptr, egl::Stream::GLTextureDescription());
// Set to incomplete // Set to incomplete
clearImageDesc(mTarget, 0); clearImageDesc(mState.target, 0);
} }
void Texture::releaseTexImageInternal() void Texture::releaseTexImageInternal()
...@@ -716,7 +741,7 @@ void Texture::releaseTexImageInternal() ...@@ -716,7 +741,7 @@ void Texture::releaseTexImageInternal()
Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget) Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget)
{ {
ASSERT(target == mTarget); ASSERT(target == mState.target);
ASSERT(target == GL_TEXTURE_2D); ASSERT(target == GL_TEXTURE_2D);
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
...@@ -744,27 +769,28 @@ Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget) ...@@ -744,27 +769,28 @@ Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget)
GLenum Texture::getBaseImageTarget() const GLenum Texture::getBaseImageTarget() const
{ {
return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget; return mState.target == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mState.target;
} }
bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, bool Texture::computeSamplerCompleteness(const SamplerState &samplerState,
const ContextState &data) const const ContextState &data) const
{ {
if (mTextureState.baseLevel > mTextureState.maxLevel) if (mState.baseLevel > mState.maxLevel)
{ {
return false; return false;
} }
const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mEffectiveBaseLevel); const ImageDesc &baseImageDesc =
getImageDesc(getBaseImageTarget(), mState.getEffectiveBaseLevel());
if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0) if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0)
{ {
return false; return false;
} }
// The cases where the texture is incomplete because base level is out of range should be // The cases where the texture is incomplete because base level is out of range should be
// handled by the above condition. // handled by the above condition.
ASSERT(mTextureState.baseLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || ASSERT(mState.baseLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || mState.immutableFormat);
mTextureState.immutableFormat);
if (mTarget == GL_TEXTURE_CUBE_MAP && baseImageDesc.size.width != baseImageDesc.size.height) if (mState.target == GL_TEXTURE_CUBE_MAP &&
baseImageDesc.size.width != baseImageDesc.size.height)
{ {
return false; return false;
} }
...@@ -802,7 +828,7 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, ...@@ -802,7 +828,7 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState,
} }
else else
{ {
if (mTarget == GL_TEXTURE_CUBE_MAP && !isCubeComplete()) if (mState.target == GL_TEXTURE_CUBE_MAP && !isCubeComplete())
{ {
return false; return false;
} }
...@@ -833,11 +859,11 @@ bool Texture::computeMipmapCompleteness() const ...@@ -833,11 +859,11 @@ bool Texture::computeMipmapCompleteness() const
{ {
size_t expectedMipLevels = getMipCompleteLevels(); size_t expectedMipLevels = getMipCompleteLevels();
size_t maxLevel = std::min<size_t>(expectedMipLevels, mTextureState.maxLevel + 1); size_t maxLevel = std::min<size_t>(expectedMipLevels, mState.maxLevel + 1);
for (size_t level = mEffectiveBaseLevel; level < maxLevel; level++) for (size_t level = mState.getEffectiveBaseLevel(); level < maxLevel; level++)
{ {
if (mTarget == GL_TEXTURE_CUBE_MAP) if (mState.target == GL_TEXTURE_CUBE_MAP)
{ {
for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
{ {
...@@ -849,7 +875,7 @@ bool Texture::computeMipmapCompleteness() const ...@@ -849,7 +875,7 @@ bool Texture::computeMipmapCompleteness() const
} }
else else
{ {
if (!computeLevelCompleteness(mTarget, level)) if (!computeLevelCompleteness(mState.target, level))
{ {
return false; return false;
} }
...@@ -863,12 +889,13 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const ...@@ -863,12 +889,13 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const
{ {
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (mTextureState.immutableFormat) if (mState.immutableFormat)
{ {
return true; return true;
} }
const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mEffectiveBaseLevel); const ImageDesc &baseImageDesc =
getImageDesc(getBaseImageTarget(), mState.getEffectiveBaseLevel());
if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0) if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0)
{ {
return false; return false;
...@@ -886,8 +913,8 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const ...@@ -886,8 +913,8 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const
return false; return false;
} }
ASSERT(level >= mEffectiveBaseLevel); ASSERT(level >= mState.getEffectiveBaseLevel());
const size_t relativeLevel = level - mEffectiveBaseLevel; const size_t relativeLevel = level - mState.getEffectiveBaseLevel();
if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel)) if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel))
{ {
return false; return false;
...@@ -898,14 +925,14 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const ...@@ -898,14 +925,14 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const
return false; return false;
} }
if (mTarget == GL_TEXTURE_3D) if (mState.target == GL_TEXTURE_3D)
{ {
if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel)) if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel))
{ {
return false; return false;
} }
} }
else if (mTarget == GL_TEXTURE_2D_ARRAY) else if (mState.target == GL_TEXTURE_2D_ARRAY)
{ {
if (levelImageDesc.size.depth != baseImageDesc.size.depth) if (levelImageDesc.size.depth != baseImageDesc.size.depth)
{ {
......
...@@ -42,6 +42,38 @@ class Framebuffer; ...@@ -42,6 +42,38 @@ class Framebuffer;
bool IsMipmapFiltered(const SamplerState &samplerState); bool IsMipmapFiltered(const SamplerState &samplerState);
// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
struct TextureState final : public angle::NonCopyable
{
TextureState(GLenum target);
bool swizzleRequired() const;
GLuint getEffectiveBaseLevel() const;
// TODO(jmadill): Make the data members here private.
const GLenum target;
GLenum swizzleRed;
GLenum swizzleGreen;
GLenum swizzleBlue;
GLenum swizzleAlpha;
SamplerState samplerState;
GLuint baseLevel;
GLuint maxLevel;
bool immutableFormat;
GLuint immutableLevels;
// From GL_ANGLE_texture_usage
GLenum usage;
};
bool operator==(const TextureState &a, const TextureState &b);
bool operator!=(const TextureState &a, const TextureState &b);
class Texture final : public egl::ImageSibling, class Texture final : public egl::ImageSibling,
public FramebufferAttachmentObject, public FramebufferAttachmentObject,
public LabeledObject public LabeledObject
...@@ -101,8 +133,6 @@ class Texture final : public egl::ImageSibling, ...@@ -101,8 +133,6 @@ class Texture final : public egl::ImageSibling,
void setBaseLevel(GLuint baseLevel); void setBaseLevel(GLuint baseLevel);
GLuint getBaseLevel() const; GLuint getBaseLevel() const;
// Returns base level after clamping required for immutable textures.
GLuint getEffectiveBaseLevel() const;
void setMaxLevel(GLuint maxLevel); void setMaxLevel(GLuint maxLevel);
GLuint getMaxLevel() const; GLuint getMaxLevel() const;
...@@ -204,15 +234,11 @@ class Texture final : public egl::ImageSibling, ...@@ -204,15 +234,11 @@ class Texture final : public egl::ImageSibling,
void acquireImageFromStream(const egl::Stream::GLTextureDescription &desc); void acquireImageFromStream(const egl::Stream::GLTextureDescription &desc);
void releaseImageFromStream(); void releaseImageFromStream();
TextureState mState;
rx::TextureImpl *mTexture; rx::TextureImpl *mTexture;
std::string mLabel; std::string mLabel;
TextureState mTextureState;
GLuint mEffectiveBaseLevel;
GLenum mTarget;
struct ImageDesc struct ImageDesc
{ {
Extents size; Extents size;
...@@ -236,8 +262,6 @@ class Texture final : public egl::ImageSibling, ...@@ -236,8 +262,6 @@ class Texture final : public egl::ImageSibling,
void clearImageDescs(); void clearImageDescs();
void releaseTexImageInternal(); void releaseTexImageInternal();
void updateEffectiveBaseLevel();
std::vector<ImageDesc> mImageDescs; std::vector<ImageDesc> mImageDescs;
struct SamplerCompletenessCache struct SamplerCompletenessCache
...@@ -262,6 +286,19 @@ class Texture final : public egl::ImageSibling, ...@@ -262,6 +286,19 @@ class Texture final : public egl::ImageSibling,
egl::Stream *mBoundStream; egl::Stream *mBoundStream;
}; };
inline bool operator==(const TextureState &a, const TextureState &b)
{
return a.swizzleRed == b.swizzleRed && a.swizzleGreen == b.swizzleGreen &&
a.swizzleBlue == b.swizzleBlue && a.swizzleAlpha == b.swizzleAlpha &&
a.samplerState == b.samplerState && a.baseLevel == b.baseLevel &&
a.maxLevel == b.maxLevel && a.immutableFormat == b.immutableFormat &&
a.immutableLevels == b.immutableLevels && a.usage == b.usage;
}
inline bool operator!=(const TextureState &a, const TextureState &b)
{
return !(a == b);
}
} }
#endif // LIBANGLE_TEXTURE_H_ #endif // LIBANGLE_TEXTURE_H_
...@@ -53,26 +53,6 @@ SamplerState::SamplerState() ...@@ -53,26 +53,6 @@ SamplerState::SamplerState()
{ {
} }
TextureState::TextureState()
: swizzleRed(GL_RED),
swizzleGreen(GL_GREEN),
swizzleBlue(GL_BLUE),
swizzleAlpha(GL_ALPHA),
samplerState(),
baseLevel(0),
maxLevel(1000),
immutableFormat(false),
immutableLevels(0),
usage(GL_NONE)
{
}
bool TextureState::swizzleRequired() const
{
return swizzleRed != GL_RED || swizzleGreen != GL_GREEN ||
swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA;
}
static void MinMax(int a, int b, int *minimum, int *maximum) static void MinMax(int a, int b, int *minimum, int *maximum)
{ {
if (a < b) if (a < b)
......
...@@ -215,33 +215,6 @@ struct SamplerState ...@@ -215,33 +215,6 @@ struct SamplerState
bool operator==(const SamplerState &a, const SamplerState &b); bool operator==(const SamplerState &a, const SamplerState &b);
bool operator!=(const SamplerState &a, const SamplerState &b); bool operator!=(const SamplerState &a, const SamplerState &b);
// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
struct TextureState
{
TextureState();
GLenum swizzleRed;
GLenum swizzleGreen;
GLenum swizzleBlue;
GLenum swizzleAlpha;
SamplerState samplerState;
GLuint baseLevel;
GLuint maxLevel;
bool immutableFormat;
GLuint immutableLevels;
// From GL_ANGLE_texture_usage
GLenum usage;
bool swizzleRequired() const;
};
bool operator==(const TextureState &a, const TextureState &b);
bool operator!=(const TextureState &a, const TextureState &b);
struct PixelUnpackState struct PixelUnpackState
{ {
BindingPointer<Buffer> pixelBuffer; BindingPointer<Buffer> pixelBuffer;
......
...@@ -56,23 +56,4 @@ inline bool operator!=(const SamplerState &a, const SamplerState &b) ...@@ -56,23 +56,4 @@ inline bool operator!=(const SamplerState &a, const SamplerState &b)
return !(a == b); return !(a == b);
} }
inline bool operator==(const TextureState &a, const TextureState &b)
{
return a.swizzleRed == b.swizzleRed &&
a.swizzleGreen == b.swizzleGreen &&
a.swizzleBlue == b.swizzleBlue &&
a.swizzleAlpha == b.swizzleAlpha &&
a.samplerState == b.samplerState &&
a.baseLevel == b.baseLevel &&
a.maxLevel == b.maxLevel &&
a.immutableFormat == b.immutableFormat &&
a.immutableLevels == b.immutableLevels &&
a.usage == b.usage;
}
inline bool operator!=(const TextureState &a, const TextureState &b)
{
return !(a == b);
}
} }
...@@ -55,7 +55,7 @@ class GLImplFactory : angle::NonCopyable ...@@ -55,7 +55,7 @@ class GLImplFactory : angle::NonCopyable
virtual FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) = 0; virtual FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) = 0;
// Texture creation // Texture creation
virtual TextureImpl *createTexture(GLenum target) = 0; virtual TextureImpl *createTexture(const gl::TextureState &state) = 0;
// Renderbuffer creation // Renderbuffer creation
virtual RenderbufferImpl *createRenderbuffer() = 0; virtual RenderbufferImpl *createRenderbuffer() = 0;
......
...@@ -41,7 +41,7 @@ namespace rx ...@@ -41,7 +41,7 @@ namespace rx
class TextureImpl : public FramebufferAttachmentObjectImpl class TextureImpl : public FramebufferAttachmentObjectImpl
{ {
public: public:
TextureImpl() {} TextureImpl(const gl::TextureState &state) : mState(state) {}
virtual ~TextureImpl() {} virtual ~TextureImpl() {}
virtual void setUsage(GLenum usage) = 0; virtual void setUsage(GLenum usage) = 0;
...@@ -69,12 +69,15 @@ class TextureImpl : public FramebufferAttachmentObjectImpl ...@@ -69,12 +69,15 @@ class TextureImpl : public FramebufferAttachmentObjectImpl
egl::Stream *stream, egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc) = 0; const egl::Stream::GLTextureDescription &desc) = 0;
virtual gl::Error generateMipmaps(const gl::TextureState &textureState) = 0; virtual gl::Error generateMipmaps() = 0;
virtual void setBaseLevel(GLuint baseLevel) = 0; virtual void setBaseLevel(GLuint baseLevel) = 0;
virtual void bindTexImage(egl::Surface *surface) = 0; virtual void bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 0; virtual void releaseTexImage() = 0;
protected:
const gl::TextureState &mState;
}; };
} }
......
...@@ -19,6 +19,7 @@ namespace rx ...@@ -19,6 +19,7 @@ namespace rx
class MockTextureImpl : public TextureImpl class MockTextureImpl : public TextureImpl
{ {
public: public:
MockTextureImpl() : TextureImpl(gl::TextureState(GL_TEXTURE_2D)) {}
virtual ~MockTextureImpl() { destructor(); } virtual ~MockTextureImpl() { destructor(); }
MOCK_METHOD1(setUsage, void(GLenum)); MOCK_METHOD1(setUsage, void(GLenum));
MOCK_METHOD8(setImage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &, GLenum, GLenum, const gl::PixelUnpackState &, const uint8_t *)); MOCK_METHOD8(setImage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &, GLenum, GLenum, const gl::PixelUnpackState &, const uint8_t *));
...@@ -31,7 +32,7 @@ class MockTextureImpl : public TextureImpl ...@@ -31,7 +32,7 @@ class MockTextureImpl : public TextureImpl
MOCK_METHOD3(setImageExternal, MOCK_METHOD3(setImageExternal,
gl::Error(GLenum, egl::Stream *, const egl::Stream::GLTextureDescription &)); gl::Error(GLenum, egl::Stream *, const egl::Stream::GLTextureDescription &));
MOCK_METHOD2(setEGLImageTarget, gl::Error(GLenum, egl::Image *)); MOCK_METHOD2(setEGLImageTarget, gl::Error(GLenum, egl::Image *));
MOCK_METHOD1(generateMipmaps, gl::Error(const gl::TextureState &)); MOCK_METHOD0(generateMipmaps, gl::Error());
MOCK_METHOD1(bindTexImage, void(egl::Surface *)); MOCK_METHOD1(bindTexImage, void(egl::Surface *));
MOCK_METHOD0(releaseTexImage, void(void)); MOCK_METHOD0(releaseTexImage, void(void));
......
...@@ -75,8 +75,9 @@ bool IsRenderTargetUsage(GLenum usage) ...@@ -75,8 +75,9 @@ bool IsRenderTargetUsage(GLenum usage)
} }
TextureD3D::TextureD3D(RendererD3D *renderer) TextureD3D::TextureD3D(const gl::TextureState &state, RendererD3D *renderer)
: mRenderer(renderer), : TextureImpl(state),
mRenderer(renderer),
mUsage(GL_NONE), mUsage(GL_NONE),
mDirtyImages(true), mDirtyImages(true),
mImmutable(false), mImmutable(false),
...@@ -404,7 +405,7 @@ gl::Error TextureD3D::setImageExternal(GLenum target, ...@@ -404,7 +405,7 @@ gl::Error TextureD3D::setImageExternal(GLenum target,
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
gl::Error TextureD3D::generateMipmaps(const gl::TextureState &textureState) gl::Error TextureD3D::generateMipmaps()
{ {
GLint mipCount = mipLevels(); GLint mipCount = mipLevels();
...@@ -442,7 +443,7 @@ gl::Error TextureD3D::generateMipmaps(const gl::TextureState &textureState) ...@@ -442,7 +443,7 @@ gl::Error TextureD3D::generateMipmaps(const gl::TextureState &textureState)
} }
// Generate the mipmap chain using the ad-hoc DirectX function. // Generate the mipmap chain using the ad-hoc DirectX function.
error = mRenderer->generateMipmapsUsingD3D(mTexStorage, textureState); error = mRenderer->generateMipmapsUsingD3D(mTexStorage, mState);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -663,8 +664,8 @@ void TextureD3D::setBaseLevel(GLuint baseLevel) ...@@ -663,8 +664,8 @@ void TextureD3D::setBaseLevel(GLuint baseLevel)
} }
} }
TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer) TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(renderer) : TextureD3D(state, renderer)
{ {
mEGLImageTarget = false; mEGLImageTarget = false;
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
...@@ -1344,8 +1345,8 @@ void TextureD3D_2D::markAllImagesDirty() ...@@ -1344,8 +1345,8 @@ void TextureD3D_2D::markAllImagesDirty()
mDirtyImages = true; mDirtyImages = true;
} }
TextureD3D_Cube::TextureD3D_Cube(RendererD3D *renderer) TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(renderer) : TextureD3D(state, renderer)
{ {
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
...@@ -1936,8 +1937,8 @@ void TextureD3D_Cube::markAllImagesDirty() ...@@ -1936,8 +1937,8 @@ void TextureD3D_Cube::markAllImagesDirty()
mDirtyImages = true; mDirtyImages = true;
} }
TextureD3D_3D::TextureD3D_3D(RendererD3D *renderer) TextureD3D_3D::TextureD3D_3D(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(renderer) : TextureD3D(state, renderer)
{ {
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{ {
...@@ -2522,8 +2523,8 @@ GLint TextureD3D_3D::getLevelZeroDepth() const ...@@ -2522,8 +2523,8 @@ GLint TextureD3D_3D::getLevelZeroDepth() const
return getBaseLevelDepth() << getBaseLevel(); return getBaseLevelDepth() << getBaseLevel();
} }
TextureD3D_2DArray::TextureD3D_2DArray(RendererD3D *renderer) TextureD3D_2DArray::TextureD3D_2DArray(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(renderer) : TextureD3D(state, renderer)
{ {
for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
{ {
...@@ -3170,7 +3171,8 @@ void TextureD3D_2DArray::markAllImagesDirty() ...@@ -3170,7 +3171,8 @@ void TextureD3D_2DArray::markAllImagesDirty()
mDirtyImages = true; mDirtyImages = true;
} }
TextureD3D_External::TextureD3D_External(RendererD3D *renderer) : TextureD3D(renderer) TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(state, renderer)
{ {
mImage = renderer->createImage(); mImage = renderer->createImage();
} }
......
...@@ -30,7 +30,7 @@ class TextureStorage; ...@@ -30,7 +30,7 @@ class TextureStorage;
class TextureD3D : public TextureImpl class TextureD3D : public TextureImpl
{ {
public: public:
TextureD3D(RendererD3D *renderer); TextureD3D(const gl::TextureState &data, RendererD3D *renderer);
virtual ~TextureD3D(); virtual ~TextureD3D();
gl::Error getNativeTexture(TextureStorage **outStorage); gl::Error getNativeTexture(TextureStorage **outStorage);
...@@ -61,7 +61,7 @@ class TextureD3D : public TextureImpl ...@@ -61,7 +61,7 @@ class TextureD3D : public TextureImpl
virtual gl::Error setImageExternal(GLenum target, virtual gl::Error setImageExternal(GLenum target,
egl::Stream *stream, egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc) override; const egl::Stream::GLTextureDescription &desc) override;
gl::Error generateMipmaps(const gl::TextureState &textureState) override; gl::Error generateMipmaps() override;
TextureStorage *getStorage(); TextureStorage *getStorage();
ImageD3D *getBaseLevelImage() const; ImageD3D *getBaseLevelImage() const;
...@@ -135,7 +135,7 @@ class TextureD3D : public TextureImpl ...@@ -135,7 +135,7 @@ class TextureD3D : public TextureImpl
class TextureD3D_2D : public TextureD3D class TextureD3D_2D : public TextureD3D
{ {
public: public:
TextureD3D_2D(RendererD3D *renderer); TextureD3D_2D(const gl::TextureState &data, RendererD3D *renderer);
virtual ~TextureD3D_2D(); virtual ~TextureD3D_2D();
virtual ImageD3D *getImage(int level, int layer) const; virtual ImageD3D *getImage(int level, int layer) const;
...@@ -204,7 +204,7 @@ class TextureD3D_2D : public TextureD3D ...@@ -204,7 +204,7 @@ class TextureD3D_2D : public TextureD3D
class TextureD3D_Cube : public TextureD3D class TextureD3D_Cube : public TextureD3D
{ {
public: public:
TextureD3D_Cube(RendererD3D *renderer); TextureD3D_Cube(const gl::TextureState &data, RendererD3D *renderer);
virtual ~TextureD3D_Cube(); virtual ~TextureD3D_Cube();
virtual ImageD3D *getImage(int level, int layer) const; virtual ImageD3D *getImage(int level, int layer) const;
...@@ -271,7 +271,7 @@ class TextureD3D_Cube : public TextureD3D ...@@ -271,7 +271,7 @@ class TextureD3D_Cube : public TextureD3D
class TextureD3D_3D : public TextureD3D class TextureD3D_3D : public TextureD3D
{ {
public: public:
TextureD3D_3D(RendererD3D *renderer); TextureD3D_3D(const gl::TextureState &data, RendererD3D *renderer);
virtual ~TextureD3D_3D(); virtual ~TextureD3D_3D();
virtual ImageD3D *getImage(int level, int layer) const; virtual ImageD3D *getImage(int level, int layer) const;
...@@ -337,7 +337,7 @@ class TextureD3D_3D : public TextureD3D ...@@ -337,7 +337,7 @@ class TextureD3D_3D : public TextureD3D
class TextureD3D_2DArray : public TextureD3D class TextureD3D_2DArray : public TextureD3D
{ {
public: public:
TextureD3D_2DArray(RendererD3D *renderer); TextureD3D_2DArray(const gl::TextureState &data, RendererD3D *renderer);
virtual ~TextureD3D_2DArray(); virtual ~TextureD3D_2DArray();
virtual ImageD3D *getImage(int level, int layer) const; virtual ImageD3D *getImage(int level, int layer) const;
...@@ -407,7 +407,7 @@ class TextureD3D_2DArray : public TextureD3D ...@@ -407,7 +407,7 @@ class TextureD3D_2DArray : public TextureD3D
class TextureD3D_External : public TextureD3D class TextureD3D_External : public TextureD3D
{ {
public: public:
TextureD3D_External(RendererD3D *renderer); TextureD3D_External(const gl::TextureState &data, RendererD3D *renderer);
~TextureD3D_External() override; ~TextureD3D_External() override;
ImageD3D *getImage(const gl::ImageIndex &index) const override; ImageD3D *getImage(const gl::ImageIndex &index) const override;
......
...@@ -1296,15 +1296,7 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t ...@@ -1296,15 +1296,7 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage); TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
// Make sure to add the level offset for our tiny compressed texture workaround ANGLE_TRY(storage11->getSRV(texture->getTextureState(), &textureSRV));
gl::TextureState textureState = texture->getTextureState();
textureState.baseLevel = texture->getEffectiveBaseLevel() + storage11->getTopLevel();
error = storage11->getSRV(textureState, &textureSRV);
if (error.isError())
{
return error;
}
// If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
// missing the shader resource view // missing the shader resource view
...@@ -2413,7 +2405,7 @@ void Renderer11::SamplerMetadataD3D11::initData(unsigned int samplerCount) ...@@ -2413,7 +2405,7 @@ void Renderer11::SamplerMetadataD3D11::initData(unsigned int samplerCount)
void Renderer11::SamplerMetadataD3D11::update(unsigned int samplerIndex, const gl::Texture &texture) void Renderer11::SamplerMetadataD3D11::update(unsigned int samplerIndex, const gl::Texture &texture)
{ {
unsigned int baseLevel = texture.getEffectiveBaseLevel(); unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
GLenum internalFormat = texture.getInternalFormat(texture.getTarget(), baseLevel); GLenum internalFormat = texture.getInternalFormat(texture.getTarget(), baseLevel);
if (mSamplerMetadata[samplerIndex].baseLevel != static_cast<int>(baseLevel)) if (mSamplerMetadata[samplerIndex].baseLevel != static_cast<int>(baseLevel))
{ {
...@@ -3733,18 +3725,22 @@ TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, b ...@@ -3733,18 +3725,22 @@ TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, b
return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels); return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
} }
TextureImpl *Renderer11::createTexture(GLenum target) TextureImpl *Renderer11::createTexture(const gl::TextureState &state)
{ {
switch(target) switch (state.target)
{ {
case GL_TEXTURE_2D: return new TextureD3D_2D(this); case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); return new TextureD3D_2D(state, this);
case GL_TEXTURE_3D: return new TextureD3D_3D(this); case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this); return new TextureD3D_Cube(state, this);
case GL_TEXTURE_EXTERNAL_OES: case GL_TEXTURE_3D:
return new TextureD3D_External(this); return new TextureD3D_3D(state, this);
default: case GL_TEXTURE_2D_ARRAY:
UNREACHABLE(); return new TextureD3D_2DArray(state, this);
case GL_TEXTURE_EXTERNAL_OES:
return new TextureD3D_External(state, this);
default:
UNREACHABLE();
} }
return NULL; return NULL;
......
...@@ -230,7 +230,7 @@ class Renderer11 : public RendererD3D ...@@ -230,7 +230,7 @@ class Renderer11 : public RendererD3D
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
// Texture creation // Texture creation
virtual TextureImpl *createTexture(GLenum target); TextureImpl *createTexture(const gl::TextureState &state) override;
// Renderbuffer creation // Renderbuffer creation
virtual RenderbufferImpl *createRenderbuffer(); virtual RenderbufferImpl *createRenderbuffer();
......
...@@ -160,6 +160,8 @@ UINT TextureStorage11::getMiscFlags() const ...@@ -160,6 +160,8 @@ UINT TextureStorage11::getMiscFlags() const
int TextureStorage11::getTopLevel() const int TextureStorage11::getTopLevel() const
{ {
// Applying top level is meant to be encapsulated inside TextureStorage11.
UNREACHABLE();
return mTopLevel; return mTopLevel;
} }
...@@ -210,13 +212,15 @@ UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const ...@@ -210,13 +212,15 @@ UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState,
ID3D11ShaderResourceView **outSRV) ID3D11ShaderResourceView **outSRV)
{ {
// Make sure to add the level offset for our tiny compressed texture workaround
const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel();
bool swizzleRequired = textureState.swizzleRequired(); bool swizzleRequired = textureState.swizzleRequired();
bool mipmapping = gl::IsMipmapFiltered(textureState.samplerState); bool mipmapping = gl::IsMipmapFiltered(textureState.samplerState);
unsigned int mipLevels = mipmapping ? (textureState.maxLevel - textureState.baseLevel + 1) : 1; unsigned int mipLevels = mipmapping ? (textureState.maxLevel - effectiveBaseLevel + 1) : 1;
// Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
// which corresponds to GL level 0) // which corresponds to GL level 0)
mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - textureState.baseLevel); mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel);
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{ {
...@@ -240,45 +244,41 @@ gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, ...@@ -240,45 +244,41 @@ gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState,
textureState.swizzleBlue, textureState.swizzleAlpha); textureState.swizzleBlue, textureState.swizzleAlpha);
} }
SRVKey key(textureState.baseLevel, mipLevels, swizzleRequired); SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired);
ANGLE_TRY(getCachedOrCreateSRV(key, outSRV));
return gl::NoError();
}
gl::Error TextureStorage11::getCachedOrCreateSRV(const SRVKey &key,
ID3D11ShaderResourceView **outSRV)
{
auto iter = mSrvCache.find(key); auto iter = mSrvCache.find(key);
if (iter != mSrvCache.end()) if (iter != mSrvCache.end())
{ {
*outSRV = iter->second; *outSRV = iter->second;
return gl::Error(GL_NO_ERROR); return gl::NoError();
} }
ID3D11Resource *texture = nullptr; ID3D11Resource *texture = nullptr;
if (swizzleRequired) if (key.swizzle)
{ {
gl::Error error = getSwizzleTexture(&texture); ANGLE_TRY(getSwizzleTexture(&texture));
if (error.isError())
{
return error;
}
} }
else else
{ {
gl::Error error = getResource(&texture); ANGLE_TRY(getResource(&texture));
if (error.isError())
{
return error;
}
} }
ID3D11ShaderResourceView *srv = nullptr; ID3D11ShaderResourceView *srv = nullptr;
DXGI_FORMAT format = DXGI_FORMAT format =
(swizzleRequired ? mSwizzleFormatSet->srvFormat : mTextureFormatSet->srvFormat); (key.swizzle ? mSwizzleFormatSet->srvFormat : mTextureFormatSet->srvFormat);
gl::Error error = createSRV(textureState.baseLevel, mipLevels, format, texture, &srv); ANGLE_TRY(createSRV(key.baseLevel, key.mipLevels, format, texture, &srv));
if (error.isError())
{
return error;
}
mSrvCache.insert(std::make_pair(key, srv)); mSrvCache.insert(std::make_pair(key, srv));
*outSRV = srv; *outSRV = srv;
return gl::Error(GL_NO_ERROR); return gl::NoError();
} }
gl::Error TextureStorage11::getSRVLevel(int mipLevel, gl::Error TextureStorage11::getSRVLevel(int mipLevel,
...@@ -349,31 +349,9 @@ gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, ...@@ -349,31 +349,9 @@ gl::Error TextureStorage11::getSRVLevels(GLint baseLevel,
} }
SRVKey key(baseLevel, mipLevels, false); SRVKey key(baseLevel, mipLevels, false);
auto iter = mSrvCache.find(key); ANGLE_TRY(getCachedOrCreateSRV(key, outSRV));
if (iter != mSrvCache.end())
{
*outSRV = iter->second;
return gl::Error(GL_NO_ERROR);
}
ID3D11Resource *texture = nullptr;
gl::Error error = getResource(&texture);
if (error.isError())
{
return error;
}
ID3D11ShaderResourceView *srv = nullptr; return gl::NoError();
error = createSRV(baseLevel, mipLevels, mTextureFormatSet->srvFormat, texture, &srv);
if (error.isError())
{
return error;
}
mSrvCache[key] = srv;
*outSRV = srv;
return gl::Error(GL_NO_ERROR);
} }
d3d11::ANGLEFormat TextureStorage11::getANGLEFormat() const d3d11::ANGLEFormat TextureStorage11::getANGLEFormat() const
......
...@@ -94,6 +94,7 @@ class TextureStorage11 : public TextureStorage ...@@ -94,6 +94,7 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0; virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0;
gl::Error getSRVLevel(int mipLevel, bool blitSRV, ID3D11ShaderResourceView **outSRV); gl::Error getSRVLevel(int mipLevel, bool blitSRV, ID3D11ShaderResourceView **outSRV);
// The baseLevel parameter should *not* have mTopLevel applied.
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const = 0; ID3D11ShaderResourceView **outSRV) const = 0;
...@@ -138,12 +139,14 @@ class TextureStorage11 : public TextureStorage ...@@ -138,12 +139,14 @@ class TextureStorage11 : public TextureStorage
bool operator<(const SRVKey &rhs) const; bool operator<(const SRVKey &rhs) const;
int baseLevel; int baseLevel; // Without mTopLevel applied.
int mipLevels; int mipLevels;
bool swizzle; bool swizzle;
}; };
typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache; typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache;
gl::Error getCachedOrCreateSRV(const SRVKey &key, ID3D11ShaderResourceView **outSRV);
SRVCache mSrvCache; SRVCache mSrvCache;
std::array<ID3D11ShaderResourceView *, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> mLevelSRVs; std::array<ID3D11ShaderResourceView *, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> mLevelSRVs;
std::array<ID3D11ShaderResourceView *, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> mLevelBlitSRVs; std::array<ID3D11ShaderResourceView *, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> mLevelBlitSRVs;
......
...@@ -2749,13 +2749,16 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo ...@@ -2749,13 +2749,16 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo
return NULL; return NULL;
} }
TextureImpl *Renderer9::createTexture(GLenum target) TextureImpl *Renderer9::createTexture(const gl::TextureState &state)
{ {
switch(target) switch (state.target)
{ {
case GL_TEXTURE_2D: return new TextureD3D_2D(this); case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); return new TextureD3D_2D(state, this);
default: UNREACHABLE(); case GL_TEXTURE_CUBE_MAP:
return new TextureD3D_Cube(state, this);
default:
UNREACHABLE();
} }
return NULL; return NULL;
......
...@@ -225,7 +225,7 @@ class Renderer9 : public RendererD3D ...@@ -225,7 +225,7 @@ class Renderer9 : public RendererD3D
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
// Texture creation // Texture creation
virtual TextureImpl *createTexture(GLenum target); TextureImpl *createTexture(const gl::TextureState &state) override;
// Renderbuffer creation // Renderbuffer creation
virtual RenderbufferImpl *createRenderbuffer(); virtual RenderbufferImpl *createRenderbuffer();
......
...@@ -288,9 +288,9 @@ FramebufferImpl *RendererGL::createFramebuffer(const gl::FramebufferState &data) ...@@ -288,9 +288,9 @@ FramebufferImpl *RendererGL::createFramebuffer(const gl::FramebufferState &data)
return new FramebufferGL(data, mFunctions, mStateManager, mWorkarounds, false); return new FramebufferGL(data, mFunctions, mStateManager, mWorkarounds, false);
} }
TextureImpl *RendererGL::createTexture(GLenum target) TextureImpl *RendererGL::createTexture(const gl::TextureState &state)
{ {
return new TextureGL(target, mFunctions, mWorkarounds, mStateManager, mBlitter); return new TextureGL(state, mFunctions, mWorkarounds, mStateManager, mBlitter);
} }
RenderbufferImpl *RendererGL::createRenderbuffer() RenderbufferImpl *RendererGL::createRenderbuffer()
......
...@@ -71,7 +71,7 @@ class RendererGL : public Renderer ...@@ -71,7 +71,7 @@ class RendererGL : public Renderer
FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
// Texture creation // Texture creation
TextureImpl *createTexture(GLenum target) override; TextureImpl *createTexture(const gl::TextureState &state) override;
// Renderbuffer creation // Renderbuffer creation
RenderbufferImpl *createRenderbuffer() override; RenderbufferImpl *createRenderbuffer() override;
......
...@@ -730,8 +730,7 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::ContextState &data) ...@@ -730,8 +730,7 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::ContextState &data)
bindTexture(textureType, textureGL->getTextureID()); bindTexture(textureType, textureGL->getTextureID());
} }
textureGL->syncState(textureUnitIndex, texture->getTextureState(), textureGL->syncState(textureUnitIndex);
texture->getEffectiveBaseLevel());
} }
else else
{ {
......
...@@ -106,19 +106,18 @@ LevelInfoGL::LevelInfoGL(GLenum sourceFormat_, ...@@ -106,19 +106,18 @@ LevelInfoGL::LevelInfoGL(GLenum sourceFormat_,
{ {
} }
TextureGL::TextureGL(GLenum type, TextureGL::TextureGL(const gl::TextureState &state,
const FunctionsGL *functions, const FunctionsGL *functions,
const WorkaroundsGL &workarounds, const WorkaroundsGL &workarounds,
StateManagerGL *stateManager, StateManagerGL *stateManager,
BlitGL *blitter) BlitGL *blitter)
: TextureImpl(), : TextureImpl(state),
mTextureType(type),
mFunctions(functions), mFunctions(functions),
mWorkarounds(workarounds), mWorkarounds(workarounds),
mStateManager(stateManager), mStateManager(stateManager),
mBlitter(blitter), mBlitter(blitter),
mLevelInfo(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1), mLevelInfo(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1),
mAppliedTextureState(), mAppliedTextureState(state.target),
mTextureID(0) mTextureID(0)
{ {
ASSERT(mFunctions); ASSERT(mFunctions);
...@@ -126,7 +125,7 @@ TextureGL::TextureGL(GLenum type, ...@@ -126,7 +125,7 @@ TextureGL::TextureGL(GLenum type,
ASSERT(mBlitter); ASSERT(mBlitter);
mFunctions->genTextures(1, &mTextureID); mFunctions->genTextures(1, &mTextureID);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
} }
TextureGL::~TextureGL() TextureGL::~TextureGL()
...@@ -145,20 +144,20 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat ...@@ -145,20 +144,20 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat
const gl::PixelUnpackState &unpack, const uint8_t *pixels) const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{ {
UNUSED_ASSERTION_VARIABLE(&CompatibleTextureTarget); // Reference this function to avoid warnings. UNUSED_ASSERTION_VARIABLE(&CompatibleTextureTarget); // Reference this function to avoid warnings.
ASSERT(CompatibleTextureTarget(mTextureType, target)); ASSERT(CompatibleTextureTarget(mState.target, target));
nativegl::TexImageFormat texImageFormat = nativegl::TexImageFormat texImageFormat =
nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type); nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
mFunctions->texImage2D(target, static_cast<GLint>(level), texImageFormat.internalFormat, mFunctions->texImage2D(target, static_cast<GLint>(level), texImageFormat.internalFormat,
size.width, size.height, 0, texImageFormat.format, size.width, size.height, 0, texImageFormat.format,
texImageFormat.type, pixels); texImageFormat.type, pixels);
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mState.target))
{ {
mFunctions->texImage3D(target, static_cast<GLint>(level), texImageFormat.internalFormat, mFunctions->texImage3D(target, static_cast<GLint>(level), texImageFormat.internalFormat,
size.width, size.height, size.depth, 0, texImageFormat.format, size.width, size.height, size.depth, 0, texImageFormat.format,
...@@ -177,20 +176,20 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat ...@@ -177,20 +176,20 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat
gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixels) const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{ {
ASSERT(CompatibleTextureTarget(mTextureType, target)); ASSERT(CompatibleTextureTarget(mState.target, target));
nativegl::TexSubImageFormat texSubImageFormat = nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
ASSERT(area.z == 0 && area.depth == 1); ASSERT(area.z == 0 && area.depth == 1);
mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width, mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width,
area.height, texSubImageFormat.format, texSubImageFormat.type, area.height, texSubImageFormat.format, texSubImageFormat.type,
pixels); pixels);
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mState.target))
{ {
mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z,
area.width, area.height, area.depth, texSubImageFormat.format, area.width, area.height, area.depth, texSubImageFormat.format,
...@@ -210,20 +209,20 @@ gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &are ...@@ -210,20 +209,20 @@ gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &are
gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
{ {
ASSERT(CompatibleTextureTarget(mTextureType, target)); ASSERT(CompatibleTextureTarget(mState.target, target));
nativegl::CompressedTexImageFormat compressedTexImageFormat = nativegl::CompressedTexImageFormat compressedTexImageFormat =
nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat); nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
mFunctions->compressedTexImage2D(target, static_cast<GLint>(level), mFunctions->compressedTexImage2D(target, static_cast<GLint>(level),
compressedTexImageFormat.internalFormat, size.width, compressedTexImageFormat.internalFormat, size.width,
size.height, 0, static_cast<GLsizei>(imageSize), pixels); size.height, 0, static_cast<GLsizei>(imageSize), pixels);
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mState.target))
{ {
mFunctions->compressedTexImage3D( mFunctions->compressedTexImage3D(
target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width, target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width,
...@@ -243,20 +242,20 @@ gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum inte ...@@ -243,20 +242,20 @@ gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum inte
gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
{ {
ASSERT(CompatibleTextureTarget(mTextureType, target)); ASSERT(CompatibleTextureTarget(mState.target, target));
nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat = nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format); nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
ASSERT(area.z == 0 && area.depth == 1); ASSERT(area.z == 0 && area.depth == 1);
mFunctions->compressedTexSubImage2D( mFunctions->compressedTexSubImage2D(
target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, target, static_cast<GLint>(level), area.x, area.y, area.width, area.height,
compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels); compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels);
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mState.target))
{ {
mFunctions->compressedTexSubImage3D(target, static_cast<GLint>(level), area.x, area.y, mFunctions->compressedTexSubImage3D(target, static_cast<GLint>(level), area.x, area.y,
area.z, area.width, area.height, area.depth, area.z, area.width, area.height, area.depth,
...@@ -284,7 +283,7 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle ...@@ -284,7 +283,7 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle
if (levelInfo.lumaWorkaround.enabled) if (levelInfo.lumaWorkaround.enabled)
{ {
gl::Error error = mBlitter->copyImageToLUMAWorkaroundTexture( gl::Error error = mBlitter->copyImageToLUMAWorkaroundTexture(
mTextureID, mTextureType, target, levelInfo.sourceFormat, level, sourceArea, mTextureID, mState.target, target, levelInfo.sourceFormat, level, sourceArea,
copyTexImageFormat.internalFormat, source); copyTexImageFormat.internalFormat, source);
if (error.isError()) if (error.isError())
{ {
...@@ -295,11 +294,11 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle ...@@ -295,11 +294,11 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle
{ {
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER,
sourceFramebufferGL->getFramebufferID()); sourceFramebufferGL->getFramebufferID());
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
mFunctions->copyTexImage2D(target, static_cast<GLint>(level), mFunctions->copyTexImage2D(target, static_cast<GLint>(level),
copyTexImageFormat.internalFormat, sourceArea.x, copyTexImageFormat.internalFormat, sourceArea.x,
...@@ -321,15 +320,15 @@ gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset ...@@ -321,15 +320,15 @@ gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset
{ {
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
const LevelInfoGL &levelInfo = mLevelInfo[level]; const LevelInfoGL &levelInfo = mLevelInfo[level];
if (levelInfo.lumaWorkaround.enabled) if (levelInfo.lumaWorkaround.enabled)
{ {
gl::Error error = mBlitter->copySubImageToLUMAWorkaroundTexture( gl::Error error = mBlitter->copySubImageToLUMAWorkaroundTexture(
mTextureID, mTextureType, target, levelInfo.sourceFormat, level, destOffset, sourceArea, mTextureID, mState.target, target, levelInfo.sourceFormat, level, destOffset,
source); sourceArea, source);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -337,14 +336,14 @@ gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset ...@@ -337,14 +336,14 @@ gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset
} }
else else
{ {
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
ASSERT(destOffset.z == 0); ASSERT(destOffset.z == 0);
mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x, mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x,
destOffset.y, sourceArea.x, sourceArea.y, destOffset.y, sourceArea.x, sourceArea.y,
sourceArea.width, sourceArea.height); sourceArea.width, sourceArea.height);
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mState.target))
{ {
mFunctions->copyTexSubImage3D(target, static_cast<GLint>(level), destOffset.x, mFunctions->copyTexSubImage3D(target, static_cast<GLint>(level), destOffset.x,
destOffset.y, destOffset.z, sourceArea.x, sourceArea.y, destOffset.y, destOffset.z, sourceArea.x, sourceArea.y,
...@@ -367,8 +366,8 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -367,8 +366,8 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
nativegl::TexStorageFormat texStorageFormat = nativegl::TexStorageFormat texStorageFormat =
nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat); nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
if (mFunctions->texStorage2D) if (mFunctions->texStorage2D)
...@@ -392,7 +391,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -392,7 +391,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
std::max(size.height >> level, 1), std::max(size.height >> level, 1),
1); 1);
if (mTextureType == GL_TEXTURE_2D) if (mState.target == GL_TEXTURE_2D)
{ {
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
...@@ -410,7 +409,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -410,7 +409,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
internalFormatInfo.type, nullptr); internalFormatInfo.type, nullptr);
} }
} }
else if (mTextureType == GL_TEXTURE_CUBE_MAP) else if (mState.target == GL_TEXTURE_CUBE_MAP)
{ {
for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++)
{ {
...@@ -438,7 +437,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -438,7 +437,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
} }
} }
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mState.target))
{ {
if (mFunctions->texStorage3D) if (mFunctions->texStorage3D)
{ {
...@@ -458,9 +457,9 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -458,9 +457,9 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
for (GLsizei i = 0; i < static_cast<GLsizei>(levels); i++) for (GLsizei i = 0; i < static_cast<GLsizei>(levels); i++)
{ {
gl::Extents levelSize(std::max(size.width >> i, 1), gl::Extents levelSize(
std::max(size.height >> i, 1), std::max(size.width >> i, 1), std::max(size.height >> i, 1),
mTextureType == GL_TEXTURE_3D ? std::max(size.depth >> i, 1) : size.depth); mState.target == GL_TEXTURE_3D ? std::max(size.depth >> i, 1) : size.depth);
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
...@@ -503,14 +502,14 @@ gl::Error TextureGL::setImageExternal(GLenum target, ...@@ -503,14 +502,14 @@ gl::Error TextureGL::setImageExternal(GLenum target,
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
gl::Error TextureGL::generateMipmaps(const gl::TextureState &textureState) gl::Error TextureGL::generateMipmaps()
{ {
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
mFunctions->generateMipmap(mTextureType); mFunctions->generateMipmap(mState.target);
for (size_t level = textureState.baseLevel; level < mLevelInfo.size(); level++) for (size_t level = mState.baseLevel; level < mLevelInfo.size(); level++)
{ {
mLevelInfo[level] = mLevelInfo[textureState.baseLevel]; mLevelInfo[level] = mLevelInfo[mState.baseLevel];
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -518,10 +517,10 @@ gl::Error TextureGL::generateMipmaps(const gl::TextureState &textureState) ...@@ -518,10 +517,10 @@ gl::Error TextureGL::generateMipmaps(const gl::TextureState &textureState)
void TextureGL::bindTexImage(egl::Surface *surface) void TextureGL::bindTexImage(egl::Surface *surface)
{ {
ASSERT(mTextureType == GL_TEXTURE_2D); ASSERT(mState.target == GL_TEXTURE_2D);
// Make sure this texture is bound // Make sure this texture is bound
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
mLevelInfo[0] = LevelInfoGL(); mLevelInfo[0] = LevelInfoGL();
} }
...@@ -529,12 +528,13 @@ void TextureGL::bindTexImage(egl::Surface *surface) ...@@ -529,12 +528,13 @@ void TextureGL::bindTexImage(egl::Surface *surface)
void TextureGL::releaseTexImage() void TextureGL::releaseTexImage()
{ {
// Not all Surface implementations reset the size of mip 0 when releasing, do it manually // Not all Surface implementations reset the size of mip 0 when releasing, do it manually
ASSERT(mTextureType == GL_TEXTURE_2D); ASSERT(mState.target == GL_TEXTURE_2D);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mState.target))
{ {
mFunctions->texImage2D(mTextureType, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); mFunctions->texImage2D(mState.target, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
} }
else else
{ {
...@@ -712,9 +712,7 @@ static inline void SyncTextureStateSwizzle(const FunctionsGL *functions, ...@@ -712,9 +712,7 @@ static inline void SyncTextureStateSwizzle(const FunctionsGL *functions,
} }
} }
void TextureGL::syncState(size_t textureUnit, void TextureGL::syncState(size_t textureUnit) const
const gl::TextureState &textureState,
const GLuint effectiveBaseLevel) const
{ {
// Callback lamdba to bind this texture only if needed. // Callback lamdba to bind this texture only if needed.
bool textureApplied = false; bool textureApplied = false;
...@@ -723,7 +721,7 @@ void TextureGL::syncState(size_t textureUnit, ...@@ -723,7 +721,7 @@ void TextureGL::syncState(size_t textureUnit,
if (!textureApplied) if (!textureApplied)
{ {
mStateManager->activeTexture(textureUnit); mStateManager->activeTexture(textureUnit);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mState.target, mTextureID);
textureApplied = true; textureApplied = true;
} }
}; };
...@@ -731,26 +729,26 @@ void TextureGL::syncState(size_t textureUnit, ...@@ -731,26 +729,26 @@ void TextureGL::syncState(size_t textureUnit,
// clang-format off // clang-format off
// Sync texture state // Sync texture state
SyncTextureStateMember(mFunctions, applyTextureFunc, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_BASE_LEVEL, &gl::TextureState::baseLevel); SyncTextureStateMember(mFunctions, applyTextureFunc, mState, mAppliedTextureState, mState.target, GL_TEXTURE_BASE_LEVEL, &gl::TextureState::baseLevel);
SyncTextureStateMember(mFunctions, applyTextureFunc, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_MAX_LEVEL, &gl::TextureState::maxLevel); SyncTextureStateMember(mFunctions, applyTextureFunc, mState, mAppliedTextureState, mState.target, GL_TEXTURE_MAX_LEVEL, &gl::TextureState::maxLevel);
const LevelInfoGL &levelInfo = mLevelInfo[effectiveBaseLevel]; const LevelInfoGL &levelInfo = mLevelInfo[mState.getEffectiveBaseLevel()];
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_R, &gl::TextureState::swizzleRed); SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_R, &gl::TextureState::swizzleRed);
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_G, &gl::TextureState::swizzleGreen); SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_G, &gl::TextureState::swizzleGreen);
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_B, &gl::TextureState::swizzleBlue); SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_B, &gl::TextureState::swizzleBlue);
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_A, &gl::TextureState::swizzleAlpha); SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_A, &gl::TextureState::swizzleAlpha);
// Sync sampler state // Sync sampler state
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode);
SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc); SyncSamplerStateMember(mFunctions, applyTextureFunc, mState.samplerState, mAppliedTextureState.samplerState, mState.target, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc);
// clang-format on // clang-format on
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/renderer/TextureImpl.h" #include "libANGLE/renderer/TextureImpl.h"
#include "libANGLE/Texture.h"
namespace rx namespace rx
{ {
...@@ -51,7 +52,7 @@ struct LevelInfoGL ...@@ -51,7 +52,7 @@ struct LevelInfoGL
class TextureGL : public TextureImpl class TextureGL : public TextureImpl
{ {
public: public:
TextureGL(GLenum type, TextureGL(const gl::TextureState &state,
const FunctionsGL *functions, const FunctionsGL *functions,
const WorkaroundsGL &workarounds, const WorkaroundsGL &workarounds,
StateManagerGL *stateManager, StateManagerGL *stateManager,
...@@ -81,16 +82,14 @@ class TextureGL : public TextureImpl ...@@ -81,16 +82,14 @@ class TextureGL : public TextureImpl
egl::Stream *stream, egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc) override; const egl::Stream::GLTextureDescription &desc) override;
gl::Error generateMipmaps(const gl::TextureState &textureState) override; gl::Error generateMipmaps() override;
void bindTexImage(egl::Surface *surface) override; void bindTexImage(egl::Surface *surface) override;
void releaseTexImage() override; void releaseTexImage() override;
gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override;
void syncState(size_t textureUnit, void syncState(size_t textureUnit) const;
const gl::TextureState &textureState,
const GLuint effectiveBaseLevel) const;
GLuint getTextureID() const; GLuint getTextureID() const;
gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target,
...@@ -102,8 +101,6 @@ class TextureGL : public TextureImpl ...@@ -102,8 +101,6 @@ class TextureGL : public TextureImpl
void setBaseLevel(GLuint) override {} void setBaseLevel(GLuint) override {}
private: private:
GLenum mTextureType;
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
const WorkaroundsGL &mWorkarounds; const WorkaroundsGL &mWorkarounds;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
......
...@@ -34,7 +34,7 @@ class NullFactory : public GLImplFactory ...@@ -34,7 +34,7 @@ class NullFactory : public GLImplFactory
} }
// Texture creation // Texture creation
TextureImpl *createTexture(GLenum target) override { return nullptr; } TextureImpl *createTexture(const gl::TextureState &data) override { return nullptr; }
// Renderbuffer creation // Renderbuffer creation
RenderbufferImpl *createRenderbuffer() override { return nullptr; } RenderbufferImpl *createRenderbuffer() override { return nullptr; }
...@@ -69,7 +69,7 @@ class MockGLFactory : public GLImplFactory ...@@ -69,7 +69,7 @@ class MockGLFactory : public GLImplFactory
MOCK_METHOD1(createShader, ShaderImpl *(const gl::ShaderState &)); MOCK_METHOD1(createShader, ShaderImpl *(const gl::ShaderState &));
MOCK_METHOD1(createProgram, ProgramImpl *(const gl::ProgramState &)); MOCK_METHOD1(createProgram, ProgramImpl *(const gl::ProgramState &));
MOCK_METHOD1(createFramebuffer, FramebufferImpl *(const gl::FramebufferState &)); MOCK_METHOD1(createFramebuffer, FramebufferImpl *(const gl::FramebufferState &));
MOCK_METHOD1(createTexture, TextureImpl *(GLenum target)); MOCK_METHOD1(createTexture, TextureImpl *(const gl::TextureState &));
MOCK_METHOD0(createRenderbuffer, RenderbufferImpl *()); MOCK_METHOD0(createRenderbuffer, RenderbufferImpl *());
MOCK_METHOD0(createBuffer, BufferImpl *()); MOCK_METHOD0(createBuffer, BufferImpl *());
MOCK_METHOD1(createVertexArray, VertexArrayImpl *(const gl::VertexArrayState &)); MOCK_METHOD1(createVertexArray, VertexArrayImpl *(const gl::VertexArrayState &));
......
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