зеркало из https://github.com/AvaloniaUI/angle.git
Add texture rectangle extension.
This is needed to support binding IOSurfaces to textures on OSX. This commit adds support in the API and tests, but didn't need to implement compiler changes as it already supported ARB_texture_rectangle. Implementation of CHROMIUM_opy_texture for rectangle texture and the spec are left for follow-up commits. Change-Id: I45c66be763a9d3f6f619640f9f95f39b05c70867 Reviewed-on: https://chromium-review.googlesource.com/559106 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
acd20b1ff9
Коммит
13c0dd4631
|
@ -537,6 +537,14 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum
|
|||
#endif
|
||||
#endif /* GL_ANGLE_multiview */
|
||||
|
||||
#ifndef GL_ANGLE_texture_rectangle
|
||||
#define GL_ANGLE_texture_rectangle 1
|
||||
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE 0x84F8
|
||||
#define GL_TEXTURE_RECTANGLE_ANGLE 0x84F5
|
||||
#define GL_TEXTURE_BINDING_RECTANGLE_ANGLE 0x84F6
|
||||
#define GL_SAMPLER_2D_RECT_ANGLE 0x8B63
|
||||
#endif /* GL_ANGLE_texture_rectangle */
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // INCLUDE_GLES2_GL2EXT_ANGLE_H_
|
||||
|
|
|
@ -16,9 +16,4 @@
|
|||
#include "GLES3/gl31.h"
|
||||
#include "GLES3/gl32.h"
|
||||
|
||||
// The following enum is used in ANGLE, but is from desktop GL
|
||||
#ifndef GL_SAMPLER_2D_RECT_ARB
|
||||
#define GL_SAMPLER_2D_RECT_ARB 0x8B63
|
||||
#endif
|
||||
|
||||
#endif // ANGLEGL_H_
|
||||
|
|
|
@ -124,6 +124,7 @@ GLenum VariableComponentType(GLenum type)
|
|||
return GL_FLOAT;
|
||||
case GL_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
|
@ -251,7 +252,7 @@ int VariableRowCount(GLenum type)
|
|||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_RECT_ARB:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
|
@ -321,7 +322,7 @@ int VariableColumnCount(GLenum type)
|
|||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_RECT_ARB:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
|
@ -385,6 +386,7 @@ bool IsSamplerType(GLenum type)
|
|||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
|
@ -471,6 +473,9 @@ GLenum SamplerTypeToTextureType(GLenum samplerType)
|
|||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
return GL_TEXTURE_2D_MULTISAMPLE;
|
||||
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
return GL_TEXTURE_RECTANGLE_ANGLE;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
|
@ -694,7 +699,7 @@ int VariableSortOrder(GLenum type)
|
|||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_RECT_ARB:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_3D:
|
||||
|
|
|
@ -332,7 +332,7 @@ GLenum GLVariableType(const TType &type)
|
|||
case EbtSamplerExternal2DY2YEXT:
|
||||
return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
|
||||
case EbtSampler2DRect:
|
||||
return GL_SAMPLER_2D_RECT_ARB;
|
||||
return GL_SAMPLER_2D_RECT_ANGLE;
|
||||
case EbtSampler2DArray:
|
||||
return GL_SAMPLER_2D_ARRAY;
|
||||
case EbtSampler2DMS:
|
||||
|
|
|
@ -229,7 +229,8 @@ Extensions::Extensions()
|
|||
surfacelessContext(false),
|
||||
clientArrays(false),
|
||||
robustResourceInitialization(false),
|
||||
programCacheControl(false)
|
||||
programCacheControl(false),
|
||||
textureRectangle(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -699,6 +700,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
|
|||
map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
|
||||
map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
|
||||
map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControl);
|
||||
map["GL_ANGLE_texture_rectangle"] = enableableExtension(&Extensions::textureRectangle);
|
||||
// clang-format on
|
||||
|
||||
return map;
|
||||
|
@ -746,6 +748,7 @@ Caps::Caps()
|
|||
: maxElementIndex(0),
|
||||
max3DTextureSize(0),
|
||||
max2DTextureSize(0),
|
||||
maxRectangleTextureSize(0),
|
||||
maxArrayTextureLayers(0),
|
||||
maxLODBias(0),
|
||||
maxCubeMapTextureSize(0),
|
||||
|
|
|
@ -370,6 +370,9 @@ struct Extensions
|
|||
|
||||
// GL_ANGLE_program_cache_control
|
||||
bool programCacheControl;
|
||||
|
||||
// GL_ANGLE_texture_rectangle
|
||||
bool textureRectangle;
|
||||
};
|
||||
|
||||
struct ExtensionInfo
|
||||
|
@ -432,6 +435,7 @@ struct Caps
|
|||
GLuint64 maxElementIndex;
|
||||
GLuint max3DTextureSize;
|
||||
GLuint max2DTextureSize;
|
||||
GLuint maxRectangleTextureSize;
|
||||
GLuint maxArrayTextureLayers;
|
||||
GLfloat maxLODBias;
|
||||
GLuint maxCubeMapTextureSize;
|
||||
|
|
|
@ -72,6 +72,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
|
|||
mResources.OES_EGL_image_external = extensions.eglImageExternal;
|
||||
mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3;
|
||||
mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal;
|
||||
mResources.ARB_texture_rectangle = extensions.textureRectangle;
|
||||
// TODO: use shader precision caps to determine if high precision is supported?
|
||||
mResources.FragmentPrecisionHigh = 1;
|
||||
mResources.EXT_frag_depth = extensions.fragDepth;
|
||||
|
|
|
@ -334,6 +334,13 @@ Context::Context(rx::EGLImplFactory *implFactory,
|
|||
}
|
||||
}
|
||||
|
||||
if (mExtensions.textureRectangle)
|
||||
{
|
||||
Texture *zeroTextureRectangle =
|
||||
new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
|
||||
}
|
||||
|
||||
if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
|
||||
{
|
||||
Texture *zeroTextureExternal =
|
||||
|
@ -1422,6 +1429,9 @@ void Context::getIntegervImpl(GLenum pname, GLint *params)
|
|||
case GL_MAX_TEXTURE_SIZE:
|
||||
*params = mCaps.max2DTextureSize;
|
||||
break;
|
||||
case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
|
||||
*params = mCaps.maxRectangleTextureSize;
|
||||
break;
|
||||
case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
|
||||
*params = mCaps.maxCubeMapTextureSize;
|
||||
break;
|
||||
|
@ -3028,6 +3038,10 @@ void Context::framebufferTexture2D(GLenum target,
|
|||
{
|
||||
index = ImageIndex::Make2D(level);
|
||||
}
|
||||
else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
index = ImageIndex::MakeRectangle(level);
|
||||
}
|
||||
else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
|
||||
{
|
||||
ASSERT(level == 0);
|
||||
|
|
|
@ -229,6 +229,17 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign
|
|||
*numParams = 1;
|
||||
return true;
|
||||
}
|
||||
case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
|
||||
case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
|
||||
{
|
||||
if (!getExtensions().textureRectangle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*type = GL_INT;
|
||||
*numParams = 1;
|
||||
return true;
|
||||
}
|
||||
case GL_MAX_DRAW_BUFFERS_EXT:
|
||||
case GL_MAX_COLOR_ATTACHMENTS_EXT:
|
||||
{
|
||||
|
|
|
@ -38,6 +38,11 @@ ImageIndex ImageIndex::Make2D(GLint mipIndex)
|
|||
return ImageIndex(GL_TEXTURE_2D, mipIndex, ENTIRE_LEVEL);
|
||||
}
|
||||
|
||||
ImageIndex ImageIndex::MakeRectangle(GLint mipIndex)
|
||||
{
|
||||
return ImageIndex(GL_TEXTURE_RECTANGLE_ANGLE, mipIndex, ENTIRE_LEVEL);
|
||||
}
|
||||
|
||||
ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex)
|
||||
{
|
||||
ASSERT(gl::IsCubeMapTextureTarget(target));
|
||||
|
@ -112,6 +117,13 @@ ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
|
|||
nullptr);
|
||||
}
|
||||
|
||||
ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip)
|
||||
{
|
||||
return ImageIndexIterator(GL_TEXTURE_RECTANGLE_ANGLE, Range<GLint>(minMip, maxMip),
|
||||
Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
|
||||
{
|
||||
return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, Range<GLint>(minMip, maxMip), Range<GLint>(0, 6),
|
||||
|
|
|
@ -31,6 +31,7 @@ struct ImageIndex
|
|||
bool is3D() const;
|
||||
|
||||
static ImageIndex Make2D(GLint mipIndex);
|
||||
static ImageIndex MakeRectangle(GLint mipIndex);
|
||||
static ImageIndex MakeCube(GLenum target, GLint mipIndex);
|
||||
static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
|
||||
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
|
||||
|
@ -55,6 +56,7 @@ class ImageIndexIterator
|
|||
{
|
||||
public:
|
||||
static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
|
||||
static ImageIndexIterator MakeRectangle(GLint minMip, GLint maxMip);
|
||||
static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
|
||||
static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
|
||||
static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
|
||||
|
|
|
@ -150,6 +150,10 @@ void State::initialize(const Context *context,
|
|||
mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
|
||||
mImageUnits.resize(caps.maxImageUnits);
|
||||
}
|
||||
if (extensions.textureRectangle)
|
||||
{
|
||||
mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits);
|
||||
}
|
||||
if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
|
||||
{
|
||||
mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
|
||||
|
@ -1917,6 +1921,11 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
|
|||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
|
||||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
|
||||
GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_CUBE_MAP:
|
||||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params =
|
||||
|
|
|
@ -1158,7 +1158,7 @@ Error Texture::bindTexImageFromSurface(const Context *context, egl::Surface *sur
|
|||
mBoundSurface = surface;
|
||||
|
||||
// Set the image info to the size and format of the surface
|
||||
ASSERT(mState.mTarget == GL_TEXTURE_2D);
|
||||
ASSERT(mState.mTarget == GL_TEXTURE_2D || mState.mTarget == GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
Extents size(surface->getWidth(), surface->getHeight(), 1);
|
||||
ImageDesc desc(size, Format(surface->getConfig()->renderTargetFormat));
|
||||
mState.setImageDesc(mState.mTarget, 0, desc);
|
||||
|
@ -1173,7 +1173,7 @@ Error Texture::releaseTexImageFromSurface(const Context *context)
|
|||
ANGLE_TRY(mTexture->releaseTexImage(context));
|
||||
|
||||
// Erase the image info for level 0
|
||||
ASSERT(mState.mTarget == GL_TEXTURE_2D);
|
||||
ASSERT(mState.mTarget == GL_TEXTURE_2D || mState.mTarget == GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
mState.clearImageDesc(mState.mTarget, 0);
|
||||
mDirtyChannel.signal();
|
||||
return NoError();
|
||||
|
|
|
@ -48,7 +48,8 @@ void BindFramebufferAttachment(const FunctionsGL *functions,
|
|||
const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
|
||||
|
||||
if (texture->getTarget() == GL_TEXTURE_2D ||
|
||||
texture->getTarget() == GL_TEXTURE_2D_MULTISAMPLE)
|
||||
texture->getTarget() == GL_TEXTURE_2D_MULTISAMPLE ||
|
||||
texture->getTarget() == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint,
|
||||
texture->getTarget(), textureGL->getTextureID(),
|
||||
|
|
|
@ -171,6 +171,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
|
|||
ASSERT(extensions.maxViews >= 1u);
|
||||
|
||||
mTextures[GL_TEXTURE_2D].resize(rendererCaps.maxCombinedTextureImageUnits);
|
||||
mTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(rendererCaps.maxCombinedTextureImageUnits);
|
||||
mTextures[GL_TEXTURE_CUBE_MAP].resize(rendererCaps.maxCombinedTextureImageUnits);
|
||||
mTextures[GL_TEXTURE_2D_ARRAY].resize(rendererCaps.maxCombinedTextureImageUnits);
|
||||
mTextures[GL_TEXTURE_3D].resize(rendererCaps.maxCombinedTextureImageUnits);
|
||||
|
|
|
@ -41,7 +41,8 @@ size_t GetLevelInfoIndex(GLenum target, size_t level)
|
|||
|
||||
bool UseTexImage2D(GLenum textureType)
|
||||
{
|
||||
return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP;
|
||||
return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP ||
|
||||
textureType == GL_TEXTURE_RECTANGLE_ANGLE;
|
||||
}
|
||||
|
||||
bool UseTexImage3D(GLenum textureType)
|
||||
|
@ -811,7 +812,7 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
|
|||
std::max(size.height >> level, 1),
|
||||
1);
|
||||
|
||||
if (getTarget() == GL_TEXTURE_2D)
|
||||
if (getTarget() == GL_TEXTURE_2D || getTarget() == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
if (internalFormatInfo.compressed)
|
||||
{
|
||||
|
@ -989,7 +990,7 @@ gl::Error TextureGL::generateMipmap(const gl::Context *context)
|
|||
|
||||
gl::Error TextureGL::bindTexImage(const gl::Context *context, egl::Surface *surface)
|
||||
{
|
||||
ASSERT(getTarget() == GL_TEXTURE_2D);
|
||||
ASSERT(getTarget() == GL_TEXTURE_2D || getTarget() == GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
|
||||
// Make sure this texture is bound
|
||||
mStateManager->bindTexture(getTarget(), mTextureID);
|
||||
|
@ -1001,7 +1002,7 @@ gl::Error TextureGL::bindTexImage(const gl::Context *context, egl::Surface *surf
|
|||
gl::Error TextureGL::releaseTexImage(const gl::Context *context)
|
||||
{
|
||||
// Not all Surface implementations reset the size of mip 0 when releasing, do it manually
|
||||
ASSERT(getTarget() == GL_TEXTURE_2D);
|
||||
ASSERT(getTarget() == GL_TEXTURE_2D || getTarget() == GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
|
||||
mStateManager->bindTexture(getTarget(), mTextureID);
|
||||
if (UseTexImage2D(getTarget()))
|
||||
|
|
|
@ -1002,6 +1002,14 @@ void GenerateCaps(const FunctionsGL *functions,
|
|||
functions->hasGLESExtension("GL_ARB_invalidate_subdata");
|
||||
|
||||
extensions->translatedShaderSource = true;
|
||||
|
||||
if (functions->isAtLeastGL(gl::Version(3, 1)) ||
|
||||
functions->hasGLExtension("GL_ARB_texture_rectangle"))
|
||||
{
|
||||
extensions->textureRectangle = true;
|
||||
caps->maxRectangleTextureSize =
|
||||
QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE);
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
|
||||
|
|
|
@ -35,6 +35,9 @@ size_t GetMaximumMipLevel(const gl::Context *context, GLenum target)
|
|||
case GL_TEXTURE_2D:
|
||||
maxDimension = caps.max2DTextureSize;
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
maxDimension = caps.maxRectangleTextureSize;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
maxDimension = caps.maxCubeMapTextureSize;
|
||||
break;
|
||||
|
|
|
@ -257,7 +257,7 @@ bool ValidReadPixelsFormatType(ValidationContext *context,
|
|||
}
|
||||
|
||||
template <typename ParamType>
|
||||
bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool isExternalTextureTarget)
|
||||
bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
|
||||
{
|
||||
switch (ConvertToGLenum(params[0]))
|
||||
{
|
||||
|
@ -266,11 +266,11 @@ bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool isEx
|
|||
|
||||
case GL_REPEAT:
|
||||
case GL_MIRRORED_REPEAT:
|
||||
if (isExternalTextureTarget)
|
||||
if (restrictedWrapModes)
|
||||
{
|
||||
// OES_EGL_image_external specifies this error.
|
||||
// OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
|
||||
context->handleError(InvalidEnum()
|
||||
<< "external textures only support CLAMP_TO_EDGE wrap mode");
|
||||
<< "texture only support CLAMP_TO_EDGE wrap mode");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -284,9 +284,7 @@ bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool isEx
|
|||
}
|
||||
|
||||
template <typename ParamType>
|
||||
bool ValidateTextureMinFilterValue(Context *context,
|
||||
ParamType *params,
|
||||
bool isExternalTextureTarget)
|
||||
bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
|
||||
{
|
||||
switch (ConvertToGLenum(params[0]))
|
||||
{
|
||||
|
@ -298,11 +296,11 @@ bool ValidateTextureMinFilterValue(Context *context,
|
|||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
if (isExternalTextureTarget)
|
||||
if (restrictedMinFilter)
|
||||
{
|
||||
// OES_EGL_image_external specifies this error.
|
||||
context->handleError(
|
||||
InvalidEnum() << "external textures only support NEAREST and LINEAR filtering");
|
||||
context->handleError(InvalidEnum()
|
||||
<< "texture only support NEAREST and LINEAR filtering");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -861,6 +859,9 @@ bool ValidTextureTarget(const ValidationContext *context, GLenum target)
|
|||
case GL_TEXTURE_CUBE_MAP:
|
||||
return true;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return context->getExtensions().textureRectangle;
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
return (context->getClientMajorVersion() >= 3);
|
||||
|
@ -881,6 +882,9 @@ bool ValidTexture2DTarget(const ValidationContext *context, GLenum target)
|
|||
case GL_TEXTURE_CUBE_MAP:
|
||||
return true;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return context->getExtensions().textureRectangle;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -924,6 +928,8 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta
|
|||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
return true;
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return context->getExtensions().textureRectangle;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1023,6 +1029,8 @@ bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum tar
|
|||
case GL_TEXTURE_2D_ARRAY:
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
return true;
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return context->getExtensions().textureRectangle;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1095,6 +1103,8 @@ bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
|
|||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
maxDimension = caps.maxCubeMapTextureSize;
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return level == 0;
|
||||
case GL_TEXTURE_3D:
|
||||
maxDimension = caps.max3DTextureSize;
|
||||
break;
|
||||
|
@ -2494,6 +2504,14 @@ bool ValidateStateQuery(ValidationContext *context,
|
|||
case GL_TEXTURE_BINDING_2D_ARRAY:
|
||||
case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
|
||||
if (!context->getExtensions().textureRectangle)
|
||||
{
|
||||
context->handleError(InvalidEnum()
|
||||
<< "ANGLE_texture_rectangle extension not present");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_EXTERNAL_OES:
|
||||
if (!context->getExtensions().eglStreamConsumerExternal &&
|
||||
!context->getExtensions().eglImageExternal)
|
||||
|
@ -2676,6 +2694,10 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context,
|
|||
maxDimension = caps.maxCubeMapTextureSize;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
maxDimension = caps.maxRectangleTextureSize;
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
maxDimension = caps.max2DTextureSize;
|
||||
break;
|
||||
|
@ -5688,17 +5710,25 @@ bool ValidateTexParameterBase(Context *context,
|
|||
case GL_TEXTURE_WRAP_S:
|
||||
case GL_TEXTURE_WRAP_T:
|
||||
case GL_TEXTURE_WRAP_R:
|
||||
if (!ValidateTextureWrapModeValue(context, params, target == GL_TEXTURE_EXTERNAL_OES))
|
||||
{
|
||||
bool restrictedWrapModes =
|
||||
target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE;
|
||||
if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_MIN_FILTER:
|
||||
if (!ValidateTextureMinFilterValue(context, params, target == GL_TEXTURE_EXTERNAL_OES))
|
||||
{
|
||||
bool restrictedMinFilter =
|
||||
target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE;
|
||||
if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
|
@ -5793,6 +5823,12 @@ bool ValidateTexParameterBase(Context *context,
|
|||
<< "Base level must be 0 for multisampled textures.");
|
||||
return false;
|
||||
}
|
||||
if (target == GL_TEXTURE_RECTANGLE_ANGLE && static_cast<GLuint>(params[0]) != 0)
|
||||
{
|
||||
context->handleError(InvalidOperation()
|
||||
<< "Base level must be 0 for rectangle textures.");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_MAX_LEVEL:
|
||||
|
|
|
@ -314,8 +314,9 @@ bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, G
|
|||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
return textureType == GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
// TODO(geofflang): accept GL_TEXTURE_RECTANGLE_ARB if the texture_rectangle extension is
|
||||
// supported
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return textureType == GL_TEXTURE_RECTANGLE_ANGLE &&
|
||||
context->getExtensions().textureRectangle;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
@ -328,9 +329,8 @@ bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
|
|||
{
|
||||
case GL_TEXTURE_2D:
|
||||
return true;
|
||||
|
||||
// TODO(geofflang): accept GL_TEXTURE_RECTANGLE_ARB if the texture_rectangle extension is
|
||||
// supported
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
return context->getExtensions().textureRectangle;
|
||||
|
||||
// TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
|
||||
// supported
|
||||
|
@ -375,6 +375,15 @@ bool IsValidCopyTextureDestinationLevel(Context *context,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
ASSERT(level == 0);
|
||||
if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
|
||||
static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (IsCubeMapTextureTarget(target))
|
||||
{
|
||||
if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
|
||||
|
@ -1002,6 +1011,22 @@ bool ValidateES2TexImageParameters(Context *context,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
ASSERT(level == 0);
|
||||
if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
|
||||
static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
|
||||
{
|
||||
context->handleError(InvalidValue());
|
||||
return false;
|
||||
}
|
||||
if (isCompressed)
|
||||
{
|
||||
context->handleError(InvalidEnum()
|
||||
<< "Rectangle texture cannot have a compressed format.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (IsCubeMapTextureTarget(target))
|
||||
{
|
||||
if (!isSubImage && width != height)
|
||||
|
@ -1480,7 +1505,8 @@ bool ValidateES2TexStorageParameters(Context *context,
|
|||
GLsizei width,
|
||||
GLsizei height)
|
||||
{
|
||||
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
|
||||
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
|
||||
target != GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
context->handleError(InvalidEnum());
|
||||
return false;
|
||||
|
@ -1523,6 +1549,20 @@ bool ValidateES2TexStorageParameters(Context *context,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
|
||||
static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
|
||||
{
|
||||
context->handleError(InvalidValue());
|
||||
return false;
|
||||
}
|
||||
if (formatInfo.compressed)
|
||||
{
|
||||
context->handleError(InvalidEnum()
|
||||
<< "Rectangle texture cannot have a compressed format.");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
|
||||
static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
|
||||
|
@ -2601,6 +2641,12 @@ bool ValidateCompressedTexImage2D(Context *context,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (target == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2796,6 +2842,15 @@ bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
|
|||
case GL_TEXTURE_CUBE_MAP:
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
if (!context->getExtensions().textureRectangle)
|
||||
{
|
||||
context->handleError(InvalidEnum()
|
||||
<< "Context does not support GL_ANGLE_texture_rectangle");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
if (context->getClientMajorVersion() < 3)
|
||||
|
@ -5807,6 +5862,22 @@ bool ValidateFramebufferTexture2D(Context *context,
|
|||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
{
|
||||
if (level != 0)
|
||||
{
|
||||
context->handleError(InvalidValue());
|
||||
return false;
|
||||
}
|
||||
if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
context->handleError(InvalidOperation()
|
||||
<< "Textarget must match the texture target type.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
|
@ -5954,7 +6025,8 @@ bool ValidateGenerateMipmap(Context *context, GLenum target)
|
|||
(!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
|
||||
!isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
|
||||
{
|
||||
ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP);
|
||||
ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
|
||||
target == GL_TEXTURE_CUBE_MAP);
|
||||
ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -199,6 +199,22 @@ bool ValidateES3TexImageParametersBase(Context *context,
|
|||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
ASSERT(level == 0);
|
||||
if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
|
||||
static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
|
||||
{
|
||||
context->handleError(InvalidValue());
|
||||
return false;
|
||||
}
|
||||
if (isCompressed)
|
||||
{
|
||||
context->handleError(InvalidEnum()
|
||||
<< "Rectangle texture cannot have a compressed format.");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
|
@ -851,6 +867,17 @@ bool ValidateES3TexStorageParametersBase(Context *context,
|
|||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_RECTANGLE_ANGLE:
|
||||
{
|
||||
if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
|
||||
static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
|
||||
{
|
||||
context->handleError(InvalidValue());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
{
|
||||
if (width != height)
|
||||
|
@ -922,6 +949,12 @@ bool ValidateES3TexStorageParametersBase(Context *context,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (formatInfo.compressed && target == GL_TEXTURE_RECTANGLE_ANGLE)
|
||||
{
|
||||
context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
'<(angle_path)/src/tests/gl_tests/SwizzleTest.cpp',
|
||||
'<(angle_path)/src/tests/gl_tests/SyncQueriesTest.cpp',
|
||||
'<(angle_path)/src/tests/gl_tests/TextureMultisampleTest.cpp',
|
||||
'<(angle_path)/src/tests/gl_tests/TextureRectangleTest.cpp',
|
||||
'<(angle_path)/src/tests/gl_tests/TextureTest.cpp',
|
||||
'<(angle_path)/src/tests/gl_tests/TimerQueriesTest.cpp',
|
||||
'<(angle_path)/src/tests/gl_tests/TransformFeedbackTest.cpp',
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
'<(angle_path)/src/tests/angle_unittests_utils.h',
|
||||
'<(angle_path)/src/tests/compiler_tests/API_test.cpp',
|
||||
'<(angle_path)/src/tests/compiler_tests/AppendixALimitations_test.cpp',
|
||||
'<(angle_path)/src/tests/compiler_tests/ARB_texture_rectangle_test.cpp',
|
||||
'<(angle_path)/src/tests/compiler_tests/AtomicCounter_test.cpp',
|
||||
'<(angle_path)/src/tests/compiler_tests/BufferVariables_test.cpp',
|
||||
'<(angle_path)/src/tests/compiler_tests/CollectVariables_test.cpp',
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// ARB_texture_rectangle_test.cpp:
|
||||
// Test for the ARB_texture_rectangle extension
|
||||
//
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
#include "angle_gl.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "tests/test_utils/ShaderCompileTreeTest.h"
|
||||
|
||||
using namespace sh;
|
||||
|
||||
class ARBTextureRectangleTestNoExt : public ShaderCompileTreeTest
|
||||
{
|
||||
protected:
|
||||
::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
|
||||
ShShaderSpec getShaderSpec() const override { return SH_GLES3_SPEC; }
|
||||
};
|
||||
|
||||
class ARBTextureRectangleTest : public ARBTextureRectangleTestNoExt
|
||||
{
|
||||
protected:
|
||||
void initResources(ShBuiltInResources *resources) override
|
||||
{
|
||||
resources->ARB_texture_rectangle = 1;
|
||||
}
|
||||
};
|
||||
|
||||
// Check that new types and builtins are disallowed if the extension isn't present in the translator
|
||||
// resources
|
||||
TEST_F(ARBTextureRectangleTest, NewTypeAndBuiltinsWithoutTranslatorResourceExtension)
|
||||
{
|
||||
// The new builtins require Sampler2DRect so we can't test them independently.
|
||||
const std::string &shaderString =
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2DRect tex;\n"
|
||||
"void main() {\n"
|
||||
"}\n";
|
||||
ASSERT_TRUE(compile(shaderString));
|
||||
}
|
||||
|
||||
// Check that new types and builtins are usable even with the #extension directive
|
||||
// Issue #15 of ARB_texture_rectangle explains that the extension was specified before the
|
||||
// #extension mechanism was in place so it doesn't require explicit enabling.
|
||||
TEST_F(ARBTextureRectangleTest, NewTypeAndBuiltinsWithoutExtensionDirective)
|
||||
{
|
||||
const std::string &shaderString =
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2DRect tex;\n"
|
||||
"void main() {\n"
|
||||
" vec4 color = texture2DRect(tex, vec2(1.0));"
|
||||
" color = texture2DRectProj(tex, vec3(1.0));"
|
||||
" color = texture2DRectProj(tex, vec4(1.0));"
|
||||
"}\n";
|
||||
ASSERT_TRUE(compile(shaderString));
|
||||
}
|
||||
|
||||
// Test valid usage of the new types and builtins
|
||||
TEST_F(ARBTextureRectangleTest, NewTypeAndBuiltingsWithExtensionDirective)
|
||||
{
|
||||
const std::string &shaderString =
|
||||
"#extension GL_ARB_texture_rectangle : require\n"
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2DRect tex;\n"
|
||||
"void main() {\n"
|
||||
" vec4 color = texture2DRect(tex, vec2(1.0));"
|
||||
" color = texture2DRectProj(tex, vec3(1.0));"
|
||||
" color = texture2DRectProj(tex, vec4(1.0));"
|
||||
"}\n";
|
||||
ASSERT_TRUE(compile(shaderString));
|
||||
}
|
||||
|
||||
// Check that it is not possible to pass a sampler2DRect where sampler2D is expected, and vice versa
|
||||
TEST_F(ARBTextureRectangleTest, Rect2DVs2DMismatch)
|
||||
{
|
||||
const std::string &shaderString1 =
|
||||
"#extension GL_ARB_texture_rectangle : require\n"
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2DRect tex;\n"
|
||||
"void main() {\n"
|
||||
" vec4 color = texture2D(tex, vec2(1.0));"
|
||||
"}\n";
|
||||
ASSERT_FALSE(compile(shaderString1));
|
||||
|
||||
const std::string &shaderString2 =
|
||||
"#extension GL_ARB_texture_rectangle : require\n"
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"void main() {\n"
|
||||
" vec4 color = texture2DRect(tex, vec2(1.0));"
|
||||
"}\n";
|
||||
ASSERT_FALSE(compile(shaderString2));
|
||||
}
|
|
@ -28,7 +28,7 @@ static sh::GLenum types[] = {
|
|||
GL_SAMPLER_2D, // 15
|
||||
GL_SAMPLER_CUBE, // 16
|
||||
GL_SAMPLER_EXTERNAL_OES, // 17
|
||||
GL_SAMPLER_2D_RECT_ARB, // 18
|
||||
GL_SAMPLER_2D_RECT_ANGLE, // 18
|
||||
GL_UNSIGNED_INT, // 19
|
||||
GL_UNSIGNED_INT_VEC2, // 20
|
||||
GL_UNSIGNED_INT_VEC3, // 21
|
||||
|
|
|
@ -0,0 +1,398 @@
|
|||
//
|
||||
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// TextureRectangleTest: Tests of GL_ANGLE_texture_rectangle
|
||||
|
||||
#include "test_utils/ANGLETest.h"
|
||||
#include "test_utils/gl_raii.h"
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class TextureRectangleTest : public ANGLETest
|
||||
{
|
||||
protected:
|
||||
TextureRectangleTest()
|
||||
{
|
||||
setWindowWidth(64);
|
||||
setWindowHeight(64);
|
||||
setConfigRedBits(8);
|
||||
setConfigGreenBits(8);
|
||||
setConfigBlueBits(8);
|
||||
setConfigAlphaBits(8);
|
||||
}
|
||||
|
||||
bool checkExtensionSupported() const
|
||||
{
|
||||
if (!extensionEnabled("GL_ANGLE_texture_rectangle"))
|
||||
{
|
||||
std::cout << "Test skipped because GL_ANGLE_texture_rectangle is not available."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class TextureRectangleTestES3 : public TextureRectangleTest
|
||||
{
|
||||
};
|
||||
|
||||
class TextureRectangleTestES31 : public TextureRectangleTest
|
||||
{
|
||||
};
|
||||
|
||||
// Test using TexImage2D to define a rectangle texture
|
||||
TEST_P(TextureRectangleTest, TexImage2D)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
|
||||
// Defining level 0 is allowed
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Defining level other than 0 is not allowed
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
|
||||
GLint maxSize = 0;
|
||||
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE, &maxSize);
|
||||
|
||||
// Defining a texture of the max size is allowed
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, maxSize, maxSize, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Defining a texture of the max size is allowed
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, maxSize + 1, maxSize, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, maxSize, maxSize + 1, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// Test using CompressedTexImage2D cannot be used on a retangle texture
|
||||
TEST_P(TextureRectangleTest, CompressedTexImage2DDisallowed)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
|
||||
|
||||
const char data[128] = {0};
|
||||
|
||||
// Control case: 2D texture
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128,
|
||||
data);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Rectangle textures cannot be compressed
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
glCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16,
|
||||
16, 0, 128, data);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
|
||||
// Test using TexStorage2D to define a rectangle texture
|
||||
TEST_P(TextureRectangleTest, TexStorage2D)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"));
|
||||
|
||||
bool useES3 = getClientMajorVersion() >= 3;
|
||||
auto TexStorage2D = [useES3](GLenum target, GLint levels, GLenum format, GLint width,
|
||||
GLint height) {
|
||||
if (useES3)
|
||||
{
|
||||
glTexStorage2D(target, levels, format, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexStorage2DEXT(target, levels, format, width, height);
|
||||
}
|
||||
};
|
||||
|
||||
// Defining one level is allowed
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
TexStorage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_RGBA8UI, 16, 16);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Having more than one level is not allowed
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
// Use 5 levels because the EXT_texture_storage extension requires a mip chain all the way
|
||||
// to a 1x1 mip.
|
||||
TexStorage2D(GL_TEXTURE_RECTANGLE_ANGLE, 5, GL_RGBA8UI, 16, 16);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
GLint maxSize = 0;
|
||||
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE, &maxSize);
|
||||
|
||||
// Defining a texture of the max size is allowed
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
TexStorage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_RGBA8UI, maxSize, maxSize);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Defining a texture of the max size is allowed
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
TexStorage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_RGBA8UI, maxSize + 1, maxSize);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
TexStorage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_RGBA8UI, maxSize, maxSize + 1);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// Compressed formats are disallowed
|
||||
if (extensionEnabled("GL_EXT_texture_compression_dxt1"))
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
TexStorage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
|
||||
// Test validation of disallowed texture parameters
|
||||
TEST_P(TextureRectangleTest, TexParameterRestriction)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
|
||||
// Only wrap mode CLAMP_TO_EDGE is supported
|
||||
// Wrap S
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
|
||||
// Wrap T
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
|
||||
// Min filter has to be nearest or linear
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
ASSERT_GL_ERROR(GL_INVALID_ENUM);
|
||||
|
||||
// Base level has to be 0
|
||||
if (getClientMajorVersion() >= 3)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_BASE_LEVEL, 1);
|
||||
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
|
||||
}
|
||||
}
|
||||
|
||||
// Test validation of 'level' in GetTexParameter
|
||||
TEST_P(TextureRectangleTestES31, GetTexLevelParameter)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLint param;
|
||||
// Control case: level 0 is ok.
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, ¶m);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Level 1 is not ok.
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_TEXTURE_INTERNAL_FORMAT, ¶m);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// Test validation of "level" in FramebufferTexture2D
|
||||
TEST_P(TextureRectangleTest, FramebufferTexture2DLevel)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
// Using level 0 of a rectangle texture is valid.
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE, tex,
|
||||
0);
|
||||
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Setting level != 0 is invalid
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE, tex,
|
||||
1);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// Test sampling from a rectangle texture
|
||||
TEST_P(TextureRectangleTest, SamplingFromRectangle)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
&GLColor::green);
|
||||
|
||||
const std::string vs =
|
||||
"attribute vec4 position;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(position.xy, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string fs =
|
||||
"#extension GL_ARB_texture_rectangle : require\n"
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2DRect tex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = texture2DRect(tex, vec2(0, 0));\n"
|
||||
"}\n";
|
||||
|
||||
ANGLE_GL_PROGRAM(program, vs, fs);
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
drawQuad(program, "position", 0.5f, 1.0f, false);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Test attaching a rectangle texture and rendering to it.
|
||||
TEST_P(TextureRectangleTest, RenderToRectangle)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
&GLColor::black);
|
||||
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE, tex,
|
||||
0);
|
||||
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Clearing a texture is just as good as checking we can render to it, right?
|
||||
glClearColor(0.0, 1.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Test glCopyTexImage with rectangle textures
|
||||
TEST_P(TextureRectangleTestES3, CopyTexImage)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClearColor(0, 1, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Error case: level != 0
|
||||
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, GL_RGBA8, 0, 0, 1, 1, 0);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
|
||||
// level = 0 works and defines the texture.
|
||||
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA8, 0, 0, 1, 1, 0);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE, tex,
|
||||
0);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Test glCopyTexSubImage with rectangle textures
|
||||
TEST_P(TextureRectangleTestES3, CopyTexSubImage)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
&GLColor::black);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClearColor(0, 1, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Error case: level != 0
|
||||
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 1, 0, 0, 0, 0, 1, 1);
|
||||
ASSERT_GL_ERROR(GL_INVALID_VALUE);
|
||||
|
||||
// level = 0 works and defines the texture.
|
||||
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, 0, 0, 0, 0, 1, 1);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE, tex,
|
||||
0);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(TextureRectangleTest, ES2_OPENGL(), ES3_OPENGL());
|
||||
ANGLE_INSTANTIATE_TEST(TextureRectangleTestES3, ES3_OPENGL());
|
||||
ANGLE_INSTANTIATE_TEST(TextureRectangleTestES31, ES31_OPENGL());
|
||||
} // anonymous namespace
|
Загрузка…
Ссылка в новой задаче