Commit 6053a52e by Brandon Jones

Moved some validation back to Texture, unified all TextureImpl variants

BUG=angle:688 Change-Id: Ie2df18277c84345fceaa31d4f63f5cbbb47540c6 Reviewed-on: https://chromium-review.googlesource.com/211387Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarBrandon Jones <bajones@chromium.org>
parent b9b5c105
......@@ -66,10 +66,10 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
mTexture2DZero.set(new Texture2D(mRenderer->createTexture2D(), 0));
mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTextureCube(), 0));
mTexture3DZero.set(new Texture3D(mRenderer->createTexture3D(), 0));
mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture2DArray(), 0));
mTexture2DZero.set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
mTexture3DZero.set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
bindVertexArray(0);
bindArrayBuffer(0);
......@@ -1501,7 +1501,7 @@ void Context::applyTextures(SamplerType shaderType, Texture *textures[], Texture
if (texture)
{
// TODO: std::binary_search may become unavailable using older versions of GCC
if (texture->isSamplerComplete(sampler) &&
if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
!std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
{
mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
......@@ -2118,7 +2118,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_2D:
{
Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture2D(), Texture::INCOMPLETE_TEXTURE_ID);
Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2d;
}
......@@ -2126,7 +2126,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_CUBE:
{
TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTextureCube(), Texture::INCOMPLETE_TEXTURE_ID);
TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
......@@ -2141,7 +2141,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_3D:
{
Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture3D(), Texture::INCOMPLETE_TEXTURE_ID);
Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete3d;
......@@ -2150,7 +2150,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_2D_ARRAY:
{
Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture2DArray(), Texture::INCOMPLETE_TEXTURE_ID);
Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2darray;
......
......@@ -379,19 +379,19 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
if (type == TEXTURE_2D)
{
textureObject = new Texture2D(mRenderer->createTexture2D(), texture);
textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
}
else if (type == TEXTURE_CUBE)
{
textureObject = new TextureCubeMap(mRenderer->createTextureCube(), texture);
textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
}
else if (type == TEXTURE_3D)
{
textureObject = new Texture3D(mRenderer->createTexture3D(), texture);
textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
}
else if (type == TEXTURE_2D_ARRAY)
{
textureObject = new Texture2DArray(mRenderer->createTexture2DArray(), texture);
textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
}
else
{
......
......@@ -14,6 +14,7 @@
#include "libGLESv2/main.h"
#include "common/mathutil.h"
#include "common/utilities.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/renderer/Image.h"
......@@ -24,8 +25,31 @@
namespace gl
{
Texture::Texture(GLuint id, GLenum target)
bool IsMipmapFiltered(const gl::SamplerState &samplerState)
{
switch (samplerState.minFilter)
{
case GL_NEAREST:
case GL_LINEAR:
return false;
case GL_NEAREST_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
return true;
default: UNREACHABLE();
return false;
}
}
bool IsPointSampled(const gl::SamplerState &samplerState)
{
return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
}
Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
: RefCountObject(id),
mTexture(impl),
mUsage(GL_NONE),
mImmutable(false),
mTarget(target)
......@@ -34,6 +58,7 @@ Texture::Texture(GLuint id, GLenum target)
Texture::~Texture()
{
SafeDelete(mTexture);
}
GLenum Texture::getTarget() const
......@@ -89,12 +114,6 @@ GLenum Texture::getBaseLevelInternalFormat() const
return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
}
// Tests for texture sampling completeness
bool Texture::isSamplerComplete(const SamplerState &samplerState) const
{
return getImplementation()->isSamplerComplete(samplerState);
}
rx::TextureStorageInterface *Texture::getNativeTexture()
{
return getImplementation()->getNativeTexture();
......@@ -136,17 +155,14 @@ const rx::Image *Texture::getBaseLevelImage() const
return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
}
Texture2D::Texture2D(rx::Texture2DImpl *impl, GLuint id)
: Texture(id, GL_TEXTURE_2D),
mTexture(impl)
Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
: Texture(impl, id, GL_TEXTURE_2D)
{
mSurface = NULL;
}
Texture2D::~Texture2D()
{
SafeDelete(mTexture);
if (mSurface)
{
mSurface->setBoundTexture(NULL);
......@@ -245,6 +261,70 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
if (width <= 0 || height <= 0)
{
return false;
}
if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
{
return false;
}
bool npotSupport = extensions.textureNPOT;
if (!npotSupport)
{
if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
(samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
{
return false;
}
}
if (IsMipmapFiltered(samplerState))
{
if (!npotSupport)
{
if (!gl::isPow2(width) || !gl::isPow2(height))
{
return false;
}
}
if (!isMipmapComplete())
{
return false;
}
}
// OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
// The internalformat specified for the texture arrays is a sized internal depth or
// depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
// MODE is NONE, and either the magnification filter is not NEAREST or the mini-
// fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
if (formatInfo.depthBits > 0 && clientVersion > 2)
{
if (samplerState.compareMode == GL_NONE)
{
if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
samplerState.magFilter != GL_NEAREST)
{
return false;
}
}
}
return true;
}
bool Texture2D::isCompressed(GLint level) const
{
return GetInternalFormatInfo(getInternalFormat(level)).compressed;
......@@ -277,15 +357,73 @@ rx::RenderTarget *Texture2D::getDepthStencil(GLint level)
return mTexture->getDepthStencil(level, 0);
}
TextureCubeMap::TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id)
: Texture(id, GL_TEXTURE_CUBE_MAP),
mTexture(impl)
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool Texture2D::isMipmapComplete() const
{
int levelCount = mipLevels();
for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
}
bool Texture2D::isLevelComplete(int level) const
{
if (isImmutable())
{
return true;
}
const rx::Image *baseImage = getBaseLevelImage();
GLsizei width = baseImage->getWidth();
GLsizei height = baseImage->getHeight();
if (width <= 0 || height <= 0)
{
return false;
}
// The base image level is complete if the width and height are positive
if (level == 0)
{
return true;
}
ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
rx::Image *image = mTexture->getImage(level, 0);
if (image->getInternalFormat() != baseImage->getInternalFormat())
{
return false;
}
if (image->getWidth() != std::max(1, width >> level))
{
return false;
}
if (image->getHeight() != std::max(1, height >> level))
{
return false;
}
return true;
}
TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
: Texture(impl, id, GL_TEXTURE_CUBE_MAP)
{
}
TextureCubeMap::~TextureCubeMap()
{
SafeDelete(mTexture);
}
GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
......@@ -368,7 +506,28 @@ void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffse
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureCubeMap::isCubeComplete() const
{
return mTexture->isCubeComplete();
int baseWidth = getBaseLevelWidth();
int baseHeight = getBaseLevelHeight();
GLenum baseFormat = getBaseLevelInternalFormat();
if (baseWidth <= 0 || baseWidth != baseHeight)
{
return false;
}
for (int faceIndex = 1; faceIndex < 6; faceIndex++)
{
const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
if (faceBaseImage->getWidth() != baseWidth ||
faceBaseImage->getHeight() != baseHeight ||
faceBaseImage->getInternalFormat() != baseFormat )
{
return false;
}
}
return true;
}
bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
......@@ -393,6 +552,44 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
}
// Tests for texture sampling completeness
bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
int size = getBaseLevelWidth();
bool mipmapping = IsMipmapFiltered(samplerState);
if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
{
return false;
}
if (!gl::isPow2(size) && !extensions.textureNPOT)
{
if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
{
return false;
}
}
if (!mipmapping)
{
if (!isCubeComplete())
{
return false;
}
}
else
{
if (!isMipmapComplete()) // Also tests for isCubeComplete()
{
return false;
}
}
return true;
}
unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
{
return mTexture->getRenderTargetSerial(level, targetToLayerIndex(target));
......@@ -430,15 +627,82 @@ rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
return mTexture->getDepthStencil(level, targetToLayerIndex(target));
}
Texture3D::Texture3D(rx::Texture3DImpl *impl, GLuint id)
: Texture(id, GL_TEXTURE_3D),
mTexture(impl)
bool TextureCubeMap::isMipmapComplete() const
{
if (isImmutable())
{
return true;
}
if (!isCubeComplete())
{
return false;
}
int levelCount = mipLevels();
for (int face = 0; face < 6; face++)
{
for (int level = 1; level < levelCount; level++)
{
if (!isFaceLevelComplete(face, level))
{
return false;
}
}
}
return true;
}
bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
{
ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
if (isImmutable())
{
return true;
}
int baseSize = getBaseLevelWidth();
if (baseSize <= 0)
{
return false;
}
// "isCubeComplete" checks for base level completeness and we must call that
// to determine if any face at level 0 is complete. We omit that check here
// to avoid re-checking cube-completeness for every face at level 0.
if (level == 0)
{
return true;
}
// Check that non-zero levels are consistent with the base level.
const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
{
return false;
}
if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
{
return false;
}
return true;
}
Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
: Texture(impl, id, GL_TEXTURE_3D)
{
}
Texture3D::~Texture3D()
{
SafeDelete(mTexture);
}
GLsizei Texture3D::getWidth(GLint level) const
......@@ -503,6 +767,30 @@ void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
}
bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
if (width <= 0 || height <= 0 || depth <= 0)
{
return false;
}
if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
{
return false;
}
if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
{
return false;
}
return true;
}
unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
{
return mTexture->getRenderTargetSerial(level, layer);
......@@ -519,15 +807,76 @@ rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer)
return mTexture->getDepthStencil(level, layer);
}
Texture2DArray::Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id)
: Texture(id, GL_TEXTURE_2D_ARRAY),
mTexture(impl)
bool Texture3D::isMipmapComplete() const
{
int levelCount = mipLevels();
for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
}
bool Texture3D::isLevelComplete(int level) const
{
ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
if (isImmutable())
{
return true;
}
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
if (width <= 0 || height <= 0 || depth <= 0)
{
return false;
}
if (level == 0)
{
return true;
}
rx::Image *levelImage = mTexture->getImage(level, 0);
if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
{
return false;
}
if (levelImage->getWidth() != std::max(1, width >> level))
{
return false;
}
if (levelImage->getHeight() != std::max(1, height >> level))
{
return false;
}
if (levelImage->getDepth() != std::max(1, depth >> level))
{
return false;
}
return true;
}
Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
: Texture(impl, id, GL_TEXTURE_2D_ARRAY)
{
}
Texture2DArray::~Texture2DArray()
{
SafeDelete(mTexture);
}
GLsizei Texture2DArray::getWidth(GLint level) const
......@@ -592,6 +941,30 @@ void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei widt
mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
}
bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getLayers(0);
if (width <= 0 || height <= 0 || depth <= 0)
{
return false;
}
if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
{
return false;
}
if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
{
return false;
}
return true;
}
unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
{
return mTexture->getRenderTargetSerial(level, layer);
......@@ -607,4 +980,65 @@ rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer)
return mTexture->getDepthStencil(level, layer);
}
bool Texture2DArray::isMipmapComplete() const
{
int levelCount = mipLevels();
for (int level = 1; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
}
bool Texture2DArray::isLevelComplete(int level) const
{
ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (isImmutable())
{
return true;
}
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei layers = getLayers(0);
if (width <= 0 || height <= 0 || layers <= 0)
{
return false;
}
if (level == 0)
{
return true;
}
if (getInternalFormat(level) != getInternalFormat(0))
{
return false;
}
if (getWidth(level) != std::max(1, width >> level))
{
return false;
}
if (getHeight(level) != std::max(1, height >> level))
{
return false;
}
if (getLayers(level) != layers)
{
return false;
}
return true;
}
}
......@@ -20,6 +20,7 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/constants.h"
#include "libGLESv2/renderer/TextureImpl.h"
#include "libGLESv2/Caps.h"
namespace egl
{
......@@ -38,10 +39,12 @@ namespace gl
class Framebuffer;
class FramebufferAttachment;
bool IsMipmapFiltered(const gl::SamplerState &samplerState);
class Texture : public RefCountObject
{
public:
Texture(GLuint id, GLenum target);
Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
virtual ~Texture();
......@@ -59,7 +62,7 @@ class Texture : public RefCountObject
GLint getBaseLevelDepth() const;
GLenum getBaseLevelInternalFormat() const;
bool isSamplerComplete(const SamplerState &samplerState) const;
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
rx::TextureStorageInterface *getNativeTexture();
......@@ -71,14 +74,16 @@ class Texture : public RefCountObject
bool isImmutable() const;
int immutableLevelCount();
virtual rx::TextureImpl *getImplementation() = 0;
virtual const rx::TextureImpl *getImplementation() const = 0;
rx::TextureImpl *getImplementation() { return mTexture; }
const rx::TextureImpl *getImplementation() const { return mTexture; }
static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
protected:
int mipLevels() const;
rx::TextureImpl *mTexture;
SamplerState mSamplerState;
GLenum mUsage;
......@@ -86,18 +91,18 @@ class Texture : public RefCountObject
GLenum mTarget;
const rx::Image *getBaseLevelImage() const;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
const rx::Image *getBaseLevelImage() const;
};
class Texture2D : public Texture
{
public:
Texture2D(rx::Texture2DImpl *impl, GLuint id);
Texture2D(rx::TextureImpl *impl, GLuint id);
~Texture2D();
virtual ~Texture2D();
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
......@@ -113,6 +118,7 @@ class Texture2D : public Texture
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
......@@ -120,9 +126,6 @@ class Texture2D : public Texture
unsigned int getRenderTargetSerial(GLint level);
virtual rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
protected:
friend class Texture2DAttachment;
rx::RenderTarget *getRenderTarget(GLint level);
......@@ -131,16 +134,18 @@ class Texture2D : public Texture
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
rx::Texture2DImpl *mTexture;
bool isMipmapComplete() const;
bool isLevelComplete(int level) const;
egl::Surface *mSurface;
};
class TextureCubeMap : public Texture
{
public:
TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id);
TextureCubeMap(rx::TextureImpl *impl, GLuint id);
~TextureCubeMap();
virtual ~TextureCubeMap();
GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const;
......@@ -163,6 +168,8 @@ class TextureCubeMap : public Texture
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei size);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
bool isCubeComplete() const;
unsigned int getRenderTargetSerial(GLenum target, GLint level);
......@@ -170,9 +177,6 @@ class TextureCubeMap : public Texture
static int targetToLayerIndex(GLenum target);
static GLenum layerIndexToTarget(GLint layer);
virtual rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
protected:
friend class TextureCubeMapAttachment;
rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
......@@ -181,15 +185,16 @@ class TextureCubeMap : public Texture
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
rx::TextureCubeImpl *mTexture;
bool isMipmapComplete() const;
bool isFaceLevelComplete(int faceIndex, int level) const;
};
class Texture3D : public Texture
{
public:
Texture3D(rx::Texture3DImpl *impl, GLuint id);
Texture3D(rx::TextureImpl *impl, GLuint id);
~Texture3D();
virtual ~Texture3D();
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
......@@ -205,10 +210,9 @@ class Texture3D : public Texture
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
unsigned int getRenderTargetSerial(GLint level, GLint layer);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
virtual rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
unsigned int getRenderTargetSerial(GLint level, GLint layer);
protected:
friend class Texture3DAttachment;
......@@ -218,15 +222,16 @@ class Texture3D : public Texture
private:
DISALLOW_COPY_AND_ASSIGN(Texture3D);
rx::Texture3DImpl *mTexture;
bool isMipmapComplete() const;
bool isLevelComplete(int level) const;
};
class Texture2DArray : public Texture
{
public:
Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id);
Texture2DArray(rx::TextureImpl *impl, GLuint id);
~Texture2DArray();
virtual ~Texture2DArray();
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
......@@ -242,10 +247,9 @@ class Texture2DArray : public Texture
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
unsigned int getRenderTargetSerial(GLint level, GLint layer);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
virtual rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
unsigned int getRenderTargetSerial(GLint level, GLint layer);
protected:
friend class Texture2DArrayAttachment;
......@@ -255,7 +259,8 @@ class Texture2DArray : public Texture
private:
DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
rx::Texture2DArrayImpl *mTexture;
bool isMipmapComplete() const;
bool isLevelComplete(int level) const;
};
}
......
......@@ -57,10 +57,7 @@ class RenderTarget;
class Image;
class TextureStorage;
class UniformStorage;
class Texture2DImpl;
class TextureCubeImpl;
class Texture3DImpl;
class Texture2DArrayImpl;
class TextureImpl;
struct ConfigDesc
{
......@@ -224,10 +221,7 @@ class Renderer
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
// Texture creation
virtual Texture2DImpl *createTexture2D() = 0;
virtual TextureCubeImpl *createTextureCube() = 0;
virtual Texture3DImpl *createTexture3D() = 0;
virtual Texture2DArrayImpl *createTexture2DArray() = 0;
virtual TextureImpl *createTexture(GLenum target) = 0;
// Buffer creation
virtual BufferImpl *createBuffer() = 0;
......
......@@ -34,6 +34,8 @@ class TextureStorageInterface;
class TextureImpl
{
public:
virtual ~TextureImpl() {};
// TODO: If this methods could go away that would be ideal;
// TextureStorage should only be necessary for the D3D backend, and as such
// higher level code should not rely on it.
......@@ -42,12 +44,8 @@ class TextureImpl
virtual Image *getImage(int level, int layer) const = 0;
virtual GLsizei getLayerCount(int level) const = 0;
virtual bool hasDirtyImages() const = 0;
virtual void resetDirty() = 0;
virtual void setUsage(GLenum usage) = 0;
virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const = 0;
virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;
virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
......@@ -61,37 +59,11 @@ class TextureImpl
virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) = 0;
virtual RenderTarget *getRenderTarget(GLint level, GLint layer) = 0;
virtual RenderTarget *getDepthStencil(GLint level, GLint layer) = 0;
};
class Texture2DImpl : public TextureImpl
{
public:
virtual ~Texture2DImpl() {}
virtual void bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 0;
};
class TextureCubeImpl : public TextureImpl
{
public:
virtual ~TextureCubeImpl() {}
virtual bool isCubeComplete() const = 0;
};
class Texture3DImpl : public TextureImpl
{
public:
virtual ~Texture3DImpl() {}
};
class Texture2DArrayImpl : public TextureImpl
{
public:
virtual ~Texture2DArrayImpl() {}
};
}
#endif // LIBGLESV2_RENDERER_TEXTUREIMPL_H_
......@@ -25,23 +25,6 @@
namespace rx
{
bool IsMipmapFiltered(const gl::SamplerState &samplerState)
{
switch (samplerState.minFilter)
{
case GL_NEAREST:
case GL_LINEAR:
return false;
case GL_NEAREST_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
return true;
default: UNREACHABLE();
return false;
}
}
bool IsRenderTargetUsage(GLenum usage)
{
return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
......@@ -59,6 +42,26 @@ TextureD3D::~TextureD3D()
{
}
TextureD3D *TextureD3D::makeTextureD3D(TextureImpl *texture)
{
ASSERT(HAS_DYNAMIC_TYPE(TextureD3D*, texture));
return static_cast<TextureD3D*>(texture);
}
TextureStorageInterface *TextureD3D::getNativeTexture()
{
// ensure the underlying texture is created
initializeStorage(false);
TextureStorageInterface *storage = getBaseLevelStorage();
if (storage)
{
updateStorage();
}
return storage;
}
GLint TextureD3D::getBaseLevelWidth() const
{
const Image *baseImage = getBaseLevelImage();
......@@ -206,7 +209,6 @@ int TextureD3D::mipLevels() const
TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
: TextureD3D(renderer),
Texture2DImpl(),
mTexStorage(NULL)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
......@@ -225,26 +227,6 @@ TextureD3D_2D::~TextureD3D_2D()
}
}
TextureD3D_2D *TextureD3D_2D::makeTextureD3D_2D(Texture2DImpl *texture)
{
ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_2D*, texture));
return static_cast<TextureD3D_2D*>(texture);
}
TextureStorageInterface *TextureD3D_2D::getNativeTexture()
{
// ensure the underlying texture is created
initializeStorage(false);
TextureStorageInterface *storage = getBaseLevelStorage();
if (storage)
{
updateStorage();
}
return storage;
}
Image *TextureD3D_2D::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
......@@ -458,75 +440,6 @@ void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat
setCompleteTexStorage(new TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels));
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
bool TextureD3D_2D::isSamplerComplete(const gl::SamplerState &samplerState) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
if (width <= 0 || height <= 0)
{
return false;
}
if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0)).filterable)
{
if (samplerState.magFilter != GL_NEAREST ||
(samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
// TODO(geofflang): use context's extensions
bool npotSupport = mRenderer->getRendererExtensions().textureNPOT;
if (!npotSupport)
{
if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
(samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
{
return false;
}
}
if (IsMipmapFiltered(samplerState))
{
if (!npotSupport)
{
if (!gl::isPow2(width) || !gl::isPow2(height))
{
return false;
}
}
if (!isMipmapComplete())
{
return false;
}
}
// OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
// The internalformat specified for the texture arrays is a sized internal depth or
// depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
// MODE is NONE, and either the magnification filter is not NEAREST or the mini-
// fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
if (formatInfo.depthBits > 0 && mRenderer->getCurrentClientVersion() > 2)
{
if (samplerState.compareMode == GL_NONE)
{
if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
samplerState.magFilter != GL_NEAREST)
{
return false;
}
}
}
return true;
}
void TextureD3D_2D::bindTexImage(egl::Surface *surface)
{
GLenum internalformat = surface->getFormat();
......@@ -632,22 +545,6 @@ RenderTarget *TextureD3D_2D::getDepthStencil(GLint level, GLint layer)
return mTexStorage->getRenderTarget(level);
}
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureD3D_2D::isMipmapComplete() const
{
int levelCount = mipLevels();
for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
}
bool TextureD3D_2D::isValidLevel(int level) const
{
return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
......@@ -851,8 +748,7 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize
TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
: TextureCubeImpl(),
TextureD3D(renderer),
: TextureD3D(renderer),
mTexStorage(NULL)
{
for (int i = 0; i < 6; i++)
......@@ -877,26 +773,6 @@ TextureD3D_Cube::~TextureD3D_Cube()
}
}
TextureD3D_Cube *TextureD3D_Cube::makeTextureD3D_Cube(TextureCubeImpl *texture)
{
ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_Cube*, texture));
return static_cast<TextureD3D_Cube*>(texture);
}
TextureStorageInterface *TextureD3D_Cube::getNativeTexture()
{
// ensure the underlying texture is created
initializeStorage(false);
TextureStorageInterface *storage = getBaseLevelStorage();
if (storage)
{
updateStorage();
}
return storage;
}
Image *TextureD3D_Cube::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
......@@ -1064,49 +940,6 @@ void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalform
setCompleteTexStorage(new TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, levels));
}
bool TextureD3D_Cube::isSamplerComplete(const gl::SamplerState &samplerState) const
{
int size = getBaseLevelWidth();
bool mipmapping = IsMipmapFiltered(samplerState);
// TODO(geofflang): use context's texture caps
if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0, 0)).filterable)
{
if (samplerState.magFilter != GL_NEAREST ||
(samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
// TODO(geofflang): use context's extensions
if (!gl::isPow2(size) && !mRenderer->getRendererExtensions().textureNPOT)
{
if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
{
return false;
}
}
if (!mipmapping)
{
if (!isCubeComplete())
{
return false;
}
}
else
{
if (!isMipmapCubeComplete()) // Also tests for isCubeComplete()
{
return false;
}
}
return true;
}
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureD3D_Cube::isCubeComplete() const
{
......@@ -1134,6 +967,17 @@ bool TextureD3D_Cube::isCubeComplete() const
return true;
}
void TextureD3D_Cube::bindTexImage(egl::Surface *surface)
{
UNREACHABLE();
}
void TextureD3D_Cube::releaseTexImage()
{
UNREACHABLE();
}
void TextureD3D_Cube::generateMipmaps()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
......@@ -1327,40 +1171,11 @@ const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const
return mImageArray[0][0];
}
bool TextureD3D_Cube::isMipmapCubeComplete() const
{
if (isImmutable())
{
return true;
}
if (!isCubeComplete())
{
return false;
}
int levelCount = mipLevels();
for (int face = 0; face < 6; face++)
{
for (int level = 1; level < levelCount; level++)
{
if (!isFaceLevelComplete(face, level))
{
return false;
}
}
}
return true;
}
bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
{
return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
}
bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
{
ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
......@@ -1457,8 +1272,7 @@ void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLin
TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
: Texture3DImpl(),
TextureD3D(renderer),
: TextureD3D(renderer),
mTexStorage(NULL)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
......@@ -1477,26 +1291,6 @@ TextureD3D_3D::~TextureD3D_3D()
}
}
TextureD3D_3D *TextureD3D_3D::makeTextureD3D_3D(Texture3DImpl *texture)
{
ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_3D*, texture));
return static_cast<TextureD3D_3D*>(texture);
}
TextureStorageInterface *TextureD3D_3D::getNativeTexture()
{
// ensure the underlying texture is created
initializeStorage(false);
TextureStorageInterface *storage = getBaseLevelStorage();
if (storage)
{
updateStorage();
}
return storage;
}
Image *TextureD3D_3D::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
......@@ -1686,50 +1480,17 @@ void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat
setCompleteTexStorage(new TextureStorageInterface3D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
}
bool TextureD3D_3D::isSamplerComplete(const gl::SamplerState &samplerState) const
void TextureD3D_3D::bindTexImage(egl::Surface *surface)
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
if (width <= 0 || height <= 0 || depth <= 0)
{
return false;
}
// TODO(geofflang): use context's texture caps
if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0)).filterable)
{
if (samplerState.magFilter != GL_NEAREST ||
(samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
{
return false;
}
return true;
UNREACHABLE();
}
bool TextureD3D_3D::isMipmapComplete() const
void TextureD3D_3D::releaseTexImage()
{
int levelCount = mipLevels();
for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
UNREACHABLE();
}
void TextureD3D_3D::generateMipmaps()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
......@@ -2025,8 +1786,7 @@ void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint
TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
: Texture2DArrayImpl(),
TextureD3D(renderer),
: TextureD3D(renderer),
mTexStorage(NULL)
{
for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
......@@ -2043,26 +1803,6 @@ TextureD3D_2DArray::~TextureD3D_2DArray()
deleteImages();
}
TextureD3D_2DArray *TextureD3D_2DArray::makeTextureD3D_2DArray(Texture2DArrayImpl *texture)
{
ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_2DArray*, texture));
return static_cast<TextureD3D_2DArray*>(texture);
}
TextureStorageInterface *TextureD3D_2DArray::getNativeTexture()
{
// ensure the underlying texture is created
initializeStorage(false);
TextureStorageInterface *storage = getBaseLevelStorage();
if (storage)
{
updateStorage();
}
return storage;
}
Image *TextureD3D_2DArray::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
......@@ -2243,50 +1983,17 @@ void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalf
setCompleteTexStorage(new TextureStorageInterface2DArray(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
}
bool TextureD3D_2DArray::isSamplerComplete(const gl::SamplerState &samplerState) const
void TextureD3D_2DArray::bindTexImage(egl::Surface *surface)
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getLayers(0);
if (width <= 0 || height <= 0 || depth <= 0)
{
return false;
}
// TODO(geofflang): use context's texture caps
if (!mRenderer->getRendererTextureCaps().get(getBaseLevelInternalFormat()).filterable)
{
if (samplerState.magFilter != GL_NEAREST ||
(samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
{
return false;
}
return true;
UNREACHABLE();
}
bool TextureD3D_2DArray::isMipmapComplete() const
void TextureD3D_2DArray::releaseTexImage()
{
int levelCount = mipLevels();
for (int level = 1; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
UNREACHABLE();
}
void TextureD3D_2DArray::generateMipmaps()
{
int baseWidth = getBaseLevelWidth();
......
......@@ -30,14 +30,20 @@ class TextureStorageInterfaceCube;
class TextureStorageInterface3D;
class TextureStorageInterface2DArray;
bool IsMipmapFiltered(const gl::SamplerState &samplerState);
class TextureD3D
class TextureD3D : public TextureImpl
{
public:
TextureD3D(Renderer *renderer);
virtual ~TextureD3D();
static TextureD3D *makeTextureD3D(TextureImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual void setUsage(GLenum usage) { mUsage = usage; }
bool hasDirtyImages() const { return mDirtyImages; }
void resetDirty() { mDirtyImages = false; }
GLint getBaseLevelWidth() const;
GLint getBaseLevelHeight() const;
GLint getBaseLevelDepth() const;
......@@ -70,27 +76,22 @@ class TextureD3D
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D);
virtual void initializeStorage(bool renderTarget) = 0;
virtual void updateStorage() = 0;
virtual TextureStorageInterface *getBaseLevelStorage() = 0;
virtual const ImageD3D *getBaseLevelImage() const = 0;
};
class TextureD3D_2D : public Texture2DImpl, public TextureD3D
class TextureD3D_2D : public TextureD3D
{
public:
TextureD3D_2D(Renderer *renderer);
virtual ~TextureD3D_2D();
static TextureD3D_2D *makeTextureD3D_2D(Texture2DImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) const;
virtual bool hasDirtyImages() const { return mDirtyImages; }
virtual void resetDirty() { mDirtyImages = false; }
virtual void setUsage(GLenum usage) { mUsage = usage; }
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
......@@ -105,7 +106,6 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
......@@ -119,16 +119,15 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
void initializeStorage(bool renderTarget);
virtual void initializeStorage(bool renderTarget);
TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage);
void updateStorage();
virtual void updateStorage();
bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapComplete() const;
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
......@@ -141,16 +140,12 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
class TextureD3D_Cube : public TextureD3D
{
public:
TextureD3D_Cube(Renderer *renderer);
virtual ~TextureD3D_Cube();
static TextureD3D_Cube *makeTextureD3D_Cube(TextureCubeImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) const;
......@@ -169,8 +164,8 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
virtual bool isCubeComplete() const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
......@@ -182,18 +177,18 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
void initializeStorage(bool renderTarget);
virtual void initializeStorage(bool renderTarget);
TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage);
void updateStorage();
virtual void updateStorage();
bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapCubeComplete() const;
bool isValidFaceLevel(int faceIndex, int level) const;
bool isFaceLevelComplete(int faceIndex, int level) const;
bool isCubeComplete() const;
void updateStorageFaceLevel(int faceIndex, int level);
void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
......@@ -204,23 +199,15 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
TextureStorageInterfaceCube *mTexStorage;
};
class TextureD3D_3D : public Texture3DImpl, public TextureD3D
class TextureD3D_3D : public TextureD3D
{
public:
TextureD3D_3D(Renderer *renderer);
virtual ~TextureD3D_3D();
static TextureD3D_3D *makeTextureD3D_3D(Texture3DImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) const;
virtual bool hasDirtyImages() const { return mDirtyImages; }
virtual void resetDirty() { mDirtyImages = false; }
virtual void setUsage(GLenum usage) { mUsage = usage; }
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLsizei getDepth(GLint level) const;
......@@ -235,7 +222,8 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
......@@ -252,12 +240,11 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D
TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage);
void updateStorage();
virtual void updateStorage();
bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapComplete() const;
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
void updateStorageLevel(int level);
......@@ -270,23 +257,15 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D
TextureStorageInterface3D *mTexStorage;
};
class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D
class TextureD3D_2DArray : public TextureD3D
{
public:
TextureD3D_2DArray(Renderer *renderer);
virtual ~TextureD3D_2DArray();
static TextureD3D_2DArray *makeTextureD3D_2DArray(Texture2DArrayImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) const;
virtual bool hasDirtyImages() const { return mDirtyImages; }
virtual void resetDirty() { mDirtyImages = false; }
virtual void setUsage(GLenum usage) { mUsage = usage; }
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLsizei getLayers(GLint level) const;
......@@ -301,7 +280,8 @@ class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
......@@ -317,12 +297,11 @@ class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D
TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage);
void updateStorage();
virtual void updateStorage();
bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapComplete() const;
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
void updateStorageLevel(int level);
......
......@@ -473,7 +473,7 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur
if (texture)
{
TextureImpl* textureImpl = texture->getImplementation();
TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorageInterface *texStorage = textureImpl->getNativeTexture();
if (texStorage)
......@@ -2799,24 +2799,19 @@ TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, b
return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
}
Texture2DImpl *Renderer11::createTexture2D()
TextureImpl *Renderer11::createTexture(GLenum target)
{
return new TextureD3D_2D(this);
}
TextureCubeImpl *Renderer11::createTextureCube()
{
return new TextureD3D_Cube(this);
}
Texture3DImpl *Renderer11::createTexture3D()
{
return new TextureD3D_3D(this);
}
switch(target)
{
case GL_TEXTURE_2D: return new TextureD3D_2D(this);
case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
case GL_TEXTURE_3D: return new TextureD3D_3D(this);
case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
default:
UNREACHABLE();
}
Texture2DArrayImpl *Renderer11::createTexture2DArray()
{
return new TextureD3D_2DArray(this);
return NULL;
}
void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
......
......@@ -171,10 +171,7 @@ class Renderer11 : public Renderer
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
// Texture creation
virtual Texture2DImpl *createTexture2D();
virtual TextureCubeImpl *createTextureCube();
virtual Texture3DImpl *createTexture3D();
virtual Texture2DArrayImpl *createTexture2DArray();
virtual TextureImpl *createTexture(GLenum target);
// Buffer creation
virtual BufferImpl *createBuffer();
......
......@@ -196,7 +196,7 @@ UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
{
bool swizzleRequired = samplerState.swizzleRequired();
bool mipmapping = IsMipmapFiltered(samplerState);
bool mipmapping = gl::IsMipmapFiltered(samplerState);
unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
// Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0)
......
......@@ -661,7 +661,7 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture
if (texture)
{
TextureImpl* textureImpl = texture->getImplementation();
TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorageInterface *texStorage = textureImpl->getNativeTexture();
if (texStorage)
......@@ -3043,24 +3043,19 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo
return NULL;
}
Texture2DImpl *Renderer9::createTexture2D()
TextureImpl *Renderer9::createTexture(GLenum target)
{
return new TextureD3D_2D(this);
}
TextureCubeImpl *Renderer9::createTextureCube()
{
return new TextureD3D_Cube(this);
}
Texture3DImpl *Renderer9::createTexture3D()
{
return new TextureD3D_3D(this);
}
switch(target)
{
case GL_TEXTURE_2D: return new TextureD3D_2D(this);
case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
case GL_TEXTURE_3D: return new TextureD3D_3D(this);
case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
default:
UNREACHABLE();
}
Texture2DArrayImpl *Renderer9::createTexture2DArray()
{
return new TextureD3D_2DArray(this);
return NULL;
}
bool Renderer9::getLUID(LUID *adapterLuid) const
......
......@@ -173,10 +173,7 @@ class Renderer9 : public Renderer
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
// Texture creation
virtual Texture2DImpl *createTexture2D();
virtual TextureCubeImpl *createTextureCube();
virtual Texture3DImpl *createTexture3D();
virtual Texture2DArrayImpl *createTexture2DArray();
virtual TextureImpl *createTexture(GLenum target);
// Buffer creation
virtual BufferImpl *createBuffer();
......
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