Commit 1d672749 by Clemen Deng Committed by Commit Bot

WGL implemetation for OpenGL tutorial

Fixes to make WGL implementation work with OpenGL tutorial - Give directive parser the correct shader spec when on Desktop GL - Minor changes to parse Desktop GL shaders - Moved clientType parameter from Context to Context->mState - Minor fixes to WGL functions Bug: angleproject:3666 Change-Id: I01ddb828f6d581ad445f49942589436849eae5d9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1693244 Commit-Queue: Clemen Deng <clemendeng@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 29fba5e0
...@@ -38,6 +38,8 @@ enum ShShaderSpec ...@@ -38,6 +38,8 @@ enum ShShaderSpec
SH_GLES3_1_SPEC, SH_GLES3_1_SPEC,
SH_WEBGL3_SPEC, SH_WEBGL3_SPEC,
SH_GL3_3_SPEC,
}; };
enum ShShaderOutput enum ShShaderOutput
...@@ -670,6 +672,14 @@ inline bool IsWebGLBasedSpec(ShShaderSpec spec) ...@@ -670,6 +672,14 @@ inline bool IsWebGLBasedSpec(ShShaderSpec spec)
{ {
return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC); return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC);
} }
//
// Helper function to identify DesktopGL specs
//
inline bool IsDesktopGLSpec(ShShaderSpec spec)
{
return spec == SH_GL3_3_SPEC;
}
} // namespace sh } // namespace sh
#endif // GLSLANG_SHADERLANG_H_ #endif // GLSLANG_SHADERLANG_H_
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_ #define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
#include <string> #include <string>
#include "GLSLANG/ShaderLang.h"
namespace angle namespace angle
{ {
...@@ -38,7 +39,7 @@ class DirectiveHandler ...@@ -38,7 +39,7 @@ class DirectiveHandler
const std::string &name, const std::string &name,
const std::string &behavior) = 0; const std::string &behavior) = 0;
virtual void handleVersion(const SourceLocation &loc, int version) = 0; virtual void handleVersion(const SourceLocation &loc, int version, ShShaderSpec spec) = 0;
}; };
} // namespace pp } // namespace pp
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <cstdlib> #include <cstdlib>
#include <sstream> #include <sstream>
#include "GLSLANG/ShaderLang.h"
#include "common/debug.h" #include "common/debug.h"
#include "compiler/preprocessor/DiagnosticsBase.h" #include "compiler/preprocessor/DiagnosticsBase.h"
#include "compiler/preprocessor/DirectiveHandlerBase.h" #include "compiler/preprocessor/DirectiveHandlerBase.h"
...@@ -699,7 +700,8 @@ void DirectiveParser::parseVersion(Token *token) ...@@ -699,7 +700,8 @@ void DirectiveParser::parseVersion(Token *token)
enum State enum State
{ {
VERSION_NUMBER, VERSION_NUMBER,
VERSION_PROFILE, VERSION_PROFILE_ES,
VERSION_PROFILE_GL,
VERSION_ENDLINE VERSION_ENDLINE
}; };
...@@ -727,10 +729,22 @@ void DirectiveParser::parseVersion(Token *token) ...@@ -727,10 +729,22 @@ void DirectiveParser::parseVersion(Token *token)
} }
if (valid) if (valid)
{ {
state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; if (sh::IsDesktopGLSpec(mSettings.shaderSpec))
{
state = VERSION_PROFILE_GL;
}
else if (version < 300)
{
state = VERSION_ENDLINE;
}
else
{
state = VERSION_PROFILE_ES;
}
} }
break; break;
case VERSION_PROFILE: case VERSION_PROFILE_ES:
ASSERT(!sh::IsDesktopGLSpec(mSettings.shaderSpec));
if (token->type != Token::IDENTIFIER || token->text != "es") if (token->type != Token::IDENTIFIER || token->text != "es")
{ {
mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
...@@ -739,6 +753,16 @@ void DirectiveParser::parseVersion(Token *token) ...@@ -739,6 +753,16 @@ void DirectiveParser::parseVersion(Token *token)
} }
state = VERSION_ENDLINE; state = VERSION_ENDLINE;
break; break;
case VERSION_PROFILE_GL:
ASSERT(sh::IsDesktopGLSpec(mSettings.shaderSpec));
if (token->type != Token::IDENTIFIER || token->text != "core")
{
mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
token->text);
valid = false;
}
state = VERSION_ENDLINE;
break;
default: default:
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
token->text); token->text);
...@@ -747,6 +771,11 @@ void DirectiveParser::parseVersion(Token *token) ...@@ -747,6 +771,11 @@ void DirectiveParser::parseVersion(Token *token)
} }
mTokenizer->lex(token); mTokenizer->lex(token);
if (token->type == '\n' && state == VERSION_PROFILE_GL)
{
state = VERSION_ENDLINE;
}
} }
if (valid && (state != VERSION_ENDLINE)) if (valid && (state != VERSION_ENDLINE))
...@@ -765,7 +794,7 @@ void DirectiveParser::parseVersion(Token *token) ...@@ -765,7 +794,7 @@ void DirectiveParser::parseVersion(Token *token)
if (valid) if (valid)
{ {
mDirectiveHandler->handleVersion(token->location, version); mDirectiveHandler->handleVersion(token->location, version, mSettings.shaderSpec);
mShaderVersion = version; mShaderVersion = version;
PredefineMacro(mMacroSet, "__VERSION__", version); PredefineMacro(mMacroSet, "__VERSION__", version);
} }
......
...@@ -216,6 +216,8 @@ int MapSpecToShaderVersion(ShShaderSpec spec) ...@@ -216,6 +216,8 @@ int MapSpecToShaderVersion(ShShaderSpec spec)
case SH_GLES3_1_SPEC: case SH_GLES3_1_SPEC:
case SH_WEBGL3_SPEC: case SH_WEBGL3_SPEC:
return 310; return 310;
case SH_GL3_3_SPEC:
return 330;
default: default:
UNREACHABLE(); UNREACHABLE();
return 0; return 0;
...@@ -376,7 +378,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -376,7 +378,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
} }
TParseContext parseContext(mSymbolTable, mExtensionBehavior, mShaderType, mShaderSpec, TParseContext parseContext(mSymbolTable, mExtensionBehavior, mShaderType, mShaderSpec,
compileOptions, true, &mDiagnostics, getResources()); compileOptions, !IsDesktopGLSpec(mShaderSpec), &mDiagnostics,
getResources());
parseContext.setFragmentPrecisionHighOnESSL1(mResources.FragmentPrecisionHigh == 1); parseContext.setFragmentPrecisionHighOnESSL1(mResources.FragmentPrecisionHigh == 1);
......
...@@ -183,9 +183,12 @@ void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc, ...@@ -183,9 +183,12 @@ void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
} }
} }
void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc, int version) void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc,
int version,
ShShaderSpec spec)
{ {
if (version == 100 || version == 300 || version == 310) if (((version == 100 || version == 300 || version == 310) && !IsDesktopGLSpec(spec)) ||
(version == 330 && IsDesktopGLSpec(spec)))
{ {
mShaderVersion = version; mShaderVersion = version;
} }
...@@ -194,7 +197,7 @@ void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc, int ...@@ -194,7 +197,7 @@ void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc, int
std::stringstream stream = sh::InitializeStream<std::stringstream>(); std::stringstream stream = sh::InitializeStream<std::stringstream>();
stream << version; stream << version;
std::string str = stream.str(); std::string str = stream.str();
mDiagnostics.error(loc, "version number not supported", str.c_str()); mDiagnostics.error(loc, "client/version number not supported", str.c_str());
} }
} }
......
...@@ -41,7 +41,9 @@ class TDirectiveHandler : public angle::pp::DirectiveHandler, angle::NonCopyable ...@@ -41,7 +41,9 @@ class TDirectiveHandler : public angle::pp::DirectiveHandler, angle::NonCopyable
const std::string &name, const std::string &name,
const std::string &behavior) override; const std::string &behavior) override;
void handleVersion(const angle::pp::SourceLocation &loc, int version) override; void handleVersion(const angle::pp::SourceLocation &loc,
int version,
ShShaderSpec spec) override;
private: private:
TPragma mPragma; TPragma mPragma;
......
...@@ -453,7 +453,8 @@ GLenum GLVariablePrecision(const TType &type) ...@@ -453,7 +453,8 @@ GLenum GLVariablePrecision(const TType &type)
case EbpLow: case EbpLow:
return GL_LOW_FLOAT; return GL_LOW_FLOAT;
case EbpUndefined: case EbpUndefined:
// Should be defined as the default precision by the parser // Desktop specs do not use precision
return GL_NONE;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -469,7 +470,8 @@ GLenum GLVariablePrecision(const TType &type) ...@@ -469,7 +470,8 @@ GLenum GLVariablePrecision(const TType &type)
case EbpLow: case EbpLow:
return GL_LOW_INT; return GL_LOW_INT;
case EbpUndefined: case EbpUndefined:
// Should be defined as the default precision by the parser // Desktop specs do not use precision
return GL_NONE;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -22,8 +22,18 @@ namespace ...@@ -22,8 +22,18 @@ namespace
// To know when to call sh::Initialize and sh::Finalize. // To know when to call sh::Initialize and sh::Finalize.
size_t gActiveCompilers = 0; size_t gActiveCompilers = 0;
ShShaderSpec SelectShaderSpec(GLint majorVersion, GLint minorVersion, bool isWebGL) ShShaderSpec SelectShaderSpec(GLint majorVersion,
GLint minorVersion,
bool isWebGL,
EGLenum clientType)
{ {
// For Desktop GL
if (clientType == EGL_OPENGL_API)
{
ASSERT(majorVersion == 3 && minorVersion == 3);
return SH_GL3_3_SPEC;
}
if (majorVersion >= 3) if (majorVersion >= 3)
{ {
if (minorVersion == 1) if (minorVersion == 1)
...@@ -51,7 +61,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state) ...@@ -51,7 +61,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state)
: mImplementation(implFactory->createCompiler()), : mImplementation(implFactory->createCompiler()),
mSpec(SelectShaderSpec(state.getClientMajorVersion(), mSpec(SelectShaderSpec(state.getClientMajorVersion(),
state.getClientMinorVersion(), state.getClientMinorVersion(),
state.getExtensions().webglCompatibility)), state.getExtensions().webglCompatibility,
state.getClientType())),
mOutputType(mImplementation->getTranslatorOutputType()), mOutputType(mImplementation->getTranslatorOutputType()),
mResources() mResources()
{ {
......
...@@ -284,6 +284,7 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -284,6 +284,7 @@ Context::Context(rx::EGLImplFactory *implFactory,
: mState(reinterpret_cast<ContextID>(this), : mState(reinterpret_cast<ContextID>(this),
shareContext ? &shareContext->mState : nullptr, shareContext ? &shareContext->mState : nullptr,
shareTextures, shareTextures,
clientType,
GetClientVersion(attribs), GetClientVersion(attribs),
GetDebug(attribs), GetDebug(attribs),
GetBindGeneratesResource(attribs), GetBindGeneratesResource(attribs),
...@@ -297,7 +298,6 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -297,7 +298,6 @@ Context::Context(rx::EGLImplFactory *implFactory,
mLabel(nullptr), mLabel(nullptr),
mCompiler(), mCompiler(),
mConfig(config), mConfig(config),
mClientType(clientType),
mHasBeenCurrent(false), mHasBeenCurrent(false),
mContextLost(false), mContextLost(false),
mResetStatus(GraphicsResetStatus::NoError), mResetStatus(GraphicsResetStatus::NoError),
...@@ -2662,7 +2662,7 @@ const egl::Config *Context::getConfig() const ...@@ -2662,7 +2662,7 @@ const egl::Config *Context::getConfig() const
EGLenum Context::getClientType() const EGLenum Context::getClientType() const
{ {
return mClientType; return mState.getClientType();
} }
EGLenum Context::getRenderBuffer() const EGLenum Context::getRenderBuffer() const
...@@ -2976,23 +2976,22 @@ void Context::initVersionStrings() ...@@ -2976,23 +2976,22 @@ void Context::initVersionStrings()
const Version &clientVersion = getClientVersion(); const Version &clientVersion = getClientVersion();
std::ostringstream versionString; std::ostringstream versionString;
versionString << "OpenGL "; if (getClientType() == EGL_OPENGL_ES_API)
if (mClientType == EGL_OPENGL_ES_API)
{ {
versionString << "ES "; versionString << "OpenGL ES ";
} }
versionString << clientVersion.major << "." << clientVersion.minor << " (ANGLE " versionString << clientVersion.major << "." << clientVersion.minor << ".0 (ANGLE "
<< ANGLE_VERSION_STRING << ")"; << ANGLE_VERSION_STRING << ")";
mVersionString = MakeStaticString(versionString.str()); mVersionString = MakeStaticString(versionString.str());
std::ostringstream shadingLanguageVersionString; std::ostringstream shadingLanguageVersionString;
if (mClientType == EGL_OPENGL_ES_API) if (getClientType() == EGL_OPENGL_ES_API)
{ {
shadingLanguageVersionString << "OpenGL ES GLSL ES "; shadingLanguageVersionString << "OpenGL ES GLSL ES ";
} }
else else
{ {
ASSERT(mClientType == EGL_OPENGL_API); ASSERT(getClientType() == EGL_OPENGL_API);
shadingLanguageVersionString << "OpenGL GLSL "; shadingLanguageVersionString << "OpenGL GLSL ";
} }
shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "." shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
......
...@@ -606,7 +606,6 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -606,7 +606,6 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
mutable BindingPointer<Compiler> mCompiler; mutable BindingPointer<Compiler> mCompiler;
const egl::Config *mConfig; const egl::Config *mConfig;
EGLenum mClientType;
TextureMap mZeroTextures; TextureMap mZeroTextures;
......
...@@ -393,7 +393,10 @@ Display *Display::GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativ ...@@ -393,7 +393,10 @@ Display *Display::GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativ
const auto &iter = displays->find(nativeDisplay); const auto &iter = displays->find(nativeDisplay);
// Check that there is a matching display // Check that there is a matching display
ASSERT(iter != displays->end()); if (iter == displays->end())
{
return nullptr;
}
return iter->second; return iter->second;
} }
......
...@@ -234,13 +234,15 @@ const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBu ...@@ -234,13 +234,15 @@ const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBu
State::State(ContextID contextIn, State::State(ContextID contextIn,
const State *shareContextState, const State *shareContextState,
TextureManager *shareTextures, TextureManager *shareTextures,
const EGLenum clientType,
const Version &clientVersion, const Version &clientVersion,
bool debug, bool debug,
bool bindGeneratesResource, bool bindGeneratesResource,
bool clientArraysEnabled, bool clientArraysEnabled,
bool robustResourceInit, bool robustResourceInit,
bool programBinaryCacheEnabled) bool programBinaryCacheEnabled)
: mClientVersion(clientVersion), : mClientType(clientType),
mClientVersion(clientVersion),
mContext(contextIn), mContext(contextIn),
mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)), mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
mShaderProgramManager( mShaderProgramManager(
......
...@@ -58,6 +58,7 @@ class State : angle::NonCopyable ...@@ -58,6 +58,7 @@ class State : angle::NonCopyable
State(ContextID contextIn, State(ContextID contextIn,
const State *shareContextState, const State *shareContextState,
TextureManager *shareTextures, TextureManager *shareTextures,
const EGLenum clientType,
const Version &clientVersion, const Version &clientVersion,
bool debug, bool debug,
bool bindGeneratesResource, bool bindGeneratesResource,
...@@ -71,6 +72,7 @@ class State : angle::NonCopyable ...@@ -71,6 +72,7 @@ class State : angle::NonCopyable
// Getters // Getters
ContextID getContextID() const { return mContext; } ContextID getContextID() const { return mContext; }
EGLenum getClientType() const { return mClientType; }
GLint getClientMajorVersion() const { return mClientVersion.major; } GLint getClientMajorVersion() const { return mClientVersion.major; }
GLint getClientMinorVersion() const { return mClientVersion.minor; } GLint getClientMinorVersion() const { return mClientVersion.minor; }
const Version &getClientVersion() const { return mClientVersion; } const Version &getClientVersion() const { return mClientVersion; }
...@@ -722,6 +724,7 @@ class State : angle::NonCopyable ...@@ -722,6 +724,7 @@ class State : angle::NonCopyable
// Dispatch table for buffer update functions. // Dispatch table for buffer update functions.
static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters; static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
EGLenum mClientType;
Version mClientVersion; Version mClientVersion;
ContextID mContext; ContextID mContext;
......
...@@ -238,17 +238,38 @@ PROC GL_APIENTRY wglGetProcAddress(LPCSTR lpszProc) ...@@ -238,17 +238,38 @@ PROC GL_APIENTRY wglGetProcAddress(LPCSTR lpszProc)
BOOL GL_APIENTRY wglMakeCurrent(HDC hDc, HGLRC newContext) BOOL GL_APIENTRY wglMakeCurrent(HDC hDc, HGLRC newContext)
{ {
Thread *thread = egl::GetCurrentThread(); Thread *thread = egl::GetCurrentThread();
egl::Display *display = egl::Display::GetExistingDisplayFromNativeDisplay(hDc); egl::Display *display = egl::Display::GetExistingDisplayFromNativeDisplay(hDc);
gl::Context *context = reinterpret_cast<gl::Context *>(newContext); const gl::Context *context =
GetContextIfValid(display, reinterpret_cast<gl::Context *>(newContext));
ANGLE_EGL_TRY_RETURN( // If display or context are invalid, make thread's current rendering context not current
thread, if (!context)
display->makeCurrent(thread, display->getWGLSurface(), display->getWGLSurface(), context), {
"wglMakeCurrent", display, FALSE); gl::Context *oldContext = thread->getContext();
if (oldContext)
{
ANGLE_EGL_TRY_RETURN(thread, oldContext->unMakeCurrent(display), "wglMakeCurrent",
GetContextIfValid(display, oldContext), EGL_FALSE);
}
SetContextCurrent(thread, nullptr);
return TRUE;
}
egl::Surface *surface = display->getWGLSurface();
Surface *previousDraw = thread->getCurrentDrawSurface();
Surface *previousRead = thread->getCurrentReadSurface();
gl::Context *previousContext = thread->getContext();
SetContextCurrent(thread, context); if (previousDraw != surface || previousRead != surface || previousContext != context)
{
ANGLE_EGL_TRY_RETURN(
thread,
display->makeCurrent(thread, surface, surface, const_cast<gl::Context *>(context)),
"wglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
SetContextCurrent(thread, const_cast<gl::Context *>(context));
}
return TRUE; return TRUE;
} }
......
...@@ -226,3 +226,79 @@ TEST_F(ShCompileTest, DecimalSepLocale) ...@@ -226,3 +226,79 @@ TEST_F(ShCompileTest, DecimalSepLocale)
} }
} }
} }
// For testing Desktop GL Shaders
class ShCompileDesktopGLTest : public ShCompileTest
{
public:
ShCompileDesktopGLTest() {}
protected:
void SetUp() override
{
sh::InitBuiltInResources(&mResources);
mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_GL3_3_SPEC,
SH_GLSL_330_CORE_OUTPUT, &mResources);
ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
}
};
// Test calling sh::Compile with fragment shader source string
TEST_F(ShCompileDesktopGLTest, FragmentShaderString)
{
constexpr char kComputeShaderString[] =
R"(#version 330
void main()
{
})";
const char *shaderStrings[] = {kComputeShaderString};
testCompile(shaderStrings, 1, true);
}
// Test calling sh::Compile with core version
TEST_F(ShCompileDesktopGLTest, FragmentShaderCoreVersion)
{
constexpr char kComputeShaderString[] =
R"(#version 330 core
void main()
{
})";
const char *shaderStrings[] = {kComputeShaderString};
testCompile(shaderStrings, 1, true);
}
// Test calling sh::Compile with core version
TEST_F(ShCompileDesktopGLTest, DISABLED_FragmentShaderAdditionConversion)
{
constexpr char kComputeShaderString[] =
R"(#version 330 core
void main()
{
float f = 1 + 1.5;
})";
const char *shaderStrings[] = {kComputeShaderString};
testCompile(shaderStrings, 1, true);
}
// GL shaders use implicit conversions between types
// Testing internal implicit conversions
TEST_F(ShCompileDesktopGLTest, DISABLED_FragmentShaderFunctionConversion)
{
constexpr char kFragmentShaderString[] =
R"(#version 330 core
void main()
{
float cosTheta = clamp(0.5,0,1);
float exp = pow(0.5,2);
})";
const char *shaderStrings[] = {kFragmentShaderString};
testCompile(shaderStrings, 1, true);
}
\ No newline at end of file
...@@ -29,7 +29,8 @@ class MockDirectiveHandler : public pp::DirectiveHandler ...@@ -29,7 +29,8 @@ class MockDirectiveHandler : public pp::DirectiveHandler
const std::string &name, const std::string &name,
const std::string &behavior)); const std::string &behavior));
MOCK_METHOD2(handleVersion, void(const pp::SourceLocation &loc, int version)); MOCK_METHOD3(handleVersion,
void(const pp::SourceLocation &loc, int version, ShShaderSpec spec));
}; };
} // namespace angle } // namespace angle
......
...@@ -45,8 +45,13 @@ void SimplePreprocessorTest::preprocess(const char *input) ...@@ -45,8 +45,13 @@ void SimplePreprocessorTest::preprocess(const char *input)
void SimplePreprocessorTest::preprocess(const char *input, const char *expected) void SimplePreprocessorTest::preprocess(const char *input, const char *expected)
{ {
preprocess(input, expected, SH_GLES2_SPEC);
}
void SimplePreprocessorTest::preprocess(const char *input, const char *expected, ShShaderSpec spec)
{
pp::Preprocessor preprocessor(&mDiagnostics, &mDirectiveHandler, pp::Preprocessor preprocessor(&mDiagnostics, &mDirectiveHandler,
pp::PreprocessorSettings(SH_GLES2_SPEC)); pp::PreprocessorSettings(spec));
std::stringstream output; std::stringstream output;
preprocess(input, &output, &preprocessor); preprocess(input, &output, &preprocessor);
......
...@@ -38,6 +38,7 @@ class SimplePreprocessorTest : public testing::Test ...@@ -38,6 +38,7 @@ class SimplePreprocessorTest : public testing::Test
// Preprocesses the input string and verifies that it matches expected output. // Preprocesses the input string and verifies that it matches expected output.
void preprocess(const char *input, const char *expected); void preprocess(const char *input, const char *expected);
void preprocess(const char *input, const char *expected, ShShaderSpec spec);
// Lexes a single token from input and writes it to token. // Lexes a single token from input and writes it to token.
void lexSingleToken(const char *input, pp::Token *token); void lexSingleToken(const char *input, pp::Token *token);
......
...@@ -90,7 +90,7 @@ TEST_F(ExtensionTest, ExtensionAfterNonPreProcessorTokenESSL3) ...@@ -90,7 +90,7 @@ TEST_F(ExtensionTest, ExtensionAfterNonPreProcessorTokenESSL3)
using testing::_; using testing::_;
// Directive successfully parsed. // Directive successfully parsed.
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 300)); EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 300, SH_GLES2_SPEC));
// Expect an error about extension pragmas after non-preprocessor tokens. // Expect an error about extension pragmas after non-preprocessor tokens.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL, _, _)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL, _, _));
......
...@@ -19,13 +19,27 @@ TEST_F(VersionTest, Valid) ...@@ -19,13 +19,27 @@ TEST_F(VersionTest, Valid)
const char *expected = "\n"; const char *expected = "\n";
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200)); EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC));
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
preprocess(str, expected); preprocess(str, expected);
} }
// Test for Desktop GL Shaders
TEST_F(VersionTest, GLSpec)
{
const char *str = "#version 330 core\n";
const char *expected = "\n";
using testing::_;
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 330, SH_GL3_3_SPEC));
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
preprocess(str, expected, SH_GL3_3_SPEC);
}
TEST_F(VersionTest, CommentsIgnored) TEST_F(VersionTest, CommentsIgnored)
{ {
const char *str = const char *str =
...@@ -41,7 +55,7 @@ TEST_F(VersionTest, CommentsIgnored) ...@@ -41,7 +55,7 @@ TEST_F(VersionTest, CommentsIgnored)
const char *expected = "\n"; const char *expected = "\n";
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200)); EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC));
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
...@@ -55,7 +69,7 @@ TEST_F(VersionTest, MissingNewline) ...@@ -55,7 +69,7 @@ TEST_F(VersionTest, MissingNewline)
using testing::_; using testing::_;
// Directive successfully parsed. // Directive successfully parsed.
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200)); EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC));
// Error reported about EOF. // Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_EOF_IN_DIRECTIVE, _, _)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_EOF_IN_DIRECTIVE, _, _));
...@@ -72,7 +86,7 @@ TEST_F(VersionTest, AfterComments) ...@@ -72,7 +86,7 @@ TEST_F(VersionTest, AfterComments)
using testing::_; using testing::_;
// Directive successfully parsed. // Directive successfully parsed.
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200)); EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200, SH_GLES2_SPEC));
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
...@@ -89,7 +103,7 @@ TEST_F(VersionTest, AfterWhitespace) ...@@ -89,7 +103,7 @@ TEST_F(VersionTest, AfterWhitespace)
using testing::_; using testing::_;
// Directive successfully parsed. // Directive successfully parsed.
EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200)); EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200, SH_GLES2_SPEC));
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
...@@ -183,7 +197,7 @@ TEST_P(InvalidVersionTest, Identified) ...@@ -183,7 +197,7 @@ TEST_P(InvalidVersionTest, Identified)
using testing::_; using testing::_;
// No handleVersion call. // No handleVersion call.
EXPECT_CALL(mDirectiveHandler, handleVersion(_, _)).Times(0); EXPECT_CALL(mDirectiveHandler, handleVersion(_, _, _)).Times(0);
// Invalid version directive call. // Invalid version directive call.
EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _)); EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));
......
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