GLES1: Texture environment API
BUG=angleproject:2306
Change-Id: Ibb168d5c9f7aa96a48c96ffbe96ecead2276975e
Reviewed-on: https://chromium-review.googlesource.com/1092101
Commit-Queue: Lingfeng Yang <lfy@google.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/common/PackedGLEnums_autogen.cpp b/src/common/PackedGLEnums_autogen.cpp
index b578d46..2131cd0 100644
--- a/src/common/PackedGLEnums_autogen.cpp
+++ b/src/common/PackedGLEnums_autogen.cpp
@@ -840,6 +840,30 @@
return TextureEnvParameter::RgbScale;
case GL_ALPHA_SCALE:
return TextureEnvParameter::AlphaScale;
+ case GL_SRC0_RGB:
+ return TextureEnvParameter::Src0Rgb;
+ case GL_SRC1_RGB:
+ return TextureEnvParameter::Src1Rgb;
+ case GL_SRC2_RGB:
+ return TextureEnvParameter::Src2Rgb;
+ case GL_SRC0_ALPHA:
+ return TextureEnvParameter::Src0Alpha;
+ case GL_SRC1_ALPHA:
+ return TextureEnvParameter::Src1Alpha;
+ case GL_SRC2_ALPHA:
+ return TextureEnvParameter::Src2Alpha;
+ case GL_OPERAND0_RGB:
+ return TextureEnvParameter::Op0Rgb;
+ case GL_OPERAND1_RGB:
+ return TextureEnvParameter::Op1Rgb;
+ case GL_OPERAND2_RGB:
+ return TextureEnvParameter::Op2Rgb;
+ case GL_OPERAND0_ALPHA:
+ return TextureEnvParameter::Op0Alpha;
+ case GL_OPERAND1_ALPHA:
+ return TextureEnvParameter::Op1Alpha;
+ case GL_OPERAND2_ALPHA:
+ return TextureEnvParameter::Op2Alpha;
default:
return TextureEnvParameter::InvalidEnum;
}
@@ -861,6 +885,30 @@
return GL_RGB_SCALE;
case TextureEnvParameter::AlphaScale:
return GL_ALPHA_SCALE;
+ case TextureEnvParameter::Src0Rgb:
+ return GL_SRC0_RGB;
+ case TextureEnvParameter::Src1Rgb:
+ return GL_SRC1_RGB;
+ case TextureEnvParameter::Src2Rgb:
+ return GL_SRC2_RGB;
+ case TextureEnvParameter::Src0Alpha:
+ return GL_SRC0_ALPHA;
+ case TextureEnvParameter::Src1Alpha:
+ return GL_SRC1_ALPHA;
+ case TextureEnvParameter::Src2Alpha:
+ return GL_SRC2_ALPHA;
+ case TextureEnvParameter::Op0Rgb:
+ return GL_OPERAND0_RGB;
+ case TextureEnvParameter::Op1Rgb:
+ return GL_OPERAND1_RGB;
+ case TextureEnvParameter::Op2Rgb:
+ return GL_OPERAND2_RGB;
+ case TextureEnvParameter::Op0Alpha:
+ return GL_OPERAND0_ALPHA;
+ case TextureEnvParameter::Op1Alpha:
+ return GL_OPERAND1_ALPHA;
+ case TextureEnvParameter::Op2Alpha:
+ return GL_OPERAND2_ALPHA;
default:
UNREACHABLE();
return 0;
diff --git a/src/common/PackedGLEnums_autogen.h b/src/common/PackedGLEnums_autogen.h
index 98642dd..1b57f6d 100644
--- a/src/common/PackedGLEnums_autogen.h
+++ b/src/common/PackedGLEnums_autogen.h
@@ -336,9 +336,21 @@
CombineAlpha = 3,
RgbScale = 4,
AlphaScale = 5,
+ Src0Rgb = 6,
+ Src1Rgb = 7,
+ Src2Rgb = 8,
+ Src0Alpha = 9,
+ Src1Alpha = 10,
+ Src2Alpha = 11,
+ Op0Rgb = 12,
+ Op1Rgb = 13,
+ Op2Rgb = 14,
+ Op0Alpha = 15,
+ Op1Alpha = 16,
+ Op2Alpha = 17,
- InvalidEnum = 6,
- EnumCount = 6,
+ InvalidEnum = 18,
+ EnumCount = 18,
};
template <>
diff --git a/src/common/packed_gl_enums.json b/src/common/packed_gl_enums.json
index 04fe239..c76a0f6 100644
--- a/src/common/packed_gl_enums.json
+++ b/src/common/packed_gl_enums.json
@@ -141,7 +141,19 @@
"CombineRgb": "GL_COMBINE_RGB",
"CombineAlpha": "GL_COMBINE_ALPHA",
"RgbScale": "GL_RGB_SCALE",
- "AlphaScale": "GL_ALPHA_SCALE"
+ "AlphaScale": "GL_ALPHA_SCALE",
+ "Src0Rgb": "GL_SRC0_RGB",
+ "Src1Rgb": "GL_SRC1_RGB",
+ "Src2Rgb": "GL_SRC2_RGB",
+ "Src0Alpha": "GL_SRC0_ALPHA",
+ "Src1Alpha": "GL_SRC1_ALPHA",
+ "Src2Alpha": "GL_SRC2_ALPHA",
+ "Op0Rgb": "GL_OPERAND0_RGB",
+ "Op1Rgb": "GL_OPERAND1_RGB",
+ "Op2Rgb": "GL_OPERAND2_RGB",
+ "Op0Alpha": "GL_OPERAND0_ALPHA",
+ "Op1Alpha": "GL_OPERAND1_ALPHA",
+ "Op2Alpha": "GL_OPERAND2_ALPHA"
},
"TextureOp":
{
diff --git a/src/libANGLE/Context_gles_1_0.cpp b/src/libANGLE/Context_gles_1_0.cpp
index 6cce051..543b068 100644
--- a/src/libANGLE/Context_gles_1_0.cpp
+++ b/src/libANGLE/Context_gles_1_0.cpp
@@ -12,6 +12,7 @@
#include "common/utilities.h"
#include "libANGLE/GLES1Renderer.h"
+#include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h"
namespace
@@ -130,7 +131,7 @@
{
if (GetFogParameterCount(pname) == 1)
{
- GLfloat paramf = pname == GL_FOG_MODE ? FixedToEnum(param) : FixedToFloat(param);
+ GLfloat paramf = pname == GL_FOG_MODE ? ConvertToGLenum(param) : FixedToFloat(param);
fogf(pname, paramf);
}
else
@@ -148,7 +149,8 @@
GLfloat paramsf[4];
for (int i = 0; i < paramCount; i++)
{
- paramsf[i] = pname == GL_FOG_MODE ? FixedToEnum(params[i]) : FixedToFloat(params[i]);
+ paramsf[i] =
+ pname == GL_FOG_MODE ? ConvertToGLenum(params[i]) : FixedToFloat(params[i]);
}
fogfv(pname, paramsf);
}
@@ -224,19 +226,23 @@
}
}
-void Context::getTexEnvfv(TextureEnvTarget env, TextureEnvParameter pname, GLfloat *params)
+void Context::getTexEnvfv(TextureEnvTarget target, TextureEnvParameter pname, GLfloat *params)
{
- UNIMPLEMENTED();
+ GetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, params);
}
-void Context::getTexEnviv(TextureEnvTarget env, TextureEnvParameter pname, GLint *params)
+void Context::getTexEnviv(TextureEnvTarget target, TextureEnvParameter pname, GLint *params)
{
- UNIMPLEMENTED();
+ GLfloat paramsf[4];
+ GetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, paramsf);
+ ConvertTextureEnvToInt(pname, paramsf, params);
}
void Context::getTexEnvxv(TextureEnvTarget target, TextureEnvParameter pname, GLfixed *params)
{
- UNIMPLEMENTED();
+ GLfloat paramsf[4];
+ GetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, paramsf);
+ ConvertTextureEnvToFixed(pname, paramsf, params);
}
void Context::getTexParameterxv(TextureType target, GLenum pname, GLfixed *params)
@@ -498,32 +504,40 @@
void Context::texEnvf(TextureEnvTarget target, TextureEnvParameter pname, GLfloat param)
{
- UNIMPLEMENTED();
+ SetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, ¶m);
}
void Context::texEnvfv(TextureEnvTarget target, TextureEnvParameter pname, const GLfloat *params)
{
- UNIMPLEMENTED();
+ SetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, params);
}
void Context::texEnvi(TextureEnvTarget target, TextureEnvParameter pname, GLint param)
{
- UNIMPLEMENTED();
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromInt(pname, ¶m, paramsf);
+ SetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, paramsf);
}
void Context::texEnviv(TextureEnvTarget target, TextureEnvParameter pname, const GLint *params)
{
- UNIMPLEMENTED();
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromInt(pname, params, paramsf);
+ SetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, paramsf);
}
void Context::texEnvx(TextureEnvTarget target, TextureEnvParameter pname, GLfixed param)
{
- UNIMPLEMENTED();
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromFixed(pname, ¶m, paramsf);
+ SetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, paramsf);
}
void Context::texEnvxv(TextureEnvTarget target, TextureEnvParameter pname, const GLfixed *params)
{
- UNIMPLEMENTED();
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromFixed(pname, params, paramsf);
+ SetTextureEnv(mGLState.getActiveSampler(), &mGLState.gles1(), target, pname, paramsf);
}
void Context::texParameterx(TextureType target, GLenum pname, GLfixed param)
diff --git a/src/libANGLE/ErrorStrings.h b/src/libANGLE/ErrorStrings.h
index 0114d74..ce305cf 100644
--- a/src/libANGLE/ErrorStrings.h
+++ b/src/libANGLE/ErrorStrings.h
@@ -135,6 +135,13 @@
ERRMSG(InvalidStencil, "Invalid stencil.");
ERRMSG(InvalidStencilBitMask, "Invalid stencil bit mask.");
ERRMSG(InvalidTarget, "Invalid target.");
+ERRMSG(InvalidTextureCombine, "Invalid texture combine mode.");
+ERRMSG(InvalidTextureCombineSrc, "Invalid texture combine source.");
+ERRMSG(InvalidTextureCombineOp, "Invalid texture combine operand.");
+ERRMSG(InvalidTextureEnvMode, "Invalid texture environment mode.");
+ERRMSG(InvalidTextureEnvParameter, "Invalid texture environment parameter.");
+ERRMSG(InvalidTextureEnvScale, "Invalid texture environment scale.");
+ERRMSG(InvalidTextureEnvTarget, "Invalid texture environment target.");
ERRMSG(InvalidTextureFilterParam, "Texture filter not recognized.");
ERRMSG(InvalidTextureName, "Not a valid texture object name.");
ERRMSG(InvalidTextureRange, "Cannot be less than 0 or greater than maximum number of textures.");
diff --git a/src/libANGLE/GLES1State.cpp b/src/libANGLE/GLES1State.cpp
index 74ed1bc..181bd93 100644
--- a/src/libANGLE/GLES1State.cpp
+++ b/src/libANGLE/GLES1State.cpp
@@ -394,4 +394,16 @@
return mFog;
}
+TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
+{
+ assert(unit < mTextureEnvironments.size());
+ return mTextureEnvironments[unit];
+}
+
+const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
+{
+ assert(unit < mTextureEnvironments.size());
+ return mTextureEnvironments[unit];
+}
+
} // namespace gl
diff --git a/src/libANGLE/GLES1State.h b/src/libANGLE/GLES1State.h
index a5b1f10..1b15d8b 100644
--- a/src/libANGLE/GLES1State.h
+++ b/src/libANGLE/GLES1State.h
@@ -76,29 +76,29 @@
struct TextureEnvironmentParameters
{
- TextureEnvMode envMode = TextureEnvMode::Modulate;
+ TextureEnvMode mode = TextureEnvMode::Modulate;
TextureCombine combineRgb = TextureCombine::Modulate;
TextureCombine combineAlpha = TextureCombine::Modulate;
- TextureSrc src0rgb = TextureSrc::Texture;
- TextureSrc src0alpha = TextureSrc::Texture;
+ TextureSrc src0Rgb = TextureSrc::Texture;
+ TextureSrc src0Alpha = TextureSrc::Texture;
- TextureSrc src1rgb = TextureSrc::Previous;
- TextureSrc src1alpha = TextureSrc::Previous;
+ TextureSrc src1Rgb = TextureSrc::Previous;
+ TextureSrc src1Alpha = TextureSrc::Previous;
- TextureSrc src2rgb = TextureSrc::Constant;
- TextureSrc src2alpha = TextureSrc::Constant;
+ TextureSrc src2Rgb = TextureSrc::Constant;
+ TextureSrc src2Alpha = TextureSrc::Constant;
- TextureOp op0rgb = TextureOp::SrcColor;
- TextureOp op0alpha = TextureOp::SrcAlpha;
+ TextureOp op0Rgb = TextureOp::SrcColor;
+ TextureOp op0Alpha = TextureOp::SrcAlpha;
- TextureOp op1rgb = TextureOp::SrcColor;
- TextureOp op1alpha = TextureOp::SrcAlpha;
+ TextureOp op1Rgb = TextureOp::SrcColor;
+ TextureOp op1Alpha = TextureOp::SrcAlpha;
- TextureOp op2rgb = TextureOp::SrcAlpha;
- TextureOp op2alpha = TextureOp::SrcAlpha;
+ TextureOp op2Rgb = TextureOp::SrcAlpha;
+ TextureOp op2Alpha = TextureOp::SrcAlpha;
- ColorF envColor = {0.0f, 0.0f, 0.0f, 0.0f};
+ ColorF color = {0.0f, 0.0f, 0.0f, 0.0f};
GLfloat rgbScale = 1.0f;
GLfloat alphaScale = 1.0f;
@@ -183,6 +183,9 @@
FogParameters &fogParameters();
const FogParameters &fogParameters() const;
+ TextureEnvironmentParameters &textureEnvironment(unsigned int unit);
+ const TextureEnvironmentParameters &textureEnvironment(unsigned int unit) const;
+
private:
friend class State;
friend class GLES1Renderer;
diff --git a/src/libANGLE/queryconversions.h b/src/libANGLE/queryconversions.h
index d295091..267e0e7 100644
--- a/src/libANGLE/queryconversions.h
+++ b/src/libANGLE/queryconversions.h
@@ -81,6 +81,24 @@
return ConvertToGLenum(GL_NONE, param);
}
+template <typename OutType>
+OutType ConvertGLenum(GLenum param)
+{
+ return static_cast<OutType>(param);
+}
+
+template <typename InType, typename OutType>
+void ConvertGLenumValue(InType param, OutType *out)
+{
+ *out = ConvertGLenum<OutType>(static_cast<GLenum>(param));
+}
+
+template <typename PackedEnumType, typename OutType>
+void ConvertPackedEnum(PackedEnumType param, OutType *out)
+{
+ *out = static_cast<OutType>(ToGLenum(param));
+}
+
template <typename ParamType>
GLint ConvertToGLint(ParamType param)
{
@@ -101,8 +119,11 @@
// The GL state query API types are: bool, int, uint, float, int64, uint64
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);
// The GL state query API types are: bool, int, uint, float, int64, uint64
template <typename QueryT>
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index f8c59fd..b489bb3 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -798,6 +798,33 @@
GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
}
+bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
+{
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // anonymous namespace
void QueryFramebufferAttachmentParameteriv(const Context *context,
@@ -2086,9 +2113,293 @@
}
}
-GLenum FixedToEnum(GLfixed val)
+unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
{
- return static_cast<GLenum>(val);
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ return 1;
+ case TextureEnvParameter::Color:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = static_cast<GLfloat>(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = input[i] / 255.0f;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = FixedToFloat(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = FixedToFloat(input[i]);
+ }
+ break;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = static_cast<GLint>(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = static_cast<GLint>(input[i] * 255.0f);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = FloatToFixed(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = FloatToFixed(input[i]);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void SetTextureEnv(unsigned int unit,
+ GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params)
+{
+ if (target == TextureEnvTarget::Env)
+ {
+ TextureEnvironmentParameters &env = state->textureEnvironment(unit);
+ GLenum asEnum = ConvertToGLenum(params[0]);
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ env.mode = FromGLenum<TextureEnvMode>(asEnum);
+ break;
+ case TextureEnvParameter::CombineRgb:
+ env.combineRgb = FromGLenum<TextureCombine>(asEnum);
+ break;
+ case TextureEnvParameter::CombineAlpha:
+ env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src1Rgb:
+ env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src2Rgb:
+ env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src0Alpha:
+ env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src1Alpha:
+ env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src2Alpha:
+ env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ env.op0Rgb = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op1Rgb:
+ env.op1Rgb = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op2Rgb:
+ env.op2Rgb = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op0Alpha:
+ env.op0Alpha = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op1Alpha:
+ env.op1Alpha = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op2Alpha:
+ env.op2Alpha = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Color:
+ env.color = ColorF::fromData(params);
+ break;
+ case TextureEnvParameter::RgbScale:
+ env.rgbScale = params[0];
+ break;
+ case TextureEnvParameter::AlphaScale:
+ env.alphaScale = params[0];
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else
+ {
+ // TODO(lfy@google.com): point sprite target
+ UNREACHABLE();
+ }
+}
+
+void GetTextureEnv(unsigned int unit,
+ const GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLfloat *params)
+{
+ if (target == TextureEnvTarget::Env)
+ {
+ const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ ConvertPackedEnum(env.mode, params);
+ break;
+ case TextureEnvParameter::CombineRgb:
+ ConvertPackedEnum(env.combineRgb, params);
+ break;
+ case TextureEnvParameter::CombineAlpha:
+ ConvertPackedEnum(env.combineAlpha, params);
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ ConvertPackedEnum(env.src0Rgb, params);
+ break;
+ case TextureEnvParameter::Src1Rgb:
+ ConvertPackedEnum(env.src1Rgb, params);
+ break;
+ case TextureEnvParameter::Src2Rgb:
+ ConvertPackedEnum(env.src2Rgb, params);
+ break;
+ case TextureEnvParameter::Src0Alpha:
+ ConvertPackedEnum(env.src0Alpha, params);
+ break;
+ case TextureEnvParameter::Src1Alpha:
+ ConvertPackedEnum(env.src1Alpha, params);
+ break;
+ case TextureEnvParameter::Src2Alpha:
+ ConvertPackedEnum(env.src2Alpha, params);
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ ConvertPackedEnum(env.op0Rgb, params);
+ break;
+ case TextureEnvParameter::Op1Rgb:
+ ConvertPackedEnum(env.op1Rgb, params);
+ break;
+ case TextureEnvParameter::Op2Rgb:
+ ConvertPackedEnum(env.op2Rgb, params);
+ break;
+ case TextureEnvParameter::Op0Alpha:
+ ConvertPackedEnum(env.op0Alpha, params);
+ break;
+ case TextureEnvParameter::Op1Alpha:
+ ConvertPackedEnum(env.op1Alpha, params);
+ break;
+ case TextureEnvParameter::Op2Alpha:
+ ConvertPackedEnum(env.op2Alpha, params);
+ break;
+ case TextureEnvParameter::Color:
+ env.color.writeData(params);
+ break;
+ case TextureEnvParameter::RgbScale:
+ *params = env.rgbScale;
+ break;
+ case TextureEnvParameter::AlphaScale:
+ *params = env.alphaScale;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else
+ {
+ // TODO(lfy@google.com): point sprite target
+ UNREACHABLE();
+ }
}
} // namespace gl
diff --git a/src/libANGLE/queryutils.h b/src/libANGLE/queryutils.h
index b7f01c9..148f007 100644
--- a/src/libANGLE/queryutils.h
+++ b/src/libANGLE/queryutils.h
@@ -179,7 +179,23 @@
void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params);
unsigned int GetFogParameterCount(GLenum pname);
-GLenum FixedToEnum(GLfixed val);
+unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname);
+
+void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output);
+void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output);
+void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output);
+void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output);
+
+void SetTextureEnv(unsigned int unit,
+ GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params);
+void GetTextureEnv(unsigned int unit,
+ const GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLfloat *params);
} // namespace gl
diff --git a/src/libANGLE/validationES1.cpp b/src/libANGLE/validationES1.cpp
index 64638eb..4ec2c53 100644
--- a/src/libANGLE/validationES1.cpp
+++ b/src/libANGLE/validationES1.cpp
@@ -12,6 +12,7 @@
#include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/GLES1State.h"
+#include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h"
#include "libANGLE/validationES.h"
@@ -368,6 +369,172 @@
return true;
}
+bool ValidateTexEnvCommon(Context *context,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context);
+
+ if (target != TextureEnvTarget::Env)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureEnvTarget);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ {
+ TextureEnvMode mode = FromGLenum<TextureEnvMode>(ConvertToGLenum(params[0]));
+ switch (mode)
+ {
+ case TextureEnvMode::Add:
+ case TextureEnvMode::Blend:
+ case TextureEnvMode::Combine:
+ case TextureEnvMode::Decal:
+ case TextureEnvMode::Modulate:
+ case TextureEnvMode::Replace:
+ break;
+ default:
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureEnvMode);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ {
+ TextureCombine combine = FromGLenum<TextureCombine>(ConvertToGLenum(params[0]));
+ switch (combine)
+ {
+ case TextureCombine::Add:
+ case TextureCombine::AddSigned:
+ case TextureCombine::Interpolate:
+ case TextureCombine::Modulate:
+ case TextureCombine::Replace:
+ case TextureCombine::Subtract:
+ break;
+ case TextureCombine::Dot3Rgb:
+ case TextureCombine::Dot3Rgba:
+ if (pname == TextureEnvParameter::CombineAlpha)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureCombine);
+ return false;
+ }
+ break;
+ default:
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureCombine);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ {
+ TextureSrc combine = FromGLenum<TextureSrc>(ConvertToGLenum(params[0]));
+ switch (combine)
+ {
+ case TextureSrc::Constant:
+ case TextureSrc::Previous:
+ case TextureSrc::PrimaryColor:
+ case TextureSrc::Texture:
+ break;
+ default:
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureCombineSrc);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ {
+ TextureOp operand = FromGLenum<TextureOp>(ConvertToGLenum(params[0]));
+ switch (operand)
+ {
+ case TextureOp::SrcAlpha:
+ case TextureOp::OneMinusSrcAlpha:
+ break;
+ case TextureOp::SrcColor:
+ case TextureOp::OneMinusSrcColor:
+ if (pname == TextureEnvParameter::Op0Alpha ||
+ pname == TextureEnvParameter::Op1Alpha ||
+ pname == TextureEnvParameter::Op2Alpha)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureCombine);
+ return false;
+ }
+ break;
+ default:
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureCombineOp);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ if (params[0] != 1.0f && params[0] != 2.0f && params[0] != 4.0f)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureEnvScale);
+ return false;
+ }
+ break;
+ case TextureEnvParameter::Color:
+ break;
+ default:
+ ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureEnvParameter);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateGetTexEnvCommon(Context *context, TextureEnvTarget target, TextureEnvParameter pname)
+{
+ GLfloat dummy[4] = {};
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ ConvertPackedEnum(TextureEnvMode::Add, dummy);
+ break;
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ ConvertPackedEnum(TextureCombine::Add, dummy);
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ ConvertPackedEnum(TextureSrc::Constant, dummy);
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ ConvertPackedEnum(TextureOp::SrcAlpha, dummy);
+ break;
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ dummy[0] = 1.0f;
+ break;
+ default:
+ break;
+ }
+
+ return ValidateTexEnvCommon(context, target, pname, dummy);
+}
+
} // namespace gl
namespace gl
@@ -592,8 +759,7 @@
TextureEnvParameter pname,
GLfloat *params)
{
- UNIMPLEMENTED();
- return true;
+ return ValidateGetTexEnvCommon(context, target, pname);
}
bool ValidateGetTexEnviv(Context *context,
@@ -601,8 +767,7 @@
TextureEnvParameter pname,
GLint *params)
{
- UNIMPLEMENTED();
- return true;
+ return ValidateGetTexEnvCommon(context, target, pname);
}
bool ValidateGetTexEnvxv(Context *context,
@@ -610,8 +775,7 @@
TextureEnvParameter pname,
GLfixed *params)
{
- UNIMPLEMENTED();
- return true;
+ return ValidateGetTexEnvCommon(context, target, pname);
}
bool ValidateGetTexParameterxv(Context *context, TextureType target, GLenum pname, GLfixed *params)
@@ -953,8 +1117,7 @@
TextureEnvParameter pname,
GLfloat param)
{
- UNIMPLEMENTED();
- return true;
+ return ValidateTexEnvCommon(context, target, pname, ¶m);
}
bool ValidateTexEnvfv(Context *context,
@@ -962,8 +1125,7 @@
TextureEnvParameter pname,
const GLfloat *params)
{
- UNIMPLEMENTED();
- return true;
+ return ValidateTexEnvCommon(context, target, pname, params);
}
bool ValidateTexEnvi(Context *context,
@@ -971,8 +1133,8 @@
TextureEnvParameter pname,
GLint param)
{
- UNIMPLEMENTED();
- return true;
+ GLfloat paramf = static_cast<GLfloat>(param);
+ return ValidateTexEnvCommon(context, target, pname, ¶mf);
}
bool ValidateTexEnviv(Context *context,
@@ -980,8 +1142,12 @@
TextureEnvParameter pname,
const GLint *params)
{
- UNIMPLEMENTED();
- return true;
+ GLfloat paramsf[4];
+ for (unsigned int i = 0; i < GetTextureEnvParameterCount(pname); i++)
+ {
+ paramsf[i] = static_cast<GLfloat>(params[i]);
+ }
+ return ValidateTexEnvCommon(context, target, pname, paramsf);
}
bool ValidateTexEnvx(Context *context,
@@ -989,8 +1155,8 @@
TextureEnvParameter pname,
GLfixed param)
{
- UNIMPLEMENTED();
- return true;
+ GLfloat paramf = static_cast<GLfloat>(param);
+ return ValidateTexEnvCommon(context, target, pname, ¶mf);
}
bool ValidateTexEnvxv(Context *context,
@@ -998,8 +1164,12 @@
TextureEnvParameter pname,
const GLfixed *params)
{
- UNIMPLEMENTED();
- return true;
+ GLfloat paramsf[4];
+ for (unsigned int i = 0; i < GetTextureEnvParameterCount(pname); i++)
+ {
+ paramsf[i] = static_cast<GLfloat>(params[i]);
+ }
+ return ValidateTexEnvCommon(context, target, pname, paramsf);
}
bool ValidateTexParameterx(Context *context, TextureType target, GLenum pname, GLfixed param)
diff --git a/src/tests/angle_end2end_tests.gypi b/src/tests/angle_end2end_tests.gypi
index a53cfd2..0265b05 100644
--- a/src/tests/angle_end2end_tests.gypi
+++ b/src/tests/angle_end2end_tests.gypi
@@ -65,6 +65,7 @@
'<(angle_path)/src/tests/gl_tests/gles1/MatrixStackTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/LightsTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/ShadeModelTest.cpp',
+ '<(angle_path)/src/tests/gl_tests/gles1/TextureEnvTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/TextureTargetEnableTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/VertexPointerTest.cpp',
'<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
diff --git a/src/tests/gl_tests/gles1/TextureEnvTest.cpp b/src/tests/gl_tests/gles1/TextureEnvTest.cpp
new file mode 100644
index 0000000..da01824
--- /dev/null
+++ b/src/tests/gl_tests/gles1/TextureEnvTest.cpp
@@ -0,0 +1,366 @@
+//
+// 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.
+//
+
+// TextureEnvTest.cpp: Tests basic usage of texture environments.
+
+#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
+#include "random_utils.h"
+
+#include <stdint.h>
+
+using namespace angle;
+
+class TextureEnvTest : public ANGLETest
+{
+ protected:
+ TextureEnvTest()
+ {
+ setWindowWidth(32);
+ setWindowHeight(32);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+ }
+
+ void verifyEnvironment(GLenum mode,
+ GLenum combineRgb,
+ GLenum combineAlpha,
+ GLenum src0Rgb,
+ GLenum src0Alpha,
+ GLenum src1Rgb,
+ GLenum src1Alpha,
+ GLenum src2Rgb,
+ GLenum src2Alpha,
+ GLenum op0Rgb,
+ GLenum op0Alpha,
+ GLenum op1Rgb,
+ GLenum op1Alpha,
+ GLenum op2Rgb,
+ GLenum op2Alpha,
+ const GLColor32F &envColor,
+ GLfloat rgbScale,
+ GLfloat alphaScale)
+ {
+
+ GLfloat actualParams[4] = {};
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(mode, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_COMBINE_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(combineRgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(combineAlpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_SRC0_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(src0Rgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_SRC0_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(src0Alpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_SRC1_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(src1Rgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_SRC1_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(src1Alpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_SRC2_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(src2Rgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_SRC2_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(src2Alpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_OPERAND0_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(op0Rgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(op0Alpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_OPERAND1_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(op1Rgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(op1Alpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_OPERAND2_RGB, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(op2Rgb, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(op2Alpha, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_EQ(envColor.R, actualParams[0]);
+ EXPECT_EQ(envColor.G, actualParams[1]);
+ EXPECT_EQ(envColor.B, actualParams[2]);
+ EXPECT_EQ(envColor.A, actualParams[3]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_RGB_SCALE, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_EQ(rgbScale, actualParams[0]);
+
+ glGetTexEnvfv(GL_TEXTURE_ENV, GL_ALPHA_SCALE, actualParams);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_EQ(alphaScale, actualParams[0]);
+ }
+};
+
+// Initial state check.
+TEST_P(TextureEnvTest, InitialState)
+{
+ GLint numUnits;
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS, &numUnits);
+ EXPECT_GL_NO_ERROR();
+
+ for (int i = 0; i < numUnits; i++)
+ {
+ glActiveTexture(GL_TEXTURE0 + i);
+ EXPECT_GL_NO_ERROR();
+
+ verifyEnvironment(GL_MODULATE, // envMode
+ GL_MODULATE, // combineRgb
+ GL_MODULATE, // combineAlpha
+ GL_TEXTURE, // src0Rgb
+ GL_TEXTURE, // src0Alpha
+ GL_PREVIOUS, // src1Rgb
+ GL_PREVIOUS, // src1Alpha
+ GL_CONSTANT, // src2Rgb
+ GL_CONSTANT, // src2Alpha
+ GL_SRC_COLOR, // op0Rgb
+ GL_SRC_ALPHA, // op0Alpha
+ GL_SRC_COLOR, // op1Rgb
+ GL_SRC_ALPHA, // op1Alpha
+ GL_SRC_ALPHA, // op2Rgb
+ GL_SRC_ALPHA, // op2Alpha
+ GLColor32F(0.0f, 0.0f, 0.0f, 0.0f), // envColor
+ 1.0f, // rgbScale
+ 1.0f // alphaScale
+ );
+ }
+}
+
+// Negative test for parameter names.
+TEST_P(TextureEnvTest, NegativeParameter)
+{
+ glTexEnvfv(0, GL_ALPHA_SCALE, nullptr);
+ EXPECT_GL_ERROR(GL_INVALID_ENUM);
+ glTexEnvfv(GL_ALPHA_SCALE, GL_ALPHA_SCALE, nullptr);
+ EXPECT_GL_ERROR(GL_INVALID_ENUM);
+ glTexEnvfv(GL_TEXTURE_ENV, 0, nullptr);
+ EXPECT_GL_ERROR(GL_INVALID_ENUM);
+}
+
+// Negative test for parameter values.
+TEST_P(TextureEnvTest, NegativeValues)
+{
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_SRC2_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_SRC2_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, 0.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, (GLfloat)GL_DOT3_RGB);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, (GLfloat)GL_DOT3_RGBA);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, (GLfloat)GL_SRC_COLOR);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, (GLfloat)GL_ONE_MINUS_SRC_COLOR);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, (GLfloat)GL_SRC_COLOR);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, (GLfloat)GL_ONE_MINUS_SRC_COLOR);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, (GLfloat)GL_SRC_COLOR);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, (GLfloat)GL_ONE_MINUS_SRC_COLOR);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 0.5f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 3.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 0.5f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+ glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 3.0f);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
+// Checks that texture environment state can be set.
+TEST_P(TextureEnvTest, Set)
+{
+ const int kTrials = 1000;
+
+ angle::RNG rng(0);
+
+ GLint numUnits;
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS, &numUnits);
+ EXPECT_GL_NO_ERROR();
+
+ std::vector<GLenum> validUnits(numUnits);
+ for (int i = 0; i < numUnits; i++)
+ {
+ validUnits[i] = GL_TEXTURE0 + i;
+ }
+
+ std::vector<GLenum> validEnvModes = {
+ GL_ADD, GL_BLEND, GL_COMBINE, GL_DECAL, GL_MODULATE, GL_REPLACE,
+ };
+
+ std::vector<GLenum> validCombineRgbs = {
+ GL_MODULATE, GL_REPLACE, GL_ADD, GL_ADD_SIGNED,
+ GL_SUBTRACT, GL_INTERPOLATE, GL_DOT3_RGB, GL_DOT3_RGBA,
+ };
+
+ std::vector<GLenum> validCombineAlphas = {
+ GL_MODULATE, GL_REPLACE, GL_ADD, GL_ADD_SIGNED, GL_SUBTRACT, GL_INTERPOLATE,
+ };
+
+ std::vector<GLenum> validSrcs = {
+ GL_CONSTANT, GL_PREVIOUS, GL_PRIMARY_COLOR, GL_TEXTURE,
+ };
+
+ std::vector<GLenum> validOpRgbs = {
+ GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+ };
+
+ std::vector<GLenum> validOpAlphas = {
+ GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+ };
+
+ std::vector<GLfloat> validScales = {
+ 1.0f, 2.0f, 4.0f,
+ };
+
+ for (int i = 0; i < kTrials; i++)
+ {
+ GLenum textureUnit = rng.randomSelect(validUnits);
+ GLenum mode = rng.randomSelect(validEnvModes);
+ GLenum combineRgb = rng.randomSelect(validCombineRgbs);
+ GLenum combineAlpha = rng.randomSelect(validCombineAlphas);
+
+ GLenum src0Rgb = rng.randomSelect(validSrcs);
+ GLenum src0Alpha = rng.randomSelect(validSrcs);
+ GLenum src1Rgb = rng.randomSelect(validSrcs);
+ GLenum src1Alpha = rng.randomSelect(validSrcs);
+ GLenum src2Rgb = rng.randomSelect(validSrcs);
+ GLenum src2Alpha = rng.randomSelect(validSrcs);
+
+ GLenum op0Rgb = rng.randomSelect(validOpRgbs);
+ GLenum op0Alpha = rng.randomSelect(validOpAlphas);
+ GLenum op1Rgb = rng.randomSelect(validOpRgbs);
+ GLenum op1Alpha = rng.randomSelect(validOpAlphas);
+ GLenum op2Rgb = rng.randomSelect(validOpRgbs);
+ GLenum op2Alpha = rng.randomSelect(validOpAlphas);
+
+ GLColor32F envColor(rng.randomFloatBetween(0.0f, 1.0f), rng.randomFloatBetween(0.0f, 1.0f),
+ rng.randomFloatBetween(0.0f, 1.0f), rng.randomFloatBetween(0.0f, 1.0f));
+
+ GLfloat rgbScale = rng.randomSelect(validScales);
+ GLfloat alphaScale = rng.randomSelect(validScales);
+
+ glActiveTexture(textureUnit);
+ EXPECT_GL_NO_ERROR();
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha);
+ EXPECT_GL_NO_ERROR();
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, src0Rgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, src1Rgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, src1Alpha);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, src2Rgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, src2Alpha);
+ EXPECT_GL_NO_ERROR();
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, op0Rgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, op0Alpha);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, op1Rgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, op1Alpha);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, op2Rgb);
+ EXPECT_GL_NO_ERROR();
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, op2Alpha);
+ EXPECT_GL_NO_ERROR();
+
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &envColor.R);
+ EXPECT_GL_NO_ERROR();
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, rgbScale);
+ EXPECT_GL_NO_ERROR();
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, alphaScale);
+ EXPECT_GL_NO_ERROR();
+
+ verifyEnvironment(mode, combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha,
+ src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb, op2Alpha,
+ envColor, rgbScale, alphaScale);
+ }
+}
+
+ANGLE_INSTANTIATE_TEST(TextureEnvTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());