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 ...@@ -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 // In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0. // objects all of whose names are 0.
mTexture2DZero.set(new Texture2D(mRenderer->createTexture2D(), 0)); mTexture2DZero.set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTextureCube(), 0)); mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
mTexture3DZero.set(new Texture3D(mRenderer->createTexture3D(), 0)); mTexture3DZero.set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture2DArray(), 0)); mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
bindVertexArray(0); bindVertexArray(0);
bindArrayBuffer(0); bindArrayBuffer(0);
...@@ -1501,7 +1501,7 @@ void Context::applyTextures(SamplerType shaderType, Texture *textures[], Texture ...@@ -1501,7 +1501,7 @@ void Context::applyTextures(SamplerType shaderType, Texture *textures[], Texture
if (texture) if (texture)
{ {
// TODO: std::binary_search may become unavailable using older versions of GCC // 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())) !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
{ {
mRenderer->setSamplerState(shaderType, samplerIndex, sampler); mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
...@@ -2118,7 +2118,7 @@ Texture *Context::getIncompleteTexture(TextureType type) ...@@ -2118,7 +2118,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_2D: 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); incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2d; t = incomplete2d;
} }
...@@ -2126,7 +2126,7 @@ Texture *Context::getIncompleteTexture(TextureType type) ...@@ -2126,7 +2126,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_CUBE: 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->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); incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
...@@ -2141,7 +2141,7 @@ Texture *Context::getIncompleteTexture(TextureType type) ...@@ -2141,7 +2141,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_3D: 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); incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete3d; t = incomplete3d;
...@@ -2150,7 +2150,7 @@ Texture *Context::getIncompleteTexture(TextureType type) ...@@ -2150,7 +2150,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_2D_ARRAY: 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); incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2darray; t = incomplete2darray;
......
...@@ -379,19 +379,19 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) ...@@ -379,19 +379,19 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
if (type == TEXTURE_2D) if (type == TEXTURE_2D)
{ {
textureObject = new Texture2D(mRenderer->createTexture2D(), texture); textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
} }
else if (type == TEXTURE_CUBE) 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) 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) else if (type == TEXTURE_2D_ARRAY)
{ {
textureObject = new Texture2DArray(mRenderer->createTexture2DArray(), texture); textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
} }
else else
{ {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libGLESv2/main.h" #include "libGLESv2/main.h"
#include "common/mathutil.h" #include "common/mathutil.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/formatutils.h" #include "libGLESv2/formatutils.h"
#include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/renderer/Image.h" #include "libGLESv2/renderer/Image.h"
...@@ -24,8 +25,31 @@ ...@@ -24,8 +25,31 @@
namespace gl 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), : RefCountObject(id),
mTexture(impl),
mUsage(GL_NONE), mUsage(GL_NONE),
mImmutable(false), mImmutable(false),
mTarget(target) mTarget(target)
...@@ -34,6 +58,7 @@ Texture::Texture(GLuint id, GLenum target) ...@@ -34,6 +58,7 @@ Texture::Texture(GLuint id, GLenum target)
Texture::~Texture() Texture::~Texture()
{ {
SafeDelete(mTexture);
} }
GLenum Texture::getTarget() const GLenum Texture::getTarget() const
...@@ -89,12 +114,6 @@ GLenum Texture::getBaseLevelInternalFormat() const ...@@ -89,12 +114,6 @@ GLenum Texture::getBaseLevelInternalFormat() const
return (baseImage ? baseImage->getInternalFormat() : GL_NONE); 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() rx::TextureStorageInterface *Texture::getNativeTexture()
{ {
return getImplementation()->getNativeTexture(); return getImplementation()->getNativeTexture();
...@@ -136,17 +155,14 @@ const rx::Image *Texture::getBaseLevelImage() const ...@@ -136,17 +155,14 @@ const rx::Image *Texture::getBaseLevelImage() const
return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL); return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
} }
Texture2D::Texture2D(rx::Texture2DImpl *impl, GLuint id) Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
: Texture(id, GL_TEXTURE_2D), : Texture(impl, id, GL_TEXTURE_2D)
mTexture(impl)
{ {
mSurface = NULL; mSurface = NULL;
} }
Texture2D::~Texture2D() Texture2D::~Texture2D()
{ {
SafeDelete(mTexture);
if (mSurface) if (mSurface)
{ {
mSurface->setBoundTexture(NULL); mSurface->setBoundTexture(NULL);
...@@ -245,6 +261,70 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL ...@@ -245,6 +261,70 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1); 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 bool Texture2D::isCompressed(GLint level) const
{ {
return GetInternalFormatInfo(getInternalFormat(level)).compressed; return GetInternalFormatInfo(getInternalFormat(level)).compressed;
...@@ -277,15 +357,73 @@ rx::RenderTarget *Texture2D::getDepthStencil(GLint level) ...@@ -277,15 +357,73 @@ rx::RenderTarget *Texture2D::getDepthStencil(GLint level)
return mTexture->getDepthStencil(level, 0); return mTexture->getDepthStencil(level, 0);
} }
TextureCubeMap::TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id) // Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
: Texture(id, GL_TEXTURE_CUBE_MAP), bool Texture2D::isMipmapComplete() const
mTexture(impl) {
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() TextureCubeMap::~TextureCubeMap()
{ {
SafeDelete(mTexture);
} }
GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
...@@ -368,7 +506,28 @@ void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffse ...@@ -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. // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureCubeMap::isCubeComplete() const 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 bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
...@@ -393,6 +552,44 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size ...@@ -393,6 +552,44 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1); 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) unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
{ {
return mTexture->getRenderTargetSerial(level, targetToLayerIndex(target)); return mTexture->getRenderTargetSerial(level, targetToLayerIndex(target));
...@@ -430,15 +627,82 @@ rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level) ...@@ -430,15 +627,82 @@ rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
return mTexture->getDepthStencil(level, targetToLayerIndex(target)); return mTexture->getDepthStencil(level, targetToLayerIndex(target));
} }
Texture3D::Texture3D(rx::Texture3DImpl *impl, GLuint id) bool TextureCubeMap::isMipmapComplete() const
: Texture(id, GL_TEXTURE_3D), {
mTexture(impl) 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() Texture3D::~Texture3D()
{ {
SafeDelete(mTexture);
} }
GLsizei Texture3D::getWidth(GLint level) const GLsizei Texture3D::getWidth(GLint level) const
...@@ -503,6 +767,30 @@ void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL ...@@ -503,6 +767,30 @@ void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth); 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) unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
{ {
return mTexture->getRenderTargetSerial(level, layer); return mTexture->getRenderTargetSerial(level, layer);
...@@ -519,15 +807,76 @@ rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer) ...@@ -519,15 +807,76 @@ rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer)
return mTexture->getDepthStencil(level, layer); return mTexture->getDepthStencil(level, layer);
} }
Texture2DArray::Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id) bool Texture3D::isMipmapComplete() const
: Texture(id, GL_TEXTURE_2D_ARRAY), {
mTexture(impl) 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() Texture2DArray::~Texture2DArray()
{ {
SafeDelete(mTexture);
} }
GLsizei Texture2DArray::getWidth(GLint level) const GLsizei Texture2DArray::getWidth(GLint level) const
...@@ -592,6 +941,30 @@ void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei widt ...@@ -592,6 +941,30 @@ void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei widt
mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth); 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) unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
{ {
return mTexture->getRenderTargetSerial(level, layer); return mTexture->getRenderTargetSerial(level, layer);
...@@ -607,4 +980,65 @@ rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer) ...@@ -607,4 +980,65 @@ rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer)
return mTexture->getDepthStencil(level, 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 @@ ...@@ -20,6 +20,7 @@
#include "libGLESv2/angletypes.h" #include "libGLESv2/angletypes.h"
#include "libGLESv2/constants.h" #include "libGLESv2/constants.h"
#include "libGLESv2/renderer/TextureImpl.h" #include "libGLESv2/renderer/TextureImpl.h"
#include "libGLESv2/Caps.h"
namespace egl namespace egl
{ {
...@@ -38,10 +39,12 @@ namespace gl ...@@ -38,10 +39,12 @@ namespace gl
class Framebuffer; class Framebuffer;
class FramebufferAttachment; class FramebufferAttachment;
bool IsMipmapFiltered(const gl::SamplerState &samplerState);
class Texture : public RefCountObject class Texture : public RefCountObject
{ {
public: public:
Texture(GLuint id, GLenum target); Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
virtual ~Texture(); virtual ~Texture();
...@@ -59,7 +62,7 @@ class Texture : public RefCountObject ...@@ -59,7 +62,7 @@ class Texture : public RefCountObject
GLint getBaseLevelDepth() const; GLint getBaseLevelDepth() const;
GLenum getBaseLevelInternalFormat() 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(); rx::TextureStorageInterface *getNativeTexture();
...@@ -71,14 +74,16 @@ class Texture : public RefCountObject ...@@ -71,14 +74,16 @@ class Texture : public RefCountObject
bool isImmutable() const; bool isImmutable() const;
int immutableLevelCount(); int immutableLevelCount();
virtual rx::TextureImpl *getImplementation() = 0; rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const = 0; 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. 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: protected:
int mipLevels() const; int mipLevels() const;
rx::TextureImpl *mTexture;
SamplerState mSamplerState; SamplerState mSamplerState;
GLenum mUsage; GLenum mUsage;
...@@ -86,18 +91,18 @@ class Texture : public RefCountObject ...@@ -86,18 +91,18 @@ class Texture : public RefCountObject
GLenum mTarget; GLenum mTarget;
const rx::Image *getBaseLevelImage() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture); DISALLOW_COPY_AND_ASSIGN(Texture);
const rx::Image *getBaseLevelImage() const;
}; };
class Texture2D : public Texture class Texture2D : public Texture
{ {
public: public:
Texture2D(rx::Texture2DImpl *impl, GLuint id); Texture2D(rx::TextureImpl *impl, GLuint id);
~Texture2D(); virtual ~Texture2D();
GLsizei getWidth(GLint level) const; GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
...@@ -113,6 +118,7 @@ class Texture2D : public Texture ...@@ -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 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); 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 bindTexImage(egl::Surface *surface);
virtual void releaseTexImage(); virtual void releaseTexImage();
...@@ -120,9 +126,6 @@ class Texture2D : public Texture ...@@ -120,9 +126,6 @@ class Texture2D : public Texture
unsigned int getRenderTargetSerial(GLint level); unsigned int getRenderTargetSerial(GLint level);
virtual rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
protected: protected:
friend class Texture2DAttachment; friend class Texture2DAttachment;
rx::RenderTarget *getRenderTarget(GLint level); rx::RenderTarget *getRenderTarget(GLint level);
...@@ -131,16 +134,18 @@ class Texture2D : public Texture ...@@ -131,16 +134,18 @@ class Texture2D : public Texture
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture2D); DISALLOW_COPY_AND_ASSIGN(Texture2D);
rx::Texture2DImpl *mTexture; bool isMipmapComplete() const;
bool isLevelComplete(int level) const;
egl::Surface *mSurface; egl::Surface *mSurface;
}; };
class TextureCubeMap : public Texture class TextureCubeMap : public Texture
{ {
public: public:
TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id); TextureCubeMap(rx::TextureImpl *impl, GLuint id);
~TextureCubeMap(); virtual ~TextureCubeMap();
GLsizei getWidth(GLenum target, GLint level) const; GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const; GLsizei getHeight(GLenum target, GLint level) const;
...@@ -163,6 +168,8 @@ class TextureCubeMap : public Texture ...@@ -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 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); 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; bool isCubeComplete() const;
unsigned int getRenderTargetSerial(GLenum target, GLint level); unsigned int getRenderTargetSerial(GLenum target, GLint level);
...@@ -170,9 +177,6 @@ class TextureCubeMap : public Texture ...@@ -170,9 +177,6 @@ class TextureCubeMap : public Texture
static int targetToLayerIndex(GLenum target); static int targetToLayerIndex(GLenum target);
static GLenum layerIndexToTarget(GLint layer); static GLenum layerIndexToTarget(GLint layer);
virtual rx::TextureImpl *getImplementation() { return mTexture; }
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
protected: protected:
friend class TextureCubeMapAttachment; friend class TextureCubeMapAttachment;
rx::RenderTarget *getRenderTarget(GLenum target, GLint level); rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
...@@ -181,15 +185,16 @@ class TextureCubeMap : public Texture ...@@ -181,15 +185,16 @@ class TextureCubeMap : public Texture
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
rx::TextureCubeImpl *mTexture; bool isMipmapComplete() const;
bool isFaceLevelComplete(int faceIndex, int level) const;
}; };
class Texture3D : public Texture class Texture3D : public Texture
{ {
public: public:
Texture3D(rx::Texture3DImpl *impl, GLuint id); Texture3D(rx::TextureImpl *impl, GLuint id);
~Texture3D(); virtual ~Texture3D();
GLsizei getWidth(GLint level) const; GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
...@@ -205,10 +210,9 @@ class Texture3D : public Texture ...@@ -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 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); 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; } unsigned int getRenderTargetSerial(GLint level, GLint layer);
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
protected: protected:
friend class Texture3DAttachment; friend class Texture3DAttachment;
...@@ -218,15 +222,16 @@ class Texture3D : public Texture ...@@ -218,15 +222,16 @@ class Texture3D : public Texture
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture3D); DISALLOW_COPY_AND_ASSIGN(Texture3D);
rx::Texture3DImpl *mTexture; bool isMipmapComplete() const;
bool isLevelComplete(int level) const;
}; };
class Texture2DArray : public Texture class Texture2DArray : public Texture
{ {
public: public:
Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id); Texture2DArray(rx::TextureImpl *impl, GLuint id);
~Texture2DArray(); virtual ~Texture2DArray();
GLsizei getWidth(GLint level) const; GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
...@@ -242,10 +247,9 @@ class Texture2DArray : public Texture ...@@ -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 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); 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; } unsigned int getRenderTargetSerial(GLint level, GLint layer);
virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
protected: protected:
friend class Texture2DArrayAttachment; friend class Texture2DArrayAttachment;
...@@ -255,7 +259,8 @@ class Texture2DArray : public Texture ...@@ -255,7 +259,8 @@ class Texture2DArray : public Texture
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture2DArray); DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
rx::Texture2DArrayImpl *mTexture; bool isMipmapComplete() const;
bool isLevelComplete(int level) const;
}; };
} }
......
...@@ -57,10 +57,7 @@ class RenderTarget; ...@@ -57,10 +57,7 @@ class RenderTarget;
class Image; class Image;
class TextureStorage; class TextureStorage;
class UniformStorage; class UniformStorage;
class Texture2DImpl; class TextureImpl;
class TextureCubeImpl;
class Texture3DImpl;
class Texture2DArrayImpl;
struct ConfigDesc struct ConfigDesc
{ {
...@@ -224,10 +221,7 @@ class Renderer ...@@ -224,10 +221,7 @@ class Renderer
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
// Texture creation // Texture creation
virtual Texture2DImpl *createTexture2D() = 0; virtual TextureImpl *createTexture(GLenum target) = 0;
virtual TextureCubeImpl *createTextureCube() = 0;
virtual Texture3DImpl *createTexture3D() = 0;
virtual Texture2DArrayImpl *createTexture2DArray() = 0;
// Buffer creation // Buffer creation
virtual BufferImpl *createBuffer() = 0; virtual BufferImpl *createBuffer() = 0;
......
...@@ -34,6 +34,8 @@ class TextureStorageInterface; ...@@ -34,6 +34,8 @@ class TextureStorageInterface;
class TextureImpl class TextureImpl
{ {
public: public:
virtual ~TextureImpl() {};
// TODO: If this methods could go away that would be ideal; // TODO: If this methods could go away that would be ideal;
// TextureStorage should only be necessary for the D3D backend, and as such // TextureStorage should only be necessary for the D3D backend, and as such
// higher level code should not rely on it. // higher level code should not rely on it.
...@@ -42,12 +44,8 @@ class TextureImpl ...@@ -42,12 +44,8 @@ class TextureImpl
virtual Image *getImage(int level, int layer) const = 0; virtual Image *getImage(int level, int layer) const = 0;
virtual GLsizei getLayerCount(int level) 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 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 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 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; 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 ...@@ -61,37 +59,11 @@ class TextureImpl
virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) = 0; virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) = 0;
virtual RenderTarget *getRenderTarget(GLint level, GLint layer) = 0; virtual RenderTarget *getRenderTarget(GLint level, GLint layer) = 0;
virtual RenderTarget *getDepthStencil(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 bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 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_ #endif // LIBGLESV2_RENDERER_TEXTUREIMPL_H_
...@@ -25,23 +25,6 @@ ...@@ -25,23 +25,6 @@
namespace rx 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) bool IsRenderTargetUsage(GLenum usage)
{ {
return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
...@@ -59,6 +42,26 @@ TextureD3D::~TextureD3D() ...@@ -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 GLint TextureD3D::getBaseLevelWidth() const
{ {
const Image *baseImage = getBaseLevelImage(); const Image *baseImage = getBaseLevelImage();
...@@ -206,7 +209,6 @@ int TextureD3D::mipLevels() const ...@@ -206,7 +209,6 @@ int TextureD3D::mipLevels() const
TextureD3D_2D::TextureD3D_2D(Renderer *renderer) TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
: TextureD3D(renderer), : TextureD3D(renderer),
Texture2DImpl(),
mTexStorage(NULL) mTexStorage(NULL)
{ {
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
...@@ -225,26 +227,6 @@ TextureD3D_2D::~TextureD3D_2D() ...@@ -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 Image *TextureD3D_2D::getImage(int level, int layer) const
{ {
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
...@@ -458,75 +440,6 @@ void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat ...@@ -458,75 +440,6 @@ void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat
setCompleteTexStorage(new TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels)); 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) void TextureD3D_2D::bindTexImage(egl::Surface *surface)
{ {
GLenum internalformat = surface->getFormat(); GLenum internalformat = surface->getFormat();
...@@ -632,22 +545,6 @@ RenderTarget *TextureD3D_2D::getDepthStencil(GLint level, GLint layer) ...@@ -632,22 +545,6 @@ RenderTarget *TextureD3D_2D::getDepthStencil(GLint level, GLint layer)
return mTexStorage->getRenderTarget(level); 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 bool TextureD3D_2D::isValidLevel(int level) const
{ {
return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false); return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
...@@ -851,8 +748,7 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize ...@@ -851,8 +748,7 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize
TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer) TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
: TextureCubeImpl(), : TextureD3D(renderer),
TextureD3D(renderer),
mTexStorage(NULL) mTexStorage(NULL)
{ {
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
...@@ -877,26 +773,6 @@ TextureD3D_Cube::~TextureD3D_Cube() ...@@ -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 Image *TextureD3D_Cube::getImage(int level, int layer) const
{ {
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
...@@ -1064,49 +940,6 @@ void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalform ...@@ -1064,49 +940,6 @@ void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalform
setCompleteTexStorage(new TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, levels)); 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. // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureD3D_Cube::isCubeComplete() const bool TextureD3D_Cube::isCubeComplete() const
{ {
...@@ -1134,6 +967,17 @@ bool TextureD3D_Cube::isCubeComplete() const ...@@ -1134,6 +967,17 @@ bool TextureD3D_Cube::isCubeComplete() const
return true; return true;
} }
void TextureD3D_Cube::bindTexImage(egl::Surface *surface)
{
UNREACHABLE();
}
void TextureD3D_Cube::releaseTexImage()
{
UNREACHABLE();
}
void TextureD3D_Cube::generateMipmaps() void TextureD3D_Cube::generateMipmaps()
{ {
// Purge array levels 1 through q and reset them to represent the generated mipmap levels. // 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 ...@@ -1327,40 +1171,11 @@ const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const
return mImageArray[0][0]; 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 bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
{ {
return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
} }
bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
{ {
ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); 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 ...@@ -1457,8 +1272,7 @@ void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLin
TextureD3D_3D::TextureD3D_3D(Renderer *renderer) TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
: Texture3DImpl(), : TextureD3D(renderer),
TextureD3D(renderer),
mTexStorage(NULL) mTexStorage(NULL)
{ {
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
...@@ -1477,26 +1291,6 @@ TextureD3D_3D::~TextureD3D_3D() ...@@ -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 Image *TextureD3D_3D::getImage(int level, int layer) const
{ {
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
...@@ -1686,50 +1480,17 @@ void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat ...@@ -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)); 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(); UNREACHABLE();
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;
} }
bool TextureD3D_3D::isMipmapComplete() const void TextureD3D_3D::releaseTexImage()
{ {
int levelCount = mipLevels(); UNREACHABLE();
for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
} }
void TextureD3D_3D::generateMipmaps() void TextureD3D_3D::generateMipmaps()
{ {
// Purge array levels 1 through q and reset them to represent the generated mipmap levels. // 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 ...@@ -2025,8 +1786,7 @@ void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint
TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer) TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
: Texture2DArrayImpl(), : TextureD3D(renderer),
TextureD3D(renderer),
mTexStorage(NULL) mTexStorage(NULL)
{ {
for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
...@@ -2043,26 +1803,6 @@ TextureD3D_2DArray::~TextureD3D_2DArray() ...@@ -2043,26 +1803,6 @@ TextureD3D_2DArray::~TextureD3D_2DArray()
deleteImages(); 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 Image *TextureD3D_2DArray::getImage(int level, int layer) const
{ {
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
...@@ -2243,50 +1983,17 @@ void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalf ...@@ -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)); 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(); UNREACHABLE();
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;
} }
bool TextureD3D_2DArray::isMipmapComplete() const void TextureD3D_2DArray::releaseTexImage()
{ {
int levelCount = mipLevels(); UNREACHABLE();
for (int level = 1; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
return false;
}
}
return true;
} }
void TextureD3D_2DArray::generateMipmaps() void TextureD3D_2DArray::generateMipmaps()
{ {
int baseWidth = getBaseLevelWidth(); int baseWidth = getBaseLevelWidth();
......
...@@ -30,14 +30,20 @@ class TextureStorageInterfaceCube; ...@@ -30,14 +30,20 @@ class TextureStorageInterfaceCube;
class TextureStorageInterface3D; class TextureStorageInterface3D;
class TextureStorageInterface2DArray; class TextureStorageInterface2DArray;
bool IsMipmapFiltered(const gl::SamplerState &samplerState); class TextureD3D : public TextureImpl
class TextureD3D
{ {
public: public:
TextureD3D(Renderer *renderer); TextureD3D(Renderer *renderer);
virtual ~TextureD3D(); 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 getBaseLevelWidth() const;
GLint getBaseLevelHeight() const; GLint getBaseLevelHeight() const;
GLint getBaseLevelDepth() const; GLint getBaseLevelDepth() const;
...@@ -70,27 +76,22 @@ class TextureD3D ...@@ -70,27 +76,22 @@ class TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D); DISALLOW_COPY_AND_ASSIGN(TextureD3D);
virtual void initializeStorage(bool renderTarget) = 0;
virtual void updateStorage() = 0;
virtual TextureStorageInterface *getBaseLevelStorage() = 0; virtual TextureStorageInterface *getBaseLevelStorage() = 0;
virtual const ImageD3D *getBaseLevelImage() const = 0; virtual const ImageD3D *getBaseLevelImage() const = 0;
}; };
class TextureD3D_2D : public Texture2DImpl, public TextureD3D class TextureD3D_2D : public TextureD3D
{ {
public: public:
TextureD3D_2D(Renderer *renderer); TextureD3D_2D(Renderer *renderer);
virtual ~TextureD3D_2D(); virtual ~TextureD3D_2D();
static TextureD3D_2D *makeTextureD3D_2D(Texture2DImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const; virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) 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 getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const; GLenum getInternalFormat(GLint level) const;
...@@ -105,7 +106,6 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D ...@@ -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 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 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 bindTexImage(egl::Surface *surface);
virtual void releaseTexImage(); virtual void releaseTexImage();
...@@ -119,16 +119,15 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D ...@@ -119,16 +119,15 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D); DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
void initializeStorage(bool renderTarget); virtual void initializeStorage(bool renderTarget);
TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const; TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage); void setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage);
void updateStorage(); virtual void updateStorage();
bool ensureRenderTarget(); bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage(); virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const; virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapComplete() const;
bool isValidLevel(int level) const; bool isValidLevel(int level) const;
bool isLevelComplete(int level) const; bool isLevelComplete(int level) const;
...@@ -141,16 +140,12 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D ...@@ -141,16 +140,12 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
}; };
class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D class TextureD3D_Cube : public TextureD3D
{ {
public: public:
TextureD3D_Cube(Renderer *renderer); TextureD3D_Cube(Renderer *renderer);
virtual ~TextureD3D_Cube(); virtual ~TextureD3D_Cube();
static TextureD3D_Cube *makeTextureD3D_Cube(TextureCubeImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const; virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) const; virtual GLsizei getLayerCount(int level) const;
...@@ -169,8 +164,8 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D ...@@ -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 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 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 bool isCubeComplete() const; virtual void releaseTexImage();
virtual void generateMipmaps(); virtual void generateMipmaps();
...@@ -182,18 +177,18 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D ...@@ -182,18 +177,18 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube); DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
void initializeStorage(bool renderTarget); virtual void initializeStorage(bool renderTarget);
TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const; TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage); void setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage);
void updateStorage(); virtual void updateStorage();
bool ensureRenderTarget(); bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage(); virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const; virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapCubeComplete() const;
bool isValidFaceLevel(int faceIndex, int level) const; bool isValidFaceLevel(int faceIndex, int level) const;
bool isFaceLevelComplete(int faceIndex, int level) const; bool isFaceLevelComplete(int faceIndex, int level) const;
bool isCubeComplete() const;
void updateStorageFaceLevel(int faceIndex, int level); void updateStorageFaceLevel(int faceIndex, int level);
void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height); void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
...@@ -204,23 +199,15 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D ...@@ -204,23 +199,15 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
TextureStorageInterfaceCube *mTexStorage; TextureStorageInterfaceCube *mTexStorage;
}; };
class TextureD3D_3D : public Texture3DImpl, public TextureD3D class TextureD3D_3D : public TextureD3D
{ {
public: public:
TextureD3D_3D(Renderer *renderer); TextureD3D_3D(Renderer *renderer);
virtual ~TextureD3D_3D(); virtual ~TextureD3D_3D();
static TextureD3D_3D *makeTextureD3D_3D(Texture3DImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const; virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) 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 getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
GLsizei getDepth(GLint level) const; GLsizei getDepth(GLint level) const;
...@@ -235,7 +222,8 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D ...@@ -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 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 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(); virtual void generateMipmaps();
...@@ -252,12 +240,11 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D ...@@ -252,12 +240,11 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D
TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const; TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage); void setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage);
void updateStorage(); virtual void updateStorage();
bool ensureRenderTarget(); bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage(); virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const; virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapComplete() const;
bool isValidLevel(int level) const; bool isValidLevel(int level) const;
bool isLevelComplete(int level) const; bool isLevelComplete(int level) const;
void updateStorageLevel(int level); void updateStorageLevel(int level);
...@@ -270,23 +257,15 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D ...@@ -270,23 +257,15 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D
TextureStorageInterface3D *mTexStorage; TextureStorageInterface3D *mTexStorage;
}; };
class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D class TextureD3D_2DArray : public TextureD3D
{ {
public: public:
TextureD3D_2DArray(Renderer *renderer); TextureD3D_2DArray(Renderer *renderer);
virtual ~TextureD3D_2DArray(); virtual ~TextureD3D_2DArray();
static TextureD3D_2DArray *makeTextureD3D_2DArray(Texture2DArrayImpl *texture);
virtual TextureStorageInterface *getNativeTexture();
virtual Image *getImage(int level, int layer) const; virtual Image *getImage(int level, int layer) const;
virtual GLsizei getLayerCount(int level) 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 getWidth(GLint level) const;
GLsizei getHeight(GLint level) const; GLsizei getHeight(GLint level) const;
GLsizei getLayers(GLint level) const; GLsizei getLayers(GLint level) const;
...@@ -301,7 +280,8 @@ class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D ...@@ -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 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 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(); virtual void generateMipmaps();
...@@ -317,12 +297,11 @@ class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D ...@@ -317,12 +297,11 @@ class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D
TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const; TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage); void setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage);
void updateStorage(); virtual void updateStorage();
bool ensureRenderTarget(); bool ensureRenderTarget();
virtual TextureStorageInterface *getBaseLevelStorage(); virtual TextureStorageInterface *getBaseLevelStorage();
virtual const ImageD3D *getBaseLevelImage() const; virtual const ImageD3D *getBaseLevelImage() const;
bool isMipmapComplete() const;
bool isValidLevel(int level) const; bool isValidLevel(int level) const;
bool isLevelComplete(int level) const; bool isLevelComplete(int level) const;
void updateStorageLevel(int level); void updateStorageLevel(int level);
......
...@@ -473,7 +473,7 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur ...@@ -473,7 +473,7 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur
if (texture) if (texture)
{ {
TextureImpl* textureImpl = texture->getImplementation(); TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorageInterface *texStorage = textureImpl->getNativeTexture(); TextureStorageInterface *texStorage = textureImpl->getNativeTexture();
if (texStorage) if (texStorage)
...@@ -2799,24 +2799,19 @@ TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, b ...@@ -2799,24 +2799,19 @@ 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);
} }
Texture2DImpl *Renderer11::createTexture2D() TextureImpl *Renderer11::createTexture(GLenum target)
{ {
return new TextureD3D_2D(this); switch(target)
} {
case GL_TEXTURE_2D: return new TextureD3D_2D(this);
TextureCubeImpl *Renderer11::createTextureCube() case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
{ case GL_TEXTURE_3D: return new TextureD3D_3D(this);
return new TextureD3D_Cube(this); case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
} default:
UNREACHABLE();
Texture3DImpl *Renderer11::createTexture3D() }
{
return new TextureD3D_3D(this);
}
Texture2DArrayImpl *Renderer11::createTexture2DArray() return NULL;
{
return new TextureD3D_2DArray(this);
} }
void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
......
...@@ -171,10 +171,7 @@ class Renderer11 : public Renderer ...@@ -171,10 +171,7 @@ class Renderer11 : public Renderer
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 Texture2DImpl *createTexture2D(); virtual TextureImpl *createTexture(GLenum target);
virtual TextureCubeImpl *createTextureCube();
virtual Texture3DImpl *createTexture3D();
virtual Texture2DArrayImpl *createTexture2DArray();
// Buffer creation // Buffer creation
virtual BufferImpl *createBuffer(); virtual BufferImpl *createBuffer();
......
...@@ -196,7 +196,7 @@ UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const ...@@ -196,7 +196,7 @@ UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState) ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
{ {
bool swizzleRequired = samplerState.swizzleRequired(); bool swizzleRequired = samplerState.swizzleRequired();
bool mipmapping = IsMipmapFiltered(samplerState); bool mipmapping = gl::IsMipmapFiltered(samplerState);
unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1; 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) // 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 ...@@ -661,7 +661,7 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture
if (texture) if (texture)
{ {
TextureImpl* textureImpl = texture->getImplementation(); TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorageInterface *texStorage = textureImpl->getNativeTexture(); TextureStorageInterface *texStorage = textureImpl->getNativeTexture();
if (texStorage) if (texStorage)
...@@ -3043,24 +3043,19 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo ...@@ -3043,24 +3043,19 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo
return NULL; return NULL;
} }
Texture2DImpl *Renderer9::createTexture2D() TextureImpl *Renderer9::createTexture(GLenum target)
{ {
return new TextureD3D_2D(this); switch(target)
} {
case GL_TEXTURE_2D: return new TextureD3D_2D(this);
TextureCubeImpl *Renderer9::createTextureCube() case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
{ case GL_TEXTURE_3D: return new TextureD3D_3D(this);
return new TextureD3D_Cube(this); case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
} default:
UNREACHABLE();
Texture3DImpl *Renderer9::createTexture3D() }
{
return new TextureD3D_3D(this);
}
Texture2DArrayImpl *Renderer9::createTexture2DArray() return NULL;
{
return new TextureD3D_2DArray(this);
} }
bool Renderer9::getLUID(LUID *adapterLuid) const bool Renderer9::getLUID(LUID *adapterLuid) const
......
...@@ -173,10 +173,7 @@ class Renderer9 : public Renderer ...@@ -173,10 +173,7 @@ class Renderer9 : public Renderer
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 Texture2DImpl *createTexture2D(); virtual TextureImpl *createTexture(GLenum target);
virtual TextureCubeImpl *createTextureCube();
virtual Texture3DImpl *createTexture3D();
virtual Texture2DArrayImpl *createTexture2DArray();
// Buffer creation // Buffer creation
virtual BufferImpl *createBuffer(); 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