Commit 461b09a8 by Lingfeng Yang Committed by Commit Bot

GLES1: Renderer (minimal)

This is the renderer code for GLES1 that delivers basic vertex attributes, matrices, and allows texturing for unit 0 only (more units mean implementing the multitexturing pipeline). + Sample + Update test expectations for GLES1 conformance tests BUG=angleproject:2554 BUG=angleproject:2306 Change-Id: I398edc764f982fbfc4c5e0f9d6bfef1e91aec47c Reviewed-on: https://chromium-review.googlesource.com/1057356Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Lingfeng Yang <lfy@google.com>
parent 5d2ccc53
...@@ -31,6 +31,7 @@ static_library("sample_util") { ...@@ -31,6 +31,7 @@ static_library("sample_util") {
"../:angle_common", "../:angle_common",
"../:angle_util", "../:angle_util",
"../:libEGL${angle_libs_suffix}", "../:libEGL${angle_libs_suffix}",
"../:libGLESv1_CM${angle_libs_suffix}",
"../:libGLESv2${angle_libs_suffix}", "../:libGLESv2${angle_libs_suffix}",
] ]
public_configs = [ ":sample_util_config" ] public_configs = [ ":sample_util_config" ]
...@@ -172,6 +173,18 @@ angle_sample("window_test") { ...@@ -172,6 +173,18 @@ angle_sample("window_test") {
] ]
} }
angle_sample("gles1_hello_triangle") {
sources = [
"gles1/HelloTriangle.cpp",
]
}
angle_sample("gles1_simple_texture_2d") {
sources = [
"gles1/SimpleTexture2D.cpp",
]
}
group("all") { group("all") {
testonly = true testonly = true
deps = [ deps = [
......
//
// 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.
//
// Based on Hello_Triangle.c from
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
#include "SampleApplication.h"
#include "shader_utils.h"
#include <GLES/gl.h>
class GLES1HelloTriangleSample : public SampleApplication
{
public:
GLES1HelloTriangleSample(EGLint displayType)
: SampleApplication("GLES1HelloTriangle", 1280, 720, 1, 0, displayType)
{
}
bool initialize() override
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
return true;
}
void destroy() override {}
void draw() override
{
GLfloat vertices[] = {
0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f,
};
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
};
int main(int argc, char **argv)
{
EGLint displayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
if (argc > 1)
{
displayType = GetDisplayTypeFromArg(argv[1]);
}
GLES1HelloTriangleSample app(displayType);
return app.run();
}
//
// 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.
//
// Based on Simple_Texture2D.c from
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
#include "SampleApplication.h"
#include "shader_utils.h"
#include "texture_utils.h"
#include <GLES/gl.h>
class GLES1SimpleTexture2DSample : public SampleApplication
{
public:
GLES1SimpleTexture2DSample(EGLint displayType)
: SampleApplication("GLES1SimpleTexture2D", 1280, 720, 1, 0, displayType)
{
}
bool initialize() override
{
// Load the texture
mTexture = CreateSimpleTexture2D();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_TEXTURE_2D);
return true;
}
void destroy() override { glDeleteTextures(1, &mTexture); }
void draw() override
{
GLfloat vertices[] = {
-0.5f, 0.5f, 0.0f, // Position 0
0.0f, 0.0f, // TexCoord 0
-0.5f, -0.5f, 0.0f, // Position 1
0.0f, 1.0f, // TexCoord 1
0.5f, -0.5f, 0.0f, // Position 2
1.0f, 1.0f, // TexCoord 2
0.5f, 0.5f, 0.0f, // Position 3
1.0f, 0.0f // TexCoord 3
};
GLushort indices[] = {0, 1, 2, 0, 2, 3};
// Set the viewport
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Load the vertex position
glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), vertices);
// Load the texture coordinate
glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), vertices + 3);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Bind the texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
private:
// Texture handle
GLuint mTexture = 0;
};
int main(int argc, char **argv)
{
EGLint displayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
if (argc > 1)
{
displayType = GetDisplayTypeFromArg(argv[1]);
}
GLES1SimpleTexture2DSample app(displayType);
return app.run();
}
...@@ -57,7 +57,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) ...@@ -57,7 +57,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
mResources(), mResources(),
mShaderCompilers({}) mShaderCompilers({})
{ {
ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3); ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
state.getClientMajorVersion() == 3);
const gl::Caps &caps = state.getCaps(); const gl::Caps &caps = state.getCaps();
const gl::Extensions &extensions = state.getExtensions(); const gl::Extensions &extensions = state.getExtensions();
...@@ -74,8 +75,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) ...@@ -74,8 +75,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
mResources.OES_standard_derivatives = extensions.standardDerivatives; mResources.OES_standard_derivatives = extensions.standardDerivatives;
mResources.EXT_draw_buffers = extensions.drawBuffers; mResources.EXT_draw_buffers = extensions.drawBuffers;
mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD; mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD;
mResources.OES_EGL_image_external = extensions.eglImageExternal; mResources.OES_EGL_image_external = extensions.eglImageExternal;
mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3; mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3;
mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal; mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal;
mResources.ARB_texture_rectangle = extensions.textureRectangle; mResources.ARB_texture_rectangle = extensions.textureRectangle;
// TODO: use shader precision caps to determine if high precision is supported? // TODO: use shader precision caps to determine if high precision is supported?
...@@ -124,7 +125,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) ...@@ -124,7 +125,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers; mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize; mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize;
mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings; mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings;
mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings; mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
// Needed by point size clamping workaround // Needed by point size clamping workaround
...@@ -144,11 +145,11 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) ...@@ -144,11 +145,11 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
mResources.MaxGeometryOutputVertices = caps.maxGeometryOutputVertices; mResources.MaxGeometryOutputVertices = caps.maxGeometryOutputVertices;
mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents; mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry]; mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
mResources.MaxGeometryAtomicCounterBuffers = caps.maxGeometryAtomicCounterBuffers; mResources.MaxGeometryAtomicCounterBuffers = caps.maxGeometryAtomicCounterBuffers;
mResources.MaxGeometryAtomicCounters = caps.maxGeometryAtomicCounters; mResources.MaxGeometryAtomicCounters = caps.maxGeometryAtomicCounters;
mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry]; mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
mResources.MaxGeometryShaderInvocations = caps.maxGeometryShaderInvocations; mResources.MaxGeometryShaderInvocations = caps.maxGeometryShaderInvocations;
mResources.MaxGeometryImageUniforms = caps.maxGeometryImageUniforms; mResources.MaxGeometryImageUniforms = caps.maxGeometryImageUniforms;
} }
Compiler::~Compiler() Compiler::~Compiler()
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "libANGLE/Fence.h" #include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h" #include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/GLES1Renderer.h"
#include "libANGLE/Path.h" #include "libANGLE/Path.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/ProgramPipeline.h" #include "libANGLE/ProgramPipeline.h"
...@@ -388,6 +389,12 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -388,6 +389,12 @@ Context::Context(rx::EGLImplFactory *implFactory,
bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1); bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1);
} }
// Initialize GLES1 renderer if appropriate.
if (getClientVersion() < Version(2, 0))
{
mGLES1Renderer.reset(new GLES1Renderer());
}
// Initialize dirty bit masks // Initialize dirty bit masks
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE); mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING); mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
...@@ -431,6 +438,11 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -431,6 +438,11 @@ Context::Context(rx::EGLImplFactory *implFactory,
egl::Error Context::onDestroy(const egl::Display *display) egl::Error Context::onDestroy(const egl::Display *display)
{ {
if (mGLES1Renderer)
{
mGLES1Renderer->onDestroy(this, &mGLState);
}
// Delete the Surface first to trigger a finish() in Vulkan. // Delete the Surface first to trigger a finish() in Vulkan.
if (mSurfacelessFramebuffer) if (mSurfacelessFramebuffer)
{ {
...@@ -3269,6 +3281,11 @@ void Context::initWorkarounds() ...@@ -3269,6 +3281,11 @@ void Context::initWorkarounds()
Error Context::prepareForDraw() Error Context::prepareForDraw()
{ {
if (mGLES1Renderer)
{
ANGLE_TRY(mGLES1Renderer->prepareForDraw(this, &mGLState));
}
ANGLE_TRY(syncDirtyObjects()); ANGLE_TRY(syncDirtyObjects());
if (isRobustResourceInitEnabled()) if (isRobustResourceInitEnabled())
......
...@@ -48,19 +48,20 @@ namespace gl ...@@ -48,19 +48,20 @@ namespace gl
class Buffer; class Buffer;
class Compiler; class Compiler;
class FenceNV; class FenceNV;
class Sync;
class Framebuffer; class Framebuffer;
class GLES1Renderer;
class MemoryProgramCache; class MemoryProgramCache;
class Program; class Program;
class ProgramPipeline;
class Query; class Query;
class Renderbuffer; class Renderbuffer;
class Sampler; class Sampler;
class Shader; class Shader;
class Sync;
class Texture; class Texture;
class TransformFeedback; class TransformFeedback;
class VertexArray; class VertexArray;
struct VertexAttribute; struct VertexAttribute;
class ProgramPipeline;
class Context final : angle::NonCopyable class Context final : angle::NonCopyable
{ {
...@@ -1458,6 +1459,8 @@ class Context final : angle::NonCopyable ...@@ -1458,6 +1459,8 @@ class Context final : angle::NonCopyable
// GLES1 emulation: Renderer level (for validation) // GLES1 emulation: Renderer level (for validation)
int vertexArrayIndex(ClientVertexArrayType type) const; int vertexArrayIndex(ClientVertexArrayType type) const;
static int TexCoordArrayIndex(unsigned int unit);
AttributesMask getVertexArraysAttributeMask() const;
private: private:
Error prepareForDraw(); Error prepareForDraw();
...@@ -1556,6 +1559,9 @@ class Context final : angle::NonCopyable ...@@ -1556,6 +1559,9 @@ class Context final : angle::NonCopyable
typedef std::set<GLenum> ErrorSet; typedef std::set<GLenum> ErrorSet;
mutable ErrorSet mErrors; mutable ErrorSet mErrors;
// GLES1 renderer state
std::unique_ptr<GLES1Renderer> mGLES1Renderer;
// Current/lost context flags // Current/lost context flags
bool mHasBeenCurrent; bool mHasBeenCurrent;
mutable bool mContextLost; mutable bool mContextLost;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "common/mathutil.h" #include "common/mathutil.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/GLES1Renderer.h"
namespace namespace
{ {
...@@ -607,22 +609,18 @@ void Context::texGenxv(GLenum coord, GLenum pname, const GLint *params) ...@@ -607,22 +609,18 @@ void Context::texGenxv(GLenum coord, GLenum pname, const GLint *params)
int Context::vertexArrayIndex(ClientVertexArrayType type) const int Context::vertexArrayIndex(ClientVertexArrayType type) const
{ {
switch (type) return mGLES1Renderer->vertexArrayIndex(type, &mGLState);
{ }
case ClientVertexArrayType::Vertex:
return 0; // static
case ClientVertexArrayType::Normal: int Context::TexCoordArrayIndex(unsigned int unit)
return 1; {
case ClientVertexArrayType::Color: return GLES1Renderer::TexCoordArrayIndex(unit);
return 2; }
case ClientVertexArrayType::PointSize:
return 3; AttributesMask Context::getVertexArraysAttributeMask() const
case ClientVertexArrayType::TextureCoord: {
return 4 + mGLState.gles1().getClientTextureUnit(); return mGLES1Renderer->getVertexArraysAttributeMask(&mGLState);
default:
UNREACHABLE();
return 0;
}
} }
// static // static
......
//
// 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.
//
// GLES1Renderer.h: Defines GLES1 emulation rendering operations on top of a GLES3
// context. Used by Context.h.
#ifndef LIBANGLE_GLES1_RENDERER_H_
#define LIBANGLE_GLES1_RENDERER_H_
#include "angle_gl.h"
#include "common/angleutils.h"
#include "libANGLE/angletypes.h"
#include <memory>
#include <string>
#include <unordered_map>
namespace gl
{
class Context;
class Program;
class State;
class Shader;
class ShaderProgramManager;
class GLES1Renderer final : angle::NonCopyable
{
public:
GLES1Renderer();
~GLES1Renderer();
void onDestroy(Context *context, State *state);
Error prepareForDraw(Context *context, State *glState);
int vertexArrayIndex(ClientVertexArrayType type, const State *glState) const;
static int TexCoordArrayIndex(unsigned int unit);
AttributesMask getVertexArraysAttributeMask(const State *glState) const;
private:
using Mat4Uniform = float[16];
Shader *getShader(GLuint handle) const;
Program *getProgram(GLuint handle) const;
Error compileShader(Context *context,
ShaderType shaderType,
const char *src,
GLuint *shaderOut);
Error linkProgram(Context *context,
State *glState,
GLuint vshader,
GLuint fshader,
const std::unordered_map<GLint, std::string> &attribLocs,
GLuint *programOut);
Error initializeRendererProgram(Context *context, State *glState);
static constexpr int kTexUnitCount = 4;
static constexpr int kVertexAttribIndex = 0;
static constexpr int kNormalAttribIndex = 1;
static constexpr int kColorAttribIndex = 2;
static constexpr int kPointSizeAttribIndex = 3;
static constexpr int kTextureCoordAttribIndexBase = 4;
bool mRendererProgramInitialized;
ShaderProgramManager *mShaderPrograms;
struct GLES1ProgramState
{
GLuint program;
GLint projMatrixLoc;
GLint modelviewMatrixLoc;
GLint textureMatrixLoc;
GLint modelviewInvTrLoc;
std::array<GLint, kTexUnitCount> tex2DSamplerLocs;
std::array<GLint, kTexUnitCount> texCubeSamplerLocs;
GLint shadeModelFlatLoc;
GLint enableTexture2DLoc;
GLint enableTextureCubeMapLoc;
};
struct GLES1UniformBuffers
{
std::array<Mat4Uniform, kTexUnitCount> textureMatrices;
std::array<GLint, kTexUnitCount> tex2DEnables;
std::array<GLint, kTexUnitCount> texCubeEnables;
};
GLES1UniformBuffers mUniformBuffers;
GLES1ProgramState mProgramState;
};
} // namespace gl
#endif // LIBANGLE_GLES1_RENDERER_H_
//
// 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.
//
// GLES1Shaders.inc: Defines GLES1 emulation shader.
constexpr char kGLES1DrawVShader[] = R"(#version 300 es
precision highp float;
#define kMaxTexUnits 4
in vec4 pos;
in vec3 normal;
in vec4 color;
in float pointsize;
in vec4 texcoord0;
in vec4 texcoord1;
in vec4 texcoord2;
in vec4 texcoord3;
uniform mat4 projection;
uniform mat4 modelview;
uniform mat4 modelview_invtr;
uniform mat4 texture_matrix[4];
out vec4 pos_varying;
out vec3 normal_varying;
out vec4 color_varying;
flat out vec4 color_varying_flat;
out float pointsize_varying;
out vec4 texcoord0_varying;
out vec4 texcoord1_varying;
out vec4 texcoord2_varying;
out vec4 texcoord3_varying;
void main()
{
pos_varying = modelview * pos;
mat3 mvInvTr3 = mat3(modelview_invtr);
normal_varying = mvInvTr3 * normal;
color_varying = color;
color_varying_flat = color;
pointsize_varying = pointsize;
texcoord0_varying = texture_matrix[0] * texcoord0;
texcoord1_varying = texture_matrix[1] * texcoord1;
texcoord2_varying = texture_matrix[2] * texcoord2;
texcoord3_varying = texture_matrix[3] * texcoord3;
vec4 vertexPos = projection * modelview * pos;
gl_Position = vertexPos;
}
)";
// version, flat,
constexpr char kGLES1DrawFShaderHeader[] = R"(#version 300 es
precision highp float;
// Defines for GL constants
#define kMaxLights 8
#define kMaxTexUnits 4
#define kModulate 0x2100
#define kDecal 0x2101
#define kCombine 0x8570
#define kReplace 0x1E01
#define kBlend 0x0BE2
#define kAdd 0x0104
#define kAddSigned 0x8574
#define kInterpolate 0x8575
#define kSubtract 0x84E7
#define kDot3Rgb 0x86AE
#define kDot3Rgba 0x86AF
#define kAlpha 0x1906
#define kRGB 0x1907
#define kRGBA 0x1908
#define kLuminance 0x1909
#define kLuminanceAlpha 0x190A
#define kTexture 0x1702
#define kConstant 0x8576
#define kPrimaryColor 0x8577
#define kPrevious 0x8578
#define kSrcColor 0x0300
#define kOneMinusSrcColor 0x0301
#define kSrcAlpha 0x0302
#define kOneMinusSrcAlpha 0x0303
#define kLinear 0x2601
#define kExp 0x0800
#define kExp2 0x0801
#define kNever 0x0200
#define kLess 0x0201
#define kEqual 0x0202
#define kLequal 0x0203
#define kGreater 0x0204
#define kNotequal 0x0205
#define kGequal 0x0206
#define kAlways 0x0207
#define kZero 0x0
#define kOne 0x1
#define kClear 0x1500
#define kAnd 0x1501
#define kAnd_reverse 0x1502
#define kCopy 0x1503
#define kAnd_inverted 0x1504
#define kNoop 0x1505
#define kXor 0x1506
#define kOr 0x1507
#define kNor 0x1508
#define kEquiv 0x1509
#define kInvert 0x150A
#define kOr_reverse 0x150B
#define kCopy_inverted 0x150C
#define kOr_inverted 0x150D
#define kNand 0x150E
#define kSet 0x150F)";
constexpr char kGLES1DrawFShaderUniformDefs[] = R"(
// Texture units ///////////////////////////////////////////////////////////////
uniform bool enable_texture_2d[kMaxTexUnits];
uniform bool enable_texture_cube_map[kMaxTexUnits];
// These are not arrays because hw support for arrays
// of samplers is rather lacking.
uniform sampler2D tex_sampler0;
uniform samplerCube tex_cube_sampler0;
uniform sampler2D tex_sampler1;
uniform samplerCube tex_cube_sampler1;
uniform sampler2D tex_sampler2;
uniform samplerCube tex_cube_sampler2;
uniform sampler2D tex_sampler3;
uniform samplerCube tex_cube_sampler3;
// Global enables, alpha func, logic op ////////////////////////////////////////
uniform bool shade_model_flat;
// Vertex attributes////////////////////////////////////////////////////////////
in vec4 pos_varying;
in vec3 normal_varying;
in vec4 color_varying;
flat in vec4 color_varying_flat;
in float pointsize_varying;
in vec4 texcoord0_varying;
in vec4 texcoord1_varying;
in vec4 texcoord2_varying;
in vec4 texcoord3_varying;
// Outgoing fragment////////////////////////////////////////////////////////////
out vec4 frag_color;
)";
constexpr char kGLES1DrawFShaderFunctions[] = R"(
bool isTextureUnitEnabled(int unit)
{
return enable_texture_2d[unit] || enable_texture_cube_map[unit];
}
vec4 getTextureColor(int unit)
{
vec4 res;
switch (unit)
{
case 0:
if (enable_texture_2d[0])
{
res = texture(tex_sampler0, texcoord0_varying.xy);
}
else if (enable_texture_cube_map[0])
{
res = texture(tex_cube_sampler0, texcoord0_varying.xyz);
}
break;
case 1:
if (enable_texture_2d[1])
{
res = texture(tex_sampler1, texcoord1_varying.xy);
}
else if (enable_texture_cube_map[1])
{
res = texture(tex_cube_sampler1, texcoord1_varying.xyz);
}
break;
case 2:
if (enable_texture_2d[2])
{
res = texture(tex_sampler2, texcoord2_varying.xy);
}
else if (enable_texture_cube_map[2])
{
res = texture(tex_cube_sampler2, texcoord2_varying.xyz);
}
break;
case 3:
if (enable_texture_2d[3])
{
res = texture(tex_sampler3, texcoord3_varying.xy);
}
else if (enable_texture_cube_map[3])
{
// TODO: Weird stuff happens
// res = texture(tex_cube_sampler3, texcoord3_varying.xyz);
}
break;
default:
break;
}
return res;
}
vec4 getColor(int unit, vec4 vertexColor)
{
if (!isTextureUnitEnabled(unit))
{
return vertexColor;
}
return getTextureColor(unit);
}
)";
constexpr char kGLES1DrawFShaderMain[] = R"(
void main()
{
vec4 currentFragment;
vec4 vertex_color;
if (shade_model_flat)
{
vertex_color = color_varying_flat;
}
else
{
vertex_color = color_varying;
}
// Unit 0 only for now
currentFragment = getColor(0, vertex_color);
frag_color = currentFragment;
}
)";
...@@ -312,6 +312,12 @@ bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const ...@@ -312,6 +312,12 @@ bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
} }
} }
bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
{
ASSERT(unit < mTexCoordArrayEnabled.size());
return mTexCoordArrayEnabled[unit];
}
bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
{ {
return mTexUnitEnables[unit].test(type); return mTexUnitEnables[unit].test(type);
......
...@@ -115,7 +115,9 @@ struct PointParameters ...@@ -115,7 +115,9 @@ struct PointParameters
}; };
class Context; class Context;
class GLES1Renderer;
class State; class State;
class GLES1State final : angle::NonCopyable class GLES1State final : angle::NonCopyable
{ {
public: public:
...@@ -152,10 +154,12 @@ class GLES1State final : angle::NonCopyable ...@@ -152,10 +154,12 @@ class GLES1State final : angle::NonCopyable
void setClientStateEnabled(ClientVertexArrayType clientState, bool enable); void setClientStateEnabled(ClientVertexArrayType clientState, bool enable);
bool isClientStateEnabled(ClientVertexArrayType clientState) const; bool isClientStateEnabled(ClientVertexArrayType clientState) const;
bool isTexCoordArrayEnabled(unsigned int unit) const;
bool isTextureTargetEnabled(unsigned int unit, const TextureType type) const; bool isTextureTargetEnabled(unsigned int unit, const TextureType type) const;
private: private:
friend class State; friend class State;
friend class GLES1Renderer;
// Back pointer for reading from State. // Back pointer for reading from State.
const State *mGLState; const State *mGLState;
......
...@@ -167,6 +167,7 @@ ...@@ -167,6 +167,7 @@
'libANGLE/Framebuffer.h', 'libANGLE/Framebuffer.h',
'libANGLE/FramebufferAttachment.cpp', 'libANGLE/FramebufferAttachment.cpp',
'libANGLE/FramebufferAttachment.h', 'libANGLE/FramebufferAttachment.h',
'libANGLE/GLES1Renderer.cpp',
'libANGLE/GLES1State.cpp', 'libANGLE/GLES1State.cpp',
'libANGLE/HandleAllocator.cpp', 'libANGLE/HandleAllocator.cpp',
'libANGLE/HandleAllocator.h', 'libANGLE/HandleAllocator.h',
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
'<(angle_path)/src/tests/gl_tests/FramebufferTest.cpp', '<(angle_path)/src/tests/gl_tests/FramebufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/GeometryShaderTest.cpp', '<(angle_path)/src/tests/gl_tests/GeometryShaderTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/AlphaFuncTest.cpp', '<(angle_path)/src/tests/gl_tests/gles1/AlphaFuncTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/BasicDrawTest.cpp',
'<(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/ClientStateEnable.cpp', '<(angle_path)/src/tests/gl_tests/gles1/ClientStateEnable.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentColorTest.cpp', '<(angle_path)/src/tests/gl_tests/gles1/CurrentColorTest.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.
//
// BasicDrawTest.cpp: Tests basic fullscreen quad draw with and without
// GL_TEXTURE_2D enabled.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include <vector>
using namespace angle;
class BasicDrawTest : public ANGLETest
{
protected:
BasicDrawTest()
{
setWindowWidth(32);
setWindowHeight(32);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
}
std::vector<float> mPositions = {
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
};
void drawRedQuad()
{
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
EXPECT_GL_NO_ERROR();
glEnableClientState(GL_VERTEX_ARRAY);
EXPECT_GL_NO_ERROR();
glVertexPointer(2, GL_FLOAT, 0, mPositions.data());
EXPECT_GL_NO_ERROR();
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}
};
// Draws a fullscreen quad with a certain color.
TEST_P(BasicDrawTest, DrawColor)
{
drawRedQuad();
}
// Checks that textures can be enabled or disabled.
TEST_P(BasicDrawTest, EnableDisableTexture)
{
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
// Green
GLubyte texture[] = {
0x00, 0xff, 0x00,
};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
// Texturing is disabled; still red;
drawRedQuad();
// Texturing enabled; is green.
glEnable(GL_TEXTURE_2D);
EXPECT_GL_NO_ERROR();
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
ANGLE_INSTANTIATE_TEST(BasicDrawTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());
...@@ -173,25 +173,21 @@ TEST_P(GLES1ConformanceTest, AtnPos) ...@@ -173,25 +173,21 @@ TEST_P(GLES1ConformanceTest, AtnPos)
TEST_P(GLES1ConformanceTest, BClear) TEST_P(GLES1ConformanceTest, BClear)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, BClearExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, BClearExec());
} }
TEST_P(GLES1ConformanceTest, BColor) TEST_P(GLES1ConformanceTest, BColor)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, BColorExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, BColorExec());
} }
TEST_P(GLES1ConformanceTest, BCorner) TEST_P(GLES1ConformanceTest, BCorner)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, BCornerExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, BCornerExec());
} }
TEST_P(GLES1ConformanceTest, Blend) TEST_P(GLES1ConformanceTest, Blend)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, BlendExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, BlendExec());
} }
...@@ -203,7 +199,6 @@ TEST_P(GLES1ConformanceTest, Clip) ...@@ -203,7 +199,6 @@ TEST_P(GLES1ConformanceTest, Clip)
TEST_P(GLES1ConformanceTest, ColRamp) TEST_P(GLES1ConformanceTest, ColRamp)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ColRampExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, ColRampExec());
} }
...@@ -239,7 +234,6 @@ TEST_P(GLES1ConformanceTest, DifMatPos) ...@@ -239,7 +234,6 @@ TEST_P(GLES1ConformanceTest, DifMatPos)
TEST_P(GLES1ConformanceTest, Dither) TEST_P(GLES1ConformanceTest, Dither)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DitherExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, DitherExec());
} }
...@@ -275,13 +269,11 @@ TEST_P(GLES1ConformanceTest, LineAntiAlias) ...@@ -275,13 +269,11 @@ TEST_P(GLES1ConformanceTest, LineAntiAlias)
TEST_P(GLES1ConformanceTest, LineHV) TEST_P(GLES1ConformanceTest, LineHV)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, LineHVExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, LineHVExec());
} }
TEST_P(GLES1ConformanceTest, LineRaster) TEST_P(GLES1ConformanceTest, LineRaster)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, LineRasterExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, LineRasterExec());
} }
...@@ -317,13 +309,11 @@ TEST_P(GLES1ConformanceTest, MipSelect) ...@@ -317,13 +309,11 @@ TEST_P(GLES1ConformanceTest, MipSelect)
TEST_P(GLES1ConformanceTest, Mask) TEST_P(GLES1ConformanceTest, Mask)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, MaskExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, MaskExec());
} }
TEST_P(GLES1ConformanceTest, MatrixStack) TEST_P(GLES1ConformanceTest, MatrixStack)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixStackExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixStackExec());
} }
...@@ -359,13 +349,11 @@ TEST_P(GLES1ConformanceTest, PointRaster) ...@@ -359,13 +349,11 @@ TEST_P(GLES1ConformanceTest, PointRaster)
TEST_P(GLES1ConformanceTest, PolyCull) TEST_P(GLES1ConformanceTest, PolyCull)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, PolyCullExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, PolyCullExec());
} }
TEST_P(GLES1ConformanceTest, ReadFormat) TEST_P(GLES1ConformanceTest, ReadFormat)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ReadFormatExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, ReadFormatExec());
} }
...@@ -377,19 +365,16 @@ TEST_P(GLES1ConformanceTest, RescaleNormal) ...@@ -377,19 +365,16 @@ TEST_P(GLES1ConformanceTest, RescaleNormal)
TEST_P(GLES1ConformanceTest, Scissor) TEST_P(GLES1ConformanceTest, Scissor)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ScissorExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, ScissorExec());
} }
TEST_P(GLES1ConformanceTest, SPClear) TEST_P(GLES1ConformanceTest, SPClear)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SPClearExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, SPClearExec());
} }
TEST_P(GLES1ConformanceTest, SPCorner) TEST_P(GLES1ConformanceTest, SPCorner)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SPCornerExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, SPCornerExec());
} }
...@@ -425,13 +410,11 @@ TEST_P(GLES1ConformanceTest, SpecNorm) ...@@ -425,13 +410,11 @@ TEST_P(GLES1ConformanceTest, SpecNorm)
TEST_P(GLES1ConformanceTest, SPFunc) TEST_P(GLES1ConformanceTest, SPFunc)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SPFuncExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, SPFuncExec());
} }
TEST_P(GLES1ConformanceTest, SPOp) TEST_P(GLES1ConformanceTest, SPOp)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SPOpExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, SPOpExec());
} }
...@@ -473,25 +456,21 @@ TEST_P(GLES1ConformanceTest, TextureEdgeClamp) ...@@ -473,25 +456,21 @@ TEST_P(GLES1ConformanceTest, TextureEdgeClamp)
TEST_P(GLES1ConformanceTest, TriRaster) TEST_P(GLES1ConformanceTest, TriRaster)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, TriRasterExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, TriRasterExec());
} }
TEST_P(GLES1ConformanceTest, TriTile) TEST_P(GLES1ConformanceTest, TriTile)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, TriTileExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, TriTileExec());
} }
TEST_P(GLES1ConformanceTest, VertexOrder) TEST_P(GLES1ConformanceTest, VertexOrder)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, VertexOrderExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, VertexOrderExec());
} }
TEST_P(GLES1ConformanceTest, ViewportClamp) TEST_P(GLES1ConformanceTest, ViewportClamp)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ViewportClampExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, ViewportClampExec());
} }
...@@ -503,7 +482,6 @@ TEST_P(GLES1ConformanceTest, XForm) ...@@ -503,7 +482,6 @@ TEST_P(GLES1ConformanceTest, XForm)
TEST_P(GLES1ConformanceTest, XFormMix) TEST_P(GLES1ConformanceTest, XFormMix)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, XFormMixExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, XFormMixExec());
} }
...@@ -527,25 +505,21 @@ TEST_P(GLES1ConformanceTest, XFormHomogenous) ...@@ -527,25 +505,21 @@ TEST_P(GLES1ConformanceTest, XFormHomogenous)
TEST_P(GLES1ConformanceTest, ZBClear) TEST_P(GLES1ConformanceTest, ZBClear)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ZBClearExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, ZBClearExec());
} }
TEST_P(GLES1ConformanceTest, ZBFunc) TEST_P(GLES1ConformanceTest, ZBFunc)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ZBFuncExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, ZBFuncExec());
} }
TEST_P(GLES1ConformanceTest, DrawTex) TEST_P(GLES1ConformanceTest, DrawTex)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DrawTexExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, DrawTexExec());
} }
TEST_P(GLES1ConformanceTest, MatrixQuery) TEST_P(GLES1ConformanceTest, MatrixQuery)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixQueryExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixQueryExec());
} }
...@@ -575,7 +549,6 @@ TEST_P(GLES1ConformanceTest, UserClip) ...@@ -575,7 +549,6 @@ TEST_P(GLES1ConformanceTest, UserClip)
TEST_P(GLES1ConformanceTest, MatrixGetTest) TEST_P(GLES1ConformanceTest, MatrixGetTest)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixGetTestExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixGetTestExec());
} }
...@@ -593,7 +566,6 @@ TEST_P(GLES1ConformanceTest, TexCombine) ...@@ -593,7 +566,6 @@ TEST_P(GLES1ConformanceTest, TexCombine)
TEST_P(GLES1ConformanceTest, MatrixPalette) TEST_P(GLES1ConformanceTest, MatrixPalette)
{ {
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixPaletteExec()); ASSERT_NE(CONFORMANCE_TEST_ERROR, MatrixPaletteExec());
} }
......
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