Path: blob/main_old/src/tests/compiler_tests/OVR_multiview_test.cpp
1693 views
//1// Copyright 2019 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// OVR_multiview_test.cpp:6// Test that shaders with gl_ViewID_OVR are validated correctly.7//89#include "GLSLANG/ShaderLang.h"10#include "compiler/translator/tree_util/IntermTraverse.h"11#include "tests/test_utils/ShaderCompileTreeTest.h"12#include "tests/test_utils/compiler_test.h"1314using namespace sh;1516namespace17{1819class SymbolOccurrenceCounter : public TIntermTraverser20{21public:22SymbolOccurrenceCounter() : TIntermTraverser(true, false, false), mNumberOfOccurrences(0u) {}2324void visitSymbol(TIntermSymbol *node) override25{26if (shouldCountSymbol(node))27{28++mNumberOfOccurrences;29}30}3132virtual bool shouldCountSymbol(const TIntermSymbol *node) const = 0;3334unsigned getNumberOfOccurrences() const { return mNumberOfOccurrences; }3536private:37unsigned mNumberOfOccurrences;38};3940class SymbolOccurrenceCounterByQualifier : public SymbolOccurrenceCounter41{42public:43SymbolOccurrenceCounterByQualifier(TQualifier symbolQualifier)44: mSymbolQualifier(symbolQualifier)45{}4647bool shouldCountSymbol(const TIntermSymbol *node) const override48{49return node->getQualifier() == mSymbolQualifier;50}5152private:53TQualifier mSymbolQualifier;54};5556class SymbolOccurrenceCounterByName : public SymbolOccurrenceCounter57{58public:59SymbolOccurrenceCounterByName(const ImmutableString &symbolName) : mSymbolName(symbolName) {}6061bool shouldCountSymbol(const TIntermSymbol *node) const override62{63return node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName;64}6566private:67ImmutableString mSymbolName;68};6970class SymbolOccurrenceCounterByNameAndQualifier : public SymbolOccurrenceCounter71{72public:73SymbolOccurrenceCounterByNameAndQualifier(const ImmutableString &symbolName,74TQualifier qualifier)75: mSymbolName(symbolName), mSymbolQualifier(qualifier)76{}7778bool shouldCountSymbol(const TIntermSymbol *node) const override79{80return node->variable().symbolType() != SymbolType::Empty &&81node->getName() == mSymbolName && node->getQualifier() == mSymbolQualifier;82}8384private:85ImmutableString mSymbolName;86TQualifier mSymbolQualifier;87};8889class OVRMultiviewVertexShaderTest : public ShaderCompileTreeTest90{91public:92OVRMultiviewVertexShaderTest() {}9394protected:95::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }96ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }97void initResources(ShBuiltInResources *resources) override98{99resources->OVR_multiview = 1;100resources->MaxViewsOVR = 4;101}102};103104class OVRMultiviewFragmentShaderTest : public ShaderCompileTreeTest105{106public:107OVRMultiviewFragmentShaderTest() {}108109protected:110::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }111ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }112void initResources(ShBuiltInResources *resources) override113{114resources->OVR_multiview = 1;115resources->MaxViewsOVR = 4;116}117};118119class OVRMultiviewOutputCodeTest : public MatchOutputCodeTest120{121public:122OVRMultiviewOutputCodeTest(sh::GLenum shaderType)123: MatchOutputCodeTest(shaderType, 0, SH_ESSL_OUTPUT)124{125addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);126127getResources()->OVR_multiview = 1;128getResources()->MaxViewsOVR = 4;129}130131void requestHLSLOutput()132{133#if defined(ANGLE_ENABLE_HLSL)134addOutputType(SH_HLSL_4_1_OUTPUT);135#endif136}137138bool foundInAllGLSLCode(const char *str)139{140return foundInGLSLCode(str) && foundInESSLCode(str);141}142143bool foundInHLSLCode(const char *stringToFind) const144{145#if defined(ANGLE_ENABLE_HLSL)146return foundInCode(SH_HLSL_4_1_OUTPUT, stringToFind);147#else148return true;149#endif150}151};152153class OVRMultiviewVertexShaderOutputCodeTest : public OVRMultiviewOutputCodeTest154{155public:156OVRMultiviewVertexShaderOutputCodeTest() : OVRMultiviewOutputCodeTest(GL_VERTEX_SHADER) {}157};158159class OVRMultiviewFragmentShaderOutputCodeTest : public OVRMultiviewOutputCodeTest160{161public:162OVRMultiviewFragmentShaderOutputCodeTest() : OVRMultiviewOutputCodeTest(GL_FRAGMENT_SHADER) {}163};164165class OVRMultiviewComputeShaderOutputCodeTest : public OVRMultiviewOutputCodeTest166{167public:168OVRMultiviewComputeShaderOutputCodeTest() : OVRMultiviewOutputCodeTest(GL_COMPUTE_SHADER) {}169};170171void VariableOccursNTimes(TIntermBlock *root,172const ImmutableString &varName,173const TQualifier varQualifier,174unsigned n)175{176// Check that there are n occurrences of the variable with the given name and qualifier.177SymbolOccurrenceCounterByNameAndQualifier viewIDByNameAndQualifier(varName, varQualifier);178root->traverse(&viewIDByNameAndQualifier);179EXPECT_EQ(n, viewIDByNameAndQualifier.getNumberOfOccurrences());180181// Check that there are n occurrences of the variable with the given name. By this we guarantee182// that there are no other occurrences of the variable with the same name but different183// qualifier.184SymbolOccurrenceCounterByName viewIDByName(varName);185root->traverse(&viewIDByName);186EXPECT_EQ(n, viewIDByName.getNumberOfOccurrences());187}188189// Unsupported GL_OVR_multiview extension directive (GL_OVR_multiview spec only exposes190// GL_OVR_multiview).191TEST_F(OVRMultiviewVertexShaderTest, InvalidMultiview)192{193const std::string &shaderString =194"#version 300 es\n"195"#extension GL_OVR_multiview2 : require\n"196"layout(num_views = 2) in;\n"197"void main()\n"198"{\n"199" gl_Position.x = (gl_ViewID_OVR == 0u) ? 1.0 : 0.0;\n"200" gl_Position.yzw = vec3(0, 0, 1);\n"201"}\n";202if (compile(shaderString))203{204FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;205}206}207208// Invalid combination of non-matching num_views declarations.209TEST_F(OVRMultiviewVertexShaderTest, InvalidNumViewsMismatch)210{211const std::string &shaderString =212"#version 300 es\n"213"#extension GL_OVR_multiview : require\n"214"layout(num_views = 2) in;\n"215"layout(num_views = 1) in;\n"216"void main()\n"217"{\n"218" gl_Position.x = (gl_ViewID_OVR == 0u) ? 1.0 : 0.0;\n"219" gl_Position.yzw = vec3(0, 0, 1);\n"220"}\n";221if (compile(shaderString))222{223FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;224}225}226227// Invalid value zero for num_views.228TEST_F(OVRMultiviewVertexShaderTest, InvalidNumViewsZero)229{230const std::string &shaderString =231"#version 300 es\n"232"#extension GL_OVR_multiview : require\n"233"layout(num_views = 0) in;\n"234"void main()\n"235"{\n"236" gl_Position.x = (gl_ViewID_OVR == 0u) ? 1.0 : 0.0;\n"237" gl_Position.yzw = vec3(0, 0, 1);\n"238"}\n";239if (compile(shaderString))240{241FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;242}243}244245// Too large value for num_views.246TEST_F(OVRMultiviewVertexShaderTest, InvalidNumViewsGreaterThanMax)247{248const std::string &shaderString =249"#version 300 es\n"250"#extension GL_OVR_multiview : require\n"251"layout(num_views = 5) in;\n"252"void main()\n"253"{\n"254" gl_Position.x = (gl_ViewID_OVR == 0u) ? 1.0 : 0.0;\n"255" gl_Position.yzw = vec3(0, 0, 1);\n"256"}\n";257if (compile(shaderString))258{259FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;260}261}262263// Valid use of gl_ViewID_OVR.264TEST_F(OVRMultiviewVertexShaderTest, ViewIDUsed)265{266const std::string &shaderString =267"#version 300 es\n"268"#extension GL_OVR_multiview : require\n"269"layout(num_views = 2) in;\n"270"layout(num_views = 2) in; // Duplicated on purpose\n"271"in vec4 pos;\n"272"out float myOutput;\n"273"void main()\n"274"{\n"275" if (gl_ViewID_OVR == 0u)\n"276" {\n"277" gl_Position = pos;\n"278" myOutput = 1.0;\n"279" }\n"280" else\n"281" {\n"282" gl_Position = pos + vec4(1.0, 0.0, 0.0, 0.0);\n"283" myOutput = 2.0;\n"284" }\n"285" gl_Position += (gl_ViewID_OVR == 0u) ? 1.0 : 0.0;\n"286"}\n";287if (!compile(shaderString))288{289FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;290}291}292293// Read gl_FragCoord in a OVR_multiview2 fragment shader.294TEST_F(OVRMultiviewFragmentShaderTest, ReadOfFragCoord)295{296const std::string &shaderString =297"#version 300 es\n"298"#extension GL_OVR_multiview : require\n"299"precision highp float;\n"300"out vec4 outColor;\n"301"void main()\n"302"{\n"303" outColor = vec4(gl_FragCoord.xy, 0, 1);\n"304"}\n";305if (!compile(shaderString))306{307FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;308}309}310311// Read gl_ViewID_OVR in an OVR_multiview2 fragment shader.312TEST_F(OVRMultiviewFragmentShaderTest, ReadOfViewID)313{314const std::string &shaderString =315"#version 300 es\n"316"#extension GL_OVR_multiview : require\n"317"precision highp float;\n"318"out vec4 outColor;\n"319"void main()\n"320"{\n"321" outColor = vec4(gl_ViewID_OVR, 0, 0, 1);\n"322"}\n";323if (!compile(shaderString))324{325FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;326}327}328329// Correct use of GL_OVR_multiview macro.330TEST_F(OVRMultiviewVertexShaderTest, UseOfExtensionMacro)331{332const std::string &shaderString =333"#version 300 es\n"334"#ifdef GL_OVR_multiview\n"335"#if (GL_OVR_multiview == 1)\n"336"void main()\n"337"{\n"338" gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"339"}\n"340"#endif\n"341"#endif\n";342if (!compile(shaderString))343{344FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;345}346}347348// Test that gl_ViewID_OVR can't be used as an l-value.349TEST_F(OVRMultiviewVertexShaderTest, ViewIdAsLValue)350{351const std::string &shaderString =352"#version 300 es\n"353"#extension GL_OVR_multiview : require\n"354"layout(num_views = 2) in;\n"355"void foo(out uint u)\n"356"{\n"357" u = 3u;\n"358"}\n"359"void main()\n"360"{\n"361" foo(gl_ViewID_OVR);\n"362" gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"363"}\n";364if (compile(shaderString))365{366FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;367}368}369370// Test that compiling an ESSL 1.00 shader with multiview support fails.371TEST_F(OVRMultiviewVertexShaderTest, ESSL1Shader)372{373const std::string &shaderString =374"#extension GL_OVR_multiview : require\n"375"layout(num_views = 2) in;\n"376"void main()\n"377"{\n"378" if (gl_ViewID_OVR == 0)\n"379" {\n"380" gl_Position = vec4(-1.0, 0.0, 0.0, 1.0);\n"381" }\n"382" else\n"383" {\n"384" gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"385" }\n"386"}\n";387if (compile(shaderString))388{389FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;390}391}392393// Test that compiling an ESSL 1.00 shader with an unsupported global layout qualifier fails.394TEST_F(OVRMultiviewVertexShaderTest, ESSL1ShaderUnsupportedGlobalLayoutQualifier)395{396const std::string &shaderString =397"#extension GL_OVR_multiview : require\n"398"layout(num_views = 2) in;\n"399"layout(std140) uniform;\n"400"void main()\n"401"{\n"402" if (gl_ViewID_OVR == 0)\n"403" {\n"404" gl_Position = vec4(-1.0, 0.0, 0.0, 1.0);\n"405" }\n"406" else\n"407" {\n"408" gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"409" }\n"410"}\n";411if (compile(shaderString))412{413FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;414}415}416417// Test that compiling an ESSL 1.00 vertex shader with an unsupported input storage qualifier fails.418TEST_F(OVRMultiviewVertexShaderTest, ESSL1ShaderUnsupportedInputStorageQualifier)419{420const std::string &shaderString =421"#extension GL_OVR_multiview : require\n"422"layout(num_views = 2) in;\n"423"in vec4 pos;\n"424"void main()\n"425"{\n"426" if (gl_ViewID_OVR == 0)\n"427" {\n"428" gl_Position = vec4(-1.0, 0.0, 0.0, 1.0);\n"429" }\n"430" else\n"431" {\n"432" gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"433" }\n"434"}\n";435if (compile(shaderString))436{437FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;438}439}440441// Test that compiling an ESSL 1.00 fragment shader with an unsupported input storage qualifier442// fails.443TEST_F(OVRMultiviewFragmentShaderTest, ESSL1ShaderUnsupportedInStorageQualifier)444{445const std::string &shaderString =446"#extension GL_OVR_multiview : require\n"447"precision highp float;\n"448"in vec4 color;\n"449"void main()\n"450"{\n"451" if (gl_ViewID_OVR == 0)\n"452" {\n"453" gl_FragColor = color;\n"454" }\n"455" else\n"456" {\n"457" gl_FragColor = color + vec4(1.0, 0.0, 0.0, 1.0);\n"458" }\n"459"}\n";460if (compile(shaderString))461{462FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;463}464}465466// Test that gl_InstanceID gets correctly replaced by InstanceID. gl_InstanceID should only be used467// twice: once to initialize ViewID_OVR and once for InstanceID. The number of occurrences of468// InstanceID in the AST should be the sum of two and the number of occurrences of gl_InstanceID469// before any renaming.470TEST_F(OVRMultiviewVertexShaderTest, GLInstanceIDIsRenamed)471{472const std::string &shaderString =473"#version 300 es\n"474"#extension GL_OVR_multiview : require\n"475"layout(num_views = 2) in;\n"476"flat out int myInstance;\n"477"out float myInstanceF;\n"478"out float myInstanceF2;\n"479"void main()\n"480"{\n"481" gl_Position.x = gl_ViewID_OVR == 0u ? 0. : 1.;\n"482" gl_Position.yzw = vec3(0., 0., 1.);\n"483" myInstance = gl_InstanceID;\n"484" myInstanceF = float(gl_InstanceID) + .5;\n"485" myInstanceF2 = float(gl_InstanceID) + .1;\n"486"}\n";487mExtraCompileOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;488compileAssumeSuccess(shaderString);489490SymbolOccurrenceCounterByName glInstanceIDByName(ImmutableString("gl_InstanceID"));491mASTRoot->traverse(&glInstanceIDByName);492EXPECT_EQ(2u, glInstanceIDByName.getNumberOfOccurrences());493494SymbolOccurrenceCounterByQualifier glInstanceIDByQualifier(EvqInstanceID);495mASTRoot->traverse(&glInstanceIDByQualifier);496EXPECT_EQ(2u, glInstanceIDByQualifier.getNumberOfOccurrences());497498SymbolOccurrenceCounterByName instanceIDByName(ImmutableString("InstanceID"));499mASTRoot->traverse(&instanceIDByName);500EXPECT_EQ(5u, instanceIDByName.getNumberOfOccurrences());501}502503// Test that gl_ViewID_OVR gets correctly replaced by ViewID_OVR. gl_ViewID_OVR should not be found504// by either name or qualifier. The number of occurrences of ViewID_OVR in the AST should be the sum505// of two and the number of occurrences of gl_ViewID_OVR before any renaming.506TEST_F(OVRMultiviewVertexShaderTest, GLViewIDIsRenamed)507{508const std::string &shaderString =509"#version 300 es\n"510"#extension GL_OVR_multiview : require\n"511"layout(num_views = 2) in;\n"512"flat out uint a;\n"513"void main()\n"514"{\n"515" gl_Position.x = gl_ViewID_OVR == 0u ? 0. : 1.;\n"516" gl_Position.yzw = vec3(0., 0., 1.);\n"517" a = gl_ViewID_OVR == 0u ? (gl_ViewID_OVR+2u) : gl_ViewID_OVR;\n"518"}\n";519mExtraCompileOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;520compileAssumeSuccess(shaderString);521522SymbolOccurrenceCounterByName glViewIDOVRByName(ImmutableString("gl_ViewID_OVR"));523mASTRoot->traverse(&glViewIDOVRByName);524EXPECT_EQ(0u, glViewIDOVRByName.getNumberOfOccurrences());525526SymbolOccurrenceCounterByQualifier glViewIDOVRByQualifier(EvqViewIDOVR);527mASTRoot->traverse(&glViewIDOVRByQualifier);528EXPECT_EQ(0u, glViewIDOVRByQualifier.getNumberOfOccurrences());529530SymbolOccurrenceCounterByNameAndQualifier viewIDByNameAndQualifier(531ImmutableString("ViewID_OVR"), EvqFlatOut);532mASTRoot->traverse(&viewIDByNameAndQualifier);533EXPECT_EQ(6u, viewIDByNameAndQualifier.getNumberOfOccurrences());534}535536// The test checks that ViewID_OVR and InstanceID have the correct initializers based on the537// number of views.538TEST_F(OVRMultiviewVertexShaderOutputCodeTest, ViewIDAndInstanceIDHaveCorrectValues)539{540const std::string &shaderString =541"#version 300 es\n"542"#extension GL_OVR_multiview : require\n"543"layout(num_views = 3) in;\n"544"flat out int myInstance;\n"545"void main()\n"546"{\n"547" gl_Position.x = gl_ViewID_OVR == 0u ? 0. : 1.;\n"548" gl_Position.yzw = vec3(0., 0., 1.);\n"549" myInstance = gl_InstanceID;\n"550"}\n";551requestHLSLOutput();552compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW);553554EXPECT_TRUE(foundInAllGLSLCode("ViewID_OVR = (uint(gl_InstanceID) % 3u)"));555EXPECT_TRUE(foundInAllGLSLCode("InstanceID = int((uint(gl_InstanceID) / 3u))"));556557EXPECT_TRUE(foundInHLSLCode("ViewID_OVR = (uint_ctor(gl_InstanceID) % 3)"));558#if defined(ANGLE_ENABLE_HLSL)559EXPECT_FALSE(foundInHLSLCode("_ViewID_OVR = (uint_ctor(gl_InstanceID) % 3)"));560#endif561EXPECT_TRUE(foundInHLSLCode("InstanceID = int_ctor((uint_ctor(gl_InstanceID) / 3))"));562}563564// The test checks that the directive enabling GL_OVR_multiview is not outputted if the extension565// is emulated.566TEST_F(OVRMultiviewVertexShaderOutputCodeTest, StrippedOVRMultiviewDirective)567{568const std::string &shaderString =569"#version 300 es\n"570"#extension GL_OVR_multiview : require\n"571"layout(num_views = 3) in;\n"572"void main()\n"573"{\n"574"}\n";575// The directive must not be present if any of the multiview emulation options are set.576compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW);577EXPECT_FALSE(foundInESSLCode("GL_OVR_multiview"));578EXPECT_FALSE(foundInGLSLCode("GL_OVR_multiview"));579580// The directive should be outputted from the ESSL translator with none of the options being581// set.582compile(shaderString);583EXPECT_TRUE(foundInESSLCode("GL_OVR_multiview"));584}585586// Test that ViewID_OVR is declared as a flat input variable in an ESSL 3.00 fragment shader.587TEST_F(OVRMultiviewFragmentShaderTest, ViewIDDeclaredAsFlatInput)588{589const std::string &shaderString =590"#version 300 es\n"591"#extension GL_OVR_multiview : require\n"592"void main()\n"593"{\n"594"}\n";595mExtraCompileOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;596compileAssumeSuccess(shaderString);597VariableOccursNTimes(mASTRoot, ImmutableString("ViewID_OVR"), EvqFlatIn, 1u);598}599600// Test that ViewID_OVR is declared as a flat output variable in an ESSL 1.00 vertex shader.601TEST_F(OVRMultiviewVertexShaderTest, ViewIDDeclaredAsFlatOutput)602{603const std::string &shaderString =604"#extension GL_OVR_multiview : require\n"605"void main()\n"606"{\n"607"}\n";608mExtraCompileOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;609compileAssumeSuccess(shaderString);610VariableOccursNTimes(mASTRoot, ImmutableString("ViewID_OVR"), EvqFlatOut, 2u);611}612613// The test checks that the GL_NV_viewport_array2 extension is emitted in a vertex shader if the614// SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set.615TEST_F(OVRMultiviewVertexShaderOutputCodeTest, ViewportArray2IsEmitted)616{617const std::string &shaderString =618"#version 300 es\n"619"#extension GL_OVR_multiview : require\n"620"layout(num_views = 3) in;\n"621"void main()\n"622"{\n"623"}\n";624compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |625SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);626EXPECT_TRUE(foundInAllGLSLCode("#extension GL_NV_viewport_array2 : require"));627}628629// The test checks that the GL_NV_viewport_array2 extension is not emitted in a vertex shader if the630// OVR_multiview2 extension is not requested in the shader source even if the631// SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set.632TEST_F(OVRMultiviewVertexShaderOutputCodeTest, ViewportArray2IsNotEmitted)633{634const std::string &shaderString =635"#version 300 es\n"636"void main()\n"637"{\n"638"}\n";639compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |640SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);641EXPECT_FALSE(foundInGLSLCode("#extension GL_NV_viewport_array2"));642EXPECT_FALSE(foundInESSLCode("#extension GL_NV_viewport_array2"));643}644645// The test checks that the GL_NV_viewport_array2 extension is not emitted in a fragment shader if646// the SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set.647TEST_F(OVRMultiviewFragmentShaderOutputCodeTest, ViewportArray2IsNotEmitted)648{649const std::string &shaderString =650"#version 300 es\n"651"#extension GL_OVR_multiview : require\n"652"void main()\n"653"{\n"654"}\n";655compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |656SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);657EXPECT_FALSE(foundInGLSLCode("#extension GL_NV_viewport_array2"));658EXPECT_FALSE(foundInESSLCode("#extension GL_NV_viewport_array2"));659}660661// The test checks if OVR_multiview is emitted only once and no other662// multiview extensions are emitted.663TEST_F(OVRMultiviewFragmentShaderOutputCodeTest, NativeOvrMultiviewOutput)664{665const std::string &shaderString =666"#version 300 es\n"667"#extension GL_OVR_multiview : require\n"668"void main()\n"669"{\n"670"}\n";671compile(shaderString);672EXPECT_FALSE(foundInGLSLCode("#extension GL_NV_viewport_array2"));673EXPECT_FALSE(foundInESSLCode("#extension GL_NV_viewport_array2"));674675EXPECT_TRUE(foundInESSLCode("#extension GL_OVR_multiview"));676EXPECT_TRUE(foundInGLSLCode("#extension GL_OVR_multiview"));677678EXPECT_FALSE(foundInESSLCode("#extension GL_OVR_multiview2"));679EXPECT_FALSE(foundInGLSLCode("#extension GL_OVR_multiview2"));680681// no double extension682std::vector<const char *> notExpectedStrings1 = {"#extension GL_OVR_multiview",683"#extension GL_OVR_multiview"};684EXPECT_FALSE(foundInCodeInOrder(SH_ESSL_OUTPUT, notExpectedStrings1));685EXPECT_FALSE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, notExpectedStrings1));686}687688// The test checks that the GL_NV_viewport_array2 extension is not emitted in a compute shader if689// the SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set.690TEST_F(OVRMultiviewComputeShaderOutputCodeTest, ViewportArray2IsNotEmitted)691{692const std::string &shaderString =693R"(#version 310 es694#extension GL_OVR_multiview : require695void main()696{697})";698compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |699SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);700EXPECT_FALSE(foundInGLSLCode("#extension GL_NV_viewport_array2"));701EXPECT_FALSE(foundInESSLCode("#extension GL_NV_viewport_array2"));702}703704// The test checks that the viewport index is selected after the initialization of ViewID_OVR for705// GLSL and ESSL ouputs.706TEST_F(OVRMultiviewVertexShaderOutputCodeTest, GlViewportIndexIsSet)707{708const std::string &shaderString =709"#version 300 es\n"710"#extension GL_OVR_multiview : require\n"711"layout(num_views = 3) in;\n"712"void main()\n"713"{\n"714"}\n";715compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |716SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);717718std::vector<const char *> expectedStrings = {"ViewID_OVR = (uint(gl_InstanceID) % 3u)",719"gl_ViewportIndex = int(ViewID_OVR)"};720EXPECT_TRUE(foundInCodeInOrder(SH_ESSL_OUTPUT, expectedStrings));721EXPECT_TRUE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, expectedStrings));722}723724// The test checks that the layer is selected after the initialization of ViewID_OVR for725// GLSL and ESSL ouputs.726TEST_F(OVRMultiviewVertexShaderOutputCodeTest, GlLayerIsSet)727{728const std::string &shaderString =729"#version 300 es\n"730"#extension GL_OVR_multiview : require\n"731"layout(num_views = 3) in;\n"732"void main()\n"733"{\n"734"}\n";735compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |736SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);737738std::vector<const char *> expectedStrings = {739"ViewID_OVR = (uint(gl_InstanceID) % 3u)",740"gl_Layer = (int(ViewID_OVR) + multiviewBaseViewLayerIndex)"};741EXPECT_TRUE(foundInCodeInOrder(SH_ESSL_OUTPUT, expectedStrings));742EXPECT_TRUE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, expectedStrings));743}744745// Test that the OVR_multiview without emulation emits OVR_multiview output.746// It also tests that the GL_OVR_multiview is emitted only once and no other747// multiview extensions are emitted.748TEST_F(OVRMultiviewVertexShaderOutputCodeTest, NativeOvrMultiviewOutput)749{750const std::string &shaderString =751"#version 300 es\n"752"#extension GL_OVR_multiview : require\n"753"layout(num_views = 3) in;\n"754"void main()\n"755"{\n"756"}\n";757compile(shaderString);758759std::vector<const char *> expectedStrings = {"#extension GL_OVR_multiview", "layout(num_views"};760EXPECT_TRUE(foundInCodeInOrder(SH_ESSL_OUTPUT, expectedStrings));761EXPECT_TRUE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, expectedStrings));762763EXPECT_FALSE(foundInGLSLCode("#extension GL_NV_viewport_array2"));764EXPECT_FALSE(foundInESSLCode("#extension GL_NV_viewport_array2"));765766EXPECT_FALSE(foundInGLSLCode("#extension GL_OVR_multiview2"));767EXPECT_FALSE(foundInESSLCode("#extension GL_OVR_multiview2"));768769EXPECT_FALSE(foundInGLSLCode("gl_ViewportIndex"));770EXPECT_FALSE(foundInESSLCode("gl_ViewportIndex"));771772// no double extension773std::vector<const char *> notExpectedStrings1 = {"#extension GL_OVR_multiview",774"#extension GL_OVR_multiview"};775EXPECT_FALSE(foundInCodeInOrder(SH_ESSL_OUTPUT, notExpectedStrings1));776EXPECT_FALSE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, notExpectedStrings1));777778// no double num_views779std::vector<const char *> notExpectedStrings2 = {"layout(num_views", "layout(num_views"};780EXPECT_FALSE(foundInCodeInOrder(SH_ESSL_OUTPUT, notExpectedStrings2));781EXPECT_FALSE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, notExpectedStrings2));782}783784} // namespace785786