Commit 13b708f2 by Lingfeng Yang Committed by Commit Bot

GLES1: glAlphaFunc

BUG=angleproject:2306 Change-Id: I0bf229d3ab8a4a1217c12b434dcd8fa67d7cbadc Reviewed-on: https://chromium-review.googlesource.com/973897 Commit-Queue: Lingfeng Yang <lfy@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 7a06ac1b
{
"glAlphaFunc": {
"func": "AlphaTestFunc"
},
"glAlphaFuncx": {
"func": "AlphaTestFunc"
},
"glBindBuffer": {
"target": "BufferBinding"
},
......
......@@ -6373,6 +6373,21 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
return true;
}
if (getClientVersion() < Version(2, 0))
{
switch (pname)
{
case GL_ALPHA_TEST_FUNC:
*type = GL_INT;
*numParams = 1;
return true;
case GL_ALPHA_TEST_REF:
*type = GL_FLOAT;
*numParams = 1;
return true;
}
}
if (getClientVersion() < Version(3, 0))
{
return false;
......
......@@ -8,19 +8,20 @@
#include "libANGLE/Context.h"
#include "common/mathutil.h"
#include "common/utilities.h"
namespace gl
{
void Context::alphaFunc(GLenum func, GLfloat ref)
void Context::alphaFunc(AlphaTestFunc func, GLfloat ref)
{
UNIMPLEMENTED();
mGLState.gles1().setAlphaFunc(func, ref);
}
void Context::alphaFuncx(GLenum func, GLfixed ref)
void Context::alphaFuncx(AlphaTestFunc func, GLfixed ref)
{
UNIMPLEMENTED();
mGLState.gles1().setAlphaFunc(func, FixedToFloat(ref));
}
void Context::clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
......
......@@ -11,8 +11,8 @@
#define ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_
#define ANGLE_GLES1_CONTEXT_API \
void alphaFunc(GLenum func, GLfloat ref); \
void alphaFuncx(GLenum func, GLfixed ref); \
void alphaFunc(AlphaTestFunc funcPacked, GLfloat ref); \
void alphaFuncx(AlphaTestFunc funcPacked, GLfixed ref); \
void clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); \
void clearDepthx(GLfixed depth); \
void clientActiveTexture(GLenum texture); \
......
......@@ -46,6 +46,7 @@ ERRMSG(FramebufferIncompleteAttachment,
"Attachment type must be compatible with attachment object.");
ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation.");
ERRMSG(GeometryShaderExtensionNotEnabled, "GL_EXT_geometry_shader extension not enabled.");
ERRMSG(GLES1Only, "GLES1-only function.");
ERRMSG(IncompatibleDrawModeAgainstGeometryShader,
"Primitive mode is incompatible with the input primitive type of the geometry shader.");
ERRMSG(IndexExceedsMaxActiveUniform, "Index exceeds program active uniform count.");
......@@ -146,7 +147,7 @@ ERRMSG(NoActiveGeometryShaderStage, "No active geometry shader stage in this pro
ERRMSG(NoActiveProgramWithComputeShader, "No active program for the compute shader stage.");
ERRMSG(NoSuchPath, "No such path object.");
ERRMSG(NoTransformFeedbackOutputVariables,
"The active program has specified no output variables to record.");
"The active program has specified no output variables to record.");
ERRMSG(NoZeroDivisor, "At least one enabled attribute must have a divisor of zero.");
ERRMSG(NVFenceNotSupported, "GL_NV_fence is not supported");
ERRMSG(ObjectNotGenerated, "Object cannot be used because it has not been generated.");
......
......@@ -34,7 +34,7 @@ GLES1State::GLES1State()
mCurrentNormal({0.0f, 0.0f, 0.0f}),
mCurrMatrixMode(MatrixType::Modelview),
mShadeModel(ShadingModel::Smooth),
mAlphaFunc(AlphaTestFunc::AlwaysPass),
mAlphaTestFunc(AlphaTestFunc::AlwaysPass),
mAlphaTestRef(0.0f),
mLogicOp(LogicalOperation::Copy),
mLineSmoothHint(HintSetting::DontCare),
......@@ -118,8 +118,8 @@ void GLES1State::initialize(const Context *context)
mShadeModel = ShadingModel::Smooth;
mAlphaFunc = AlphaTestFunc::AlwaysPass;
mAlphaTestRef = 0.0f;
mAlphaTestFunc = AlphaTestFunc::AlwaysPass;
mAlphaTestRef = 0.0f;
mLogicOp = LogicalOperation::Copy;
......@@ -142,4 +142,10 @@ void GLES1State::initialize(const Context *context)
mFogHint = HintSetting::DontCare;
}
void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
{
mAlphaTestFunc = func;
mAlphaTestRef = ref;
}
} // namespace gl
......@@ -109,6 +109,7 @@ struct PointParameters
};
class Context;
class State;
class GLES1State final : angle::NonCopyable
{
public:
......@@ -117,7 +118,11 @@ class GLES1State final : angle::NonCopyable
void initialize(const Context *context);
void setAlphaFunc(AlphaTestFunc func, GLfloat ref);
private:
friend class State;
// All initial state values come from the
// OpenGL ES 1.1 spec.
struct TextureEnables
......@@ -179,7 +184,7 @@ class GLES1State final : angle::NonCopyable
PointParameters mPointParameters;
// Table 6.16
AlphaTestFunc mAlphaFunc;
AlphaTestFunc mAlphaTestFunc;
GLfloat mAlphaTestRef;
LogicalOperation mLogicOp;
......
......@@ -98,7 +98,9 @@ State::State()
{
}
State::~State() {}
State::~State()
{
}
void State::initialize(const Context *context,
bool debug,
......@@ -764,6 +766,12 @@ void State::setEnableFeature(GLenum feature, bool enabled)
case GL_FRAMEBUFFER_SRGB_EXT:
setFramebufferSRGB(enabled);
break;
// GLES1 emulation
case GL_ALPHA_TEST:
mGLES1State.mAlphaTestEnabled = enabled;
break;
default:
UNREACHABLE();
}
......@@ -816,6 +824,10 @@ bool State::getEnableFeature(GLenum feature) const
case GL_PROGRAM_CACHE_ENABLED_ANGLE:
return mProgramBinaryCacheEnabled;
// GLES1 emulation
case GL_ALPHA_TEST:
return mGLES1State.mAlphaTestEnabled;
default:
UNREACHABLE();
return false;
......@@ -1915,6 +1927,9 @@ void State::getFloatv(GLenum pname, GLfloat *params)
case GL_COVERAGE_MODULATION_CHROMIUM:
params[0] = static_cast<GLfloat>(mCoverageModulation);
break;
case GL_ALPHA_TEST_REF:
*params = mGLES1State.mAlphaTestRef;
break;
default:
UNREACHABLE();
break;
......@@ -2286,6 +2301,9 @@ Error State::getIntegerv(const Context *context, GLenum pname, GLint *params)
case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
*params = mBoundBuffers[BufferBinding::DispatchIndirect].id();
break;
case GL_ALPHA_TEST_FUNC:
*params = ToGLenum(mGLES1State.mAlphaTestFunc);
break;
default:
UNREACHABLE();
break;
......
......@@ -474,6 +474,9 @@ class State : public angle::ObserverInterface, angle::NonCopyable
bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
bool isCurrentVertexArray(const VertexArray *va) const;
GLES1State &gles1() { return mGLES1State; }
const GLES1State &gles1() const { return mGLES1State; }
private:
void syncProgramTextures(const Context *context);
......@@ -603,7 +606,6 @@ class State : public angle::ObserverInterface, angle::NonCopyable
bool mProgramBinaryCacheEnabled;
// GLES1 emulation: state specific to GLES1
friend class GLES1State;
GLES1State mGLES1State;
DirtyBits mDirtyBits;
......
......@@ -10,8 +10,8 @@
#include <vector>
#include "libANGLE/Context.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
namespace gl
{
......@@ -31,14 +31,22 @@ QueryT CastFromStateValueToInt(GLenum pname, NativeT value)
if (nativeType == GL_FLOAT)
{
// RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
{
return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
}
else
// RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from
// Table 4.5
switch (pname)
{
return clampCast<QueryT>(std::round(value));
case GL_DEPTH_RANGE:
case GL_COLOR_CLEAR_VALUE:
case GL_DEPTH_CLEAR_VALUE:
case GL_BLEND_COLOR:
// GLES1 emulation:
// Also, several GLES1.x values need to be converted to integer with
// ExpandFloatToInteger rather than rounding. See GLES 1.1 spec 6.1.2 "Data
// Conversions".
case GL_ALPHA_TEST_REF:
return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
default:
return clampCast<QueryT>(std::round(value));
}
}
......@@ -151,8 +159,11 @@ template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value);
template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value);
template <typename QueryT>
void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
unsigned int numParams, QueryT *outParams)
void CastStateValues(Context *context,
GLenum nativeType,
GLenum pname,
unsigned int numParams,
QueryT *outParams)
{
if (nativeType == GL_INT)
{
......@@ -171,7 +182,8 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
for (unsigned int i = 0; i < numParams; ++i)
{
outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
outParams[i] =
(boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
}
}
else if (nativeType == GL_FLOAT)
......@@ -194,7 +206,8 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
}
}
else UNREACHABLE();
else
UNREACHABLE();
}
// Explicit template instantiation (how we export template functions in different files)
......
......@@ -9,20 +9,53 @@
#include "libANGLE/validationES1.h"
#include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#define ANGLE_VALIDATE_IS_GLES1(context) \
if (context->getClientMajorVersion() > 1) \
{ \
ANGLE_VALIDATION_ERR(context, InvalidOperation(), GLES1Only); \
return false; \
}
namespace
{
bool ValidateAlphaFuncCommon(gl::Context *context, gl::AlphaTestFunc func)
{
switch (func)
{
case gl::AlphaTestFunc::AlwaysPass:
case gl::AlphaTestFunc::Equal:
case gl::AlphaTestFunc::Gequal:
case gl::AlphaTestFunc::Greater:
case gl::AlphaTestFunc::Lequal:
case gl::AlphaTestFunc::Less:
case gl::AlphaTestFunc::Never:
case gl::AlphaTestFunc::NotEqual:
return true;
default:
context->handleError(gl::InvalidEnum() << gl::kErrorEnumNotSupported);
return false;
}
}
} // anonymous namespace
namespace gl
{
bool ValidateAlphaFunc(Context *context, GLenum func, GLfloat ref)
bool ValidateAlphaFunc(Context *context, AlphaTestFunc func, GLfloat ref)
{
UNIMPLEMENTED();
return true;
ANGLE_VALIDATE_IS_GLES1(context);
return ValidateAlphaFuncCommon(context, func);
}
bool ValidateAlphaFuncx(Context *context, GLenum func, GLfixed ref)
bool ValidateAlphaFuncx(Context *context, AlphaTestFunc func, GLfixed ref)
{
UNIMPLEMENTED();
return true;
ANGLE_VALIDATE_IS_GLES1(context);
return ValidateAlphaFuncCommon(context, func);
}
bool ValidateClearColorx(Context *context, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
......
......@@ -18,8 +18,8 @@ namespace gl
{
class Context;
bool ValidateAlphaFunc(Context *context, GLenum func, GLfloat ref);
bool ValidateAlphaFuncx(Context *context, GLenum func, GLfixed ref);
bool ValidateAlphaFunc(Context *context, AlphaTestFunc func, GLfloat ref);
bool ValidateAlphaFuncx(Context *context, AlphaTestFunc func, GLfixed ref);
bool ValidateClearColorx(Context *context, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
bool ValidateClearDepthx(Context *context, GLfixed depth);
bool ValidateClientActiveTexture(Context *context, GLenum texture);
......
......@@ -792,6 +792,10 @@ bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
return queryOnly && context->getExtensions().robustResourceInitialization;
// GLES1 emulation: GLES1-specific caps
case GL_ALPHA_TEST:
return context->getClientVersion() < Version(2, 0);
default:
return false;
}
......
......@@ -23,11 +23,12 @@ void GL_APIENTRY AlphaFunc(GLenum func, GLfloat ref)
Context *context = GetValidGlobalContext();
if (context)
{
context->gatherParams<EntryPoint::AlphaFunc>(func, ref);
AlphaTestFunc funcPacked = FromGLenum<AlphaTestFunc>(func);
context->gatherParams<EntryPoint::AlphaFunc>(funcPacked, ref);
if (context->skipValidation() || ValidateAlphaFunc(context, func, ref))
if (context->skipValidation() || ValidateAlphaFunc(context, funcPacked, ref))
{
context->alphaFunc(func, ref);
context->alphaFunc(funcPacked, ref);
}
}
}
......@@ -39,11 +40,12 @@ void GL_APIENTRY AlphaFuncx(GLenum func, GLfixed ref)
Context *context = GetValidGlobalContext();
if (context)
{
context->gatherParams<EntryPoint::AlphaFuncx>(func, ref);
AlphaTestFunc funcPacked = FromGLenum<AlphaTestFunc>(func);
context->gatherParams<EntryPoint::AlphaFuncx>(funcPacked, ref);
if (context->skipValidation() || ValidateAlphaFuncx(context, func, ref))
if (context->skipValidation() || ValidateAlphaFuncx(context, funcPacked, ref))
{
context->alphaFuncx(func, ref);
context->alphaFuncx(funcPacked, ref);
}
}
}
......
......@@ -179,6 +179,7 @@ if (is_win || is_linux || is_mac || is_android) {
angle_root + ":angle_image_util",
angle_root + ":angle_util",
angle_root + ":libEGL${angle_libs_suffix}",
angle_root + ":libGLESv1_CM${angle_libs_suffix}",
angle_root + ":libGLESv2${angle_libs_suffix}",
angle_root + ":preprocessor",
angle_root + ":translator",
......
......@@ -47,6 +47,7 @@
'<(angle_path)/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp',
'<(angle_path)/src/tests/gl_tests/FramebufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/GeometryShaderTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/AlphaFuncTest.cpp',
'<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
'<(angle_path)/src/tests/gl_tests/ImageTest.cpp',
'<(angle_path)/src/tests/gl_tests/IncompleteTextureTest.cpp',
......@@ -147,6 +148,7 @@
# This lets us filter test configs more intelligently.
'<(angle_path)/src/angle.gyp:libANGLE_renderer_config',
'<(angle_path)/src/angle.gyp:libEGL',
'<(angle_path)/src/angle.gyp:libGLESv1_CM',
'<(angle_path)/src/angle.gyp:libGLESv2',
'<(angle_path)/src/tests/tests.gyp:angle_test_support',
'<(angle_path)/util/util.gyp:angle_util',
......
//
// Copyright 2018 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.
//
// AlphaFuncTest.cpp: Tests basic usage of glAlphaFunc.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "random_utils.h"
#include <stdint.h>
using namespace angle;
class AlphaFuncTest : public ANGLETest
{
protected:
AlphaFuncTest()
{
setWindowWidth(32);
setWindowHeight(32);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
}
};
// Checks that disable / enable works as expected.
TEST_P(AlphaFuncTest, EnableDisable)
{
EXPECT_GL_FALSE(glIsEnabled(GL_ALPHA_TEST));
EXPECT_GL_NO_ERROR();
glEnable(GL_ALPHA_TEST);
EXPECT_GL_NO_ERROR();
EXPECT_GL_TRUE(glIsEnabled(GL_ALPHA_TEST));
EXPECT_GL_NO_ERROR();
glDisable(GL_ALPHA_TEST);
EXPECT_GL_NO_ERROR();
EXPECT_GL_FALSE(glIsEnabled(GL_ALPHA_TEST));
EXPECT_GL_NO_ERROR();
}
// Negative test: Checks that invalid enums for alpha test function generate the proper GL error.
TEST_P(AlphaFuncTest, SetFuncNegative)
{
glAlphaFunc((GLenum)0, 0.0f);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glAlphaFunc((GLenum)1, 0.0f);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glAlphaFunc((GLenum)GL_ALPHA, 0.0f);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
// Query test: Checks that the alpha test ref value can be obtained with glGetFloatv.
TEST_P(AlphaFuncTest, SetFuncGetFloat)
{
GLfloat alphaTestVal = -1.0f;
glAlphaFunc(GL_ALWAYS, 0.0f);
glGetFloatv(GL_ALPHA_TEST_REF, &alphaTestVal);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0.0f, alphaTestVal);
glAlphaFunc(GL_ALWAYS, 0.4f);
glGetFloatv(GL_ALPHA_TEST_REF, &alphaTestVal);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0.4f, alphaTestVal);
}
// Query test: Checks that the alpha test ref value can be obtained with glGetIntegerv,
// with proper scaling.
TEST_P(AlphaFuncTest, SetFuncGetInt)
{
GLint alphaTestVal = -1;
glAlphaFunc(GL_ALWAYS, 0.0f);
glGetIntegerv(GL_ALPHA_TEST_REF, &alphaTestVal);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0, alphaTestVal);
glAlphaFunc(GL_ALWAYS, 1.0f);
glGetIntegerv(GL_ALPHA_TEST_REF, &alphaTestVal);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(std::numeric_limits<GLint>::max(), alphaTestVal);
}
ANGLE_INSTANTIATE_TEST(AlphaFuncTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());
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