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();
......
...@@ -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
{ {
......
...@@ -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