Commit 038dd539 by Lingfeng Yang Committed by Commit Bot

GLES1: glMultiTexCoord4(f|x)

BUG=angleproject:2306 + common validation for multitexturing units + clang-format Change-Id: I6eb456c273490e85fc7008e7e11d15e22dd20276 Reviewed-on: https://chromium-review.googlesource.com/987298 Commit-Queue: Lingfeng Yang <lfy@google.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 858c1ccc
...@@ -6400,6 +6400,10 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu ...@@ -6400,6 +6400,10 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*type = GL_FLOAT; *type = GL_FLOAT;
*numParams = 3; *numParams = 3;
return true; return true;
case GL_CURRENT_TEXTURE_COORDS:
*type = GL_FLOAT;
*numParams = 4;
return true;
} }
} }
......
...@@ -279,12 +279,17 @@ void Context::multMatrixx(const GLfixed *m) ...@@ -279,12 +279,17 @@ void Context::multMatrixx(const GLfixed *m)
void Context::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) void Context::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{ {
UNIMPLEMENTED(); unsigned int unit = target - GL_TEXTURE0;
ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits);
mGLState.gles1().setCurrentTextureCoords(unit, {s, t, r, q});
} }
void Context::multiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q) void Context::multiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
{ {
UNIMPLEMENTED(); unsigned int unit = target - GL_TEXTURE0;
ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits);
mGLState.gles1().setCurrentTextureCoords(
unit, {FixedToFloat(s), FixedToFloat(t), FixedToFloat(r), FixedToFloat(q)});
} }
void Context::normal3f(GLfloat nx, GLfloat ny, GLfloat nz) void Context::normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
......
...@@ -14,6 +14,17 @@ ...@@ -14,6 +14,17 @@
namespace gl namespace gl
{ {
TextureCoordF::TextureCoordF() = default;
TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q)
{
}
bool TextureCoordF::operator==(const TextureCoordF &other) const
{
return s == other.s && t == other.t && r == other.r && q == other.q;
}
GLES1State::GLES1State() GLES1State::GLES1State()
: mVertexArrayEnabled(false), : mVertexArrayEnabled(false),
mNormalArrayEnabled(false), mNormalArrayEnabled(false),
...@@ -179,4 +190,14 @@ const angle::Vector3 &GLES1State::getCurrentNormal() const ...@@ -179,4 +190,14 @@ const angle::Vector3 &GLES1State::getCurrentNormal() const
return mCurrentNormal; return mCurrentNormal;
} }
void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
{
mCurrentTextureCoords[unit] = coords;
}
const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
{
return mCurrentTextureCoords[unit];
}
} // namespace gl } // namespace gl
...@@ -23,6 +23,10 @@ namespace gl ...@@ -23,6 +23,10 @@ namespace gl
// State types specific to GLES1 contexts, from the OpenGL ES 1.1 spec "State Tables" section // State types specific to GLES1 contexts, from the OpenGL ES 1.1 spec "State Tables" section
struct TextureCoordF struct TextureCoordF
{ {
TextureCoordF();
TextureCoordF(float _s, float _t, float _r, float _q);
bool operator==(const TextureCoordF &other) const;
GLfloat s = 0.0f; GLfloat s = 0.0f;
GLfloat t = 0.0f; GLfloat t = 0.0f;
GLfloat r = 0.0f; GLfloat r = 0.0f;
...@@ -128,6 +132,9 @@ class GLES1State final : angle::NonCopyable ...@@ -128,6 +132,9 @@ class GLES1State final : angle::NonCopyable
void setCurrentNormal(const angle::Vector3 &normal); void setCurrentNormal(const angle::Vector3 &normal);
const angle::Vector3 &getCurrentNormal() const; const angle::Vector3 &getCurrentNormal() const;
void setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords);
const TextureCoordF &getCurrentTextureCoords(unsigned int unit) const;
private: private:
friend class State; friend class State;
......
...@@ -1947,6 +1947,15 @@ void State::getFloatv(GLenum pname, GLfloat *params) ...@@ -1947,6 +1947,15 @@ void State::getFloatv(GLenum pname, GLfloat *params)
params[2] = normal[2]; params[2] = normal[2];
break; break;
} }
case GL_CURRENT_TEXTURE_COORDS:
{
const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
params[0] = texcoord.s;
params[1] = texcoord.t;
params[2] = texcoord.r;
params[3] = texcoord.q;
break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -90,8 +90,8 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi ...@@ -90,8 +90,8 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi
// If we have no buffer, then we either get an error, or there are no more checks to be // If we have no buffer, then we either get an error, or there are no more checks to be
// done. // done.
const VertexBinding &binding = vertexBindings[attrib.bindingIndex]; const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
gl::Buffer *buffer = binding.getBuffer().get(); gl::Buffer *buffer = binding.getBuffer().get();
if (!buffer) if (!buffer)
{ {
if (webglCompatibility || !state.areClientArraysEnabled()) if (webglCompatibility || !state.areClientArraysEnabled())
...@@ -477,7 +477,7 @@ bool ValidateFragmentShaderColorBufferTypeMatch(Context *context) ...@@ -477,7 +477,7 @@ bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
bool ValidateVertexShaderAttributeTypeMatch(Context *context) bool ValidateVertexShaderAttributeTypeMatch(Context *context)
{ {
const auto &glState = context->getGLState(); const auto &glState = context->getGLState();
const Program *program = context->getGLState().getProgram(); const Program *program = context->getGLState().getProgram();
const VertexArray *vao = context->getGLState().getVertexArray(); const VertexArray *vao = context->getGLState().getVertexArray();
...@@ -1333,7 +1333,7 @@ bool ValidateBlitFramebufferParameters(Context *context, ...@@ -1333,7 +1333,7 @@ bool ValidateBlitFramebufferParameters(Context *context,
GLenum drawComponentType = drawFormat.info->componentType; GLenum drawComponentType = drawFormat.info->componentType;
bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
readComponentType == GL_SIGNED_NORMALIZED); readComponentType == GL_SIGNED_NORMALIZED);
bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED || bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
drawComponentType == GL_SIGNED_NORMALIZED); drawComponentType == GL_SIGNED_NORMALIZED);
if (extensions.colorBufferFloat) if (extensions.colorBufferFloat)
...@@ -2753,7 +2753,7 @@ bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count) ...@@ -2753,7 +2753,7 @@ bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count)
uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{ {
const gl::InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); const gl::InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
const OffsetBindingPointer<Buffer> &uniformBuffer = const OffsetBindingPointer<Buffer> &uniformBuffer =
state.getIndexedUniformBuffer(blockBinding); state.getIndexedUniformBuffer(blockBinding);
...@@ -5743,26 +5743,26 @@ bool ValidateTexParameterBase(Context *context, ...@@ -5743,26 +5743,26 @@ bool ValidateTexParameterBase(Context *context,
case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R: case GL_TEXTURE_WRAP_R:
{
bool restrictedWrapModes =
target == TextureType::External || target == TextureType::Rectangle;
if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
{ {
bool restrictedWrapModes = return false;
target == TextureType::External || target == TextureType::Rectangle;
if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
{
return false;
}
} }
break; }
break;
case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MIN_FILTER:
{
bool restrictedMinFilter =
target == TextureType::External || target == TextureType::Rectangle;
if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
{ {
bool restrictedMinFilter = return false;
target == TextureType::External || target == TextureType::Rectangle;
if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
{
return false;
}
} }
break; }
break;
case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MAG_FILTER:
if (!ValidateTextureMagFilterValue(context, params)) if (!ValidateTextureMagFilterValue(context, params))
...@@ -5791,15 +5791,15 @@ bool ValidateTexParameterBase(Context *context, ...@@ -5791,15 +5791,15 @@ bool ValidateTexParameterBase(Context *context,
break; break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_MAX_ANISOTROPY_EXT:
{
GLfloat paramValue = static_cast<GLfloat>(params[0]);
if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
{ {
GLfloat paramValue = static_cast<GLfloat>(params[0]); return false;
if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
{
return false;
}
ASSERT(static_cast<ParamType>(paramValue) == params[0]);
} }
break; ASSERT(static_cast<ParamType>(paramValue) == params[0]);
}
break;
case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_MAX_LOD:
...@@ -6253,4 +6253,14 @@ bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuff ...@@ -6253,4 +6253,14 @@ bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuff
return true; return true;
} }
bool ValidateMultitextureUnit(Context *context, GLenum texture)
{
if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMultitextureUnit);
return false;
}
return true;
}
} // namespace gl } // namespace gl
...@@ -617,6 +617,8 @@ bool ValidateGetInternalFormativBase(Context *context, ...@@ -617,6 +617,8 @@ bool ValidateGetInternalFormativBase(Context *context,
bool ValidateFramebufferComplete(Context *context, Framebuffer *framebuffer, bool isFramebufferOp); bool ValidateFramebufferComplete(Context *context, Framebuffer *framebuffer, bool isFramebufferOp);
bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer); bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer);
bool ValidateMultitextureUnit(Context *context, GLenum texture);
// Utility macro for handling implementation methods inside Validation. // Utility macro for handling implementation methods inside Validation.
#define ANGLE_HANDLE_VALIDATION_ERR(X) \ #define ANGLE_HANDLE_VALIDATION_ERR(X) \
context->handleError(X); \ context->handleError(X); \
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h" #include "libANGLE/ErrorStrings.h"
#include "libANGLE/validationES.h"
#define ANGLE_VALIDATE_IS_GLES1(context) \ #define ANGLE_VALIDATE_IS_GLES1(context) \
if (context->getClientMajorVersion() > 1) \ if (context->getClientMajorVersion() > 1) \
...@@ -73,14 +74,7 @@ bool ValidateClearDepthx(Context *context, GLfixed depth) ...@@ -73,14 +74,7 @@ bool ValidateClearDepthx(Context *context, GLfixed depth)
bool ValidateClientActiveTexture(Context *context, GLenum texture) bool ValidateClientActiveTexture(Context *context, GLenum texture)
{ {
ANGLE_VALIDATE_IS_GLES1(context); ANGLE_VALIDATE_IS_GLES1(context);
if (texture < GL_TEXTURE0 || return ValidateMultitextureUnit(context, texture);
texture > GL_TEXTURE0 + context->getCaps().maxMultitextureUnits - 1)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMultitextureUnit);
return false;
}
return true;
} }
bool ValidateClipPlanef(Context *context, GLenum p, const GLfloat *eqn) bool ValidateClipPlanef(Context *context, GLenum p, const GLfloat *eqn)
...@@ -400,19 +394,19 @@ bool ValidateMultiTexCoord4f(Context *context, ...@@ -400,19 +394,19 @@ bool ValidateMultiTexCoord4f(Context *context,
GLfloat r, GLfloat r,
GLfloat q) GLfloat q)
{ {
UNIMPLEMENTED(); ANGLE_VALIDATE_IS_GLES1(context);
return true; return ValidateMultitextureUnit(context, target);
} }
bool ValidateMultiTexCoord4x(Context *context, bool ValidateMultiTexCoord4x(Context *context,
GLenum texture, GLenum target,
GLfixed s, GLfixed s,
GLfixed t, GLfixed t,
GLfixed r, GLfixed r,
GLfixed q) GLfixed q)
{ {
UNIMPLEMENTED(); ANGLE_VALIDATE_IS_GLES1(context);
return true; return ValidateMultitextureUnit(context, target);
} }
bool ValidateNormal3f(Context *context, GLfloat nx, GLfloat ny, GLfloat nz) bool ValidateNormal3f(Context *context, GLfloat nx, GLfloat ny, GLfloat nz)
......
...@@ -4347,6 +4347,11 @@ bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name) ...@@ -4347,6 +4347,11 @@ bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
bool ValidateActiveTexture(Context *context, GLenum texture) bool ValidateActiveTexture(Context *context, GLenum texture)
{ {
if (context->getClientMajorVersion() < 2)
{
return ValidateMultitextureUnit(context, texture);
}
if (texture < GL_TEXTURE0 || if (texture < GL_TEXTURE0 ||
texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1) texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
{ {
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
'<(angle_path)/src/tests/gl_tests/gles1/ClientActiveTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/gles1/ClientActiveTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentColorTest.cpp', '<(angle_path)/src/tests/gl_tests/gles1/CurrentColorTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentNormalTest.cpp', '<(angle_path)/src/tests/gl_tests/gles1/CurrentNormalTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentTextureCoordsTest.cpp',
'<(angle_path)/src/tests/gl_tests/GLSLTest.cpp', '<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
'<(angle_path)/src/tests/gl_tests/ImageTest.cpp', '<(angle_path)/src/tests/gl_tests/ImageTest.cpp',
'<(angle_path)/src/tests/gl_tests/IncompleteTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/IncompleteTextureTest.cpp',
......
//
// 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.
//
// CurrentTextureCoordsTest.cpp: Tests basic usage of glMultiTexCoord4(f|x).
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "random_utils.h"
#include "common/vector_utils.h"
#include <array>
#include <stdint.h>
using namespace angle;
using TextureCoord = std::array<float, 4>;
class CurrentTextureCoordsTest : public ANGLETest
{
protected:
CurrentTextureCoordsTest()
{
setWindowWidth(32);
setWindowHeight(32);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
}
};
// State query: Checks the initial state is correct.
TEST_P(CurrentTextureCoordsTest, InitialState)
{
GLint maxUnits = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxUnits);
EXPECT_GL_NO_ERROR();
const TextureCoord kZero = {0.0f, 0.0f, 0.0f, 0.0f};
TextureCoord actualTexCoord;
for (GLint i = 0; i < maxUnits; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_CURRENT_TEXTURE_COORDS, actualTexCoord.data());
EXPECT_GL_NO_ERROR();
EXPECT_EQ(kZero, actualTexCoord);
}
}
// Checks that errors are generated if the texture unit specified is invalid.
TEST_P(CurrentTextureCoordsTest, Negative)
{
GLint maxUnits = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxUnits);
EXPECT_GL_NO_ERROR();
glMultiTexCoord4f(GL_TEXTURE0 - 1, 1.0f, 0.0f, 0.0f, 0.0f);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glMultiTexCoord4f(GL_TEXTURE0 + maxUnits, 1.0f, 0.0f, 0.0f, 0.0f);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
// Tests setting and getting the current texture coordinates for each unit and with float/fixed
// inputs.
TEST_P(CurrentTextureCoordsTest, Set)
{
float epsilon = 0.00001f;
GLint maxUnits = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxUnits);
EXPECT_GL_NO_ERROR();
TextureCoord actualTexCoord;
for (int i = 0; i < maxUnits; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glMultiTexCoord4f(GL_TEXTURE0 + i, 0.1f, 0.2f, 0.3f, 0.4f);
glGetFloatv(GL_CURRENT_TEXTURE_COORDS, actualTexCoord.data());
EXPECT_EQ((TextureCoord{0.1f, 0.2f, 0.3f, 0.4f}), actualTexCoord);
glMultiTexCoord4x(GL_TEXTURE0 + i, 0x10000, 0x0, 0x3333, 0x5555);
glGetFloatv(GL_CURRENT_TEXTURE_COORDS, actualTexCoord.data());
EXPECT_NEAR(1.0f, actualTexCoord[0], epsilon);
EXPECT_NEAR(0.0f, actualTexCoord[1], epsilon);
EXPECT_NEAR(0.2f, actualTexCoord[2], epsilon);
EXPECT_NEAR(1.0f / 3.0f, actualTexCoord[3], epsilon);
}
}
ANGLE_INSTANTIATE_TEST(CurrentTextureCoordsTest, 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