Path: blob/main_old/src/tests/compiler_tests/HLSLOutput_test.cpp
1693 views
//1// Copyright 2017 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// HLSLOutput_test.cpp:6// Tests for HLSL output.7//89#include <regex>10#include "GLSLANG/ShaderLang.h"11#include "angle_gl.h"12#include "gtest/gtest.h"13#include "tests/test_utils/compiler_test.h"1415using namespace sh;1617class HLSLOutputTest : public MatchOutputCodeTest18{19public:20HLSLOutputTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_HLSL_4_1_OUTPUT) {}21};2223class HLSL30VertexOutputTest : public MatchOutputCodeTest24{25public:26HLSL30VertexOutputTest() : MatchOutputCodeTest(GL_VERTEX_SHADER, 0, SH_HLSL_3_0_OUTPUT) {}27};2829// Test that having dynamic indexing of a vector inside the right hand side of logical or doesn't30// trigger asserts in HLSL output.31TEST_F(HLSLOutputTest, DynamicIndexingOfVectorOnRightSideOfLogicalOr)32{33const std::string &shaderString =34"#version 300 es\n"35"precision highp float;\n"36"out vec4 my_FragColor;\n"37"uniform int u1;\n"38"void main() {\n"39" bvec4 v = bvec4(true, true, true, false);\n"40" my_FragColor = vec4(v[u1 + 1] || v[u1]);\n"41"}\n";42compile(shaderString);43}4445// Test that rewriting else blocks in a function that returns a struct doesn't use the struct name46// without a prefix.47TEST_F(HLSL30VertexOutputTest, RewriteElseBlockReturningStruct)48{49const std::string &shaderString =50"struct foo\n"51"{\n"52" float member;\n"53"};\n"54"uniform bool b;\n"55"foo getFoo()\n"56"{\n"57" if (b)\n"58" {\n"59" return foo(0.0);\n"60" }\n"61" else\n"62" {\n"63" return foo(1.0);\n"64" }\n"65"}\n"66"void main()\n"67"{\n"68" gl_Position = vec4(getFoo().member);\n"69"}\n";70compile(shaderString);71EXPECT_TRUE(foundInCode("_foo"));72EXPECT_FALSE(foundInCode("(foo)"));73EXPECT_FALSE(foundInCode(" foo"));74}7576// Test that having an array constructor as a statement doesn't trigger an assert in HLSL output.77// This test has a constant array constructor statement.78TEST_F(HLSLOutputTest, ConstArrayConstructorStatement)79{80const std::string &shaderString =81R"(#version 300 es82void main()83{84int[1](0);85})";86compile(shaderString);87}8889// Test that having an array constructor as a statement doesn't trigger an assert in HLSL output.90TEST_F(HLSLOutputTest, ArrayConstructorStatement)91{92const std::string &shaderString =93R"(#version 300 es94precision mediump float;95out vec4 outColor;96void main()97{98outColor = vec4(0.0, 0.0, 0.0, 1.0);99float[1](outColor[1]++);100})";101compile(shaderString);102}103104// Test an array of arrays constructor as a statement.105TEST_F(HLSLOutputTest, ArrayOfArraysStatement)106{107const std::string &shaderString =108R"(#version 310 es109precision mediump float;110out vec4 outColor;111void main()112{113outColor = vec4(0.0, 0.0, 0.0, 1.0);114float[2][2](float[2](outColor[1]++, 0.0), float[2](1.0, 2.0));115})";116compile(shaderString);117}118119// Test dynamic indexing of a vector. This makes sure that helper functions added for dynamic120// indexing have correct data that subsequent traversal steps rely on.121TEST_F(HLSLOutputTest, VectorDynamicIndexing)122{123const std::string &shaderString =124R"(#version 300 es125precision mediump float;126out vec4 outColor;127uniform int i;128void main()129{130vec4 foo = vec4(0.0, 0.0, 0.0, 1.0);131foo[i] = foo[i + 1];132outColor = foo;133})";134compile(shaderString);135}136137// Test returning an array from a user-defined function. This makes sure that function symbols are138// changed consistently when the user-defined function is changed to have an array out parameter.139TEST_F(HLSLOutputTest, ArrayReturnValue)140{141const std::string &shaderString =142R"(#version 300 es143precision mediump float;144uniform float u;145out vec4 outColor;146147float[2] getArray(float f)148{149return float[2](f, f + 1.0);150}151152void main()153{154float[2] arr = getArray(u);155outColor = vec4(arr[0], arr[1], 0.0, 1.0);156})";157compile(shaderString);158}159160// Test that writing parameters without a name doesn't assert.161TEST_F(HLSLOutputTest, ParameterWithNoName)162{163const std::string &shaderString =164R"(precision mediump float;165166uniform vec4 v;167168vec4 s(vec4)169{170return v;171}172void main()173{174gl_FragColor = s(v);175})";176compile(shaderString);177}178179// Test that array dimensions are written out correctly.180TEST_F(HLSLOutputTest, Array)181{182const std::string &shaderString =183R"(#version 300 es184precision mediump float;185186uniform float uf;187188out vec4 my_FragColor;189190void main()191{192my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);193float arr[2];194for (int i = 0; i < 2; ++i) {195arr[i] = uf * 2.0;196my_FragColor.x += arr[i];197}198})";199compile(shaderString);200EXPECT_TRUE(foundInCodeRegex(std::regex("_arr(\\d)*\\[2\\]")));201}202203// Test that initializing array with previously declared array will not be overwritten204TEST_F(HLSLOutputTest, SameNameArray)205{206const std::string &shaderString =207R"(#version 300 es208precision highp float;209out vec4 my_FragColor;210211void main()212{213float arr[2] = float[2](1.0, 1.0);214{215float arr[2] = arr;216my_FragColor = vec4(0.0, arr[0], 0.0, arr[1]);217}218})";219compile(shaderString);220// There should be two different arr defined, e.g. _arr1000 and _arr1001221// Use Workaround for now.222// Once the build team fixes libc++ we could use the following one line solution instead.223// EXPECT_TRUE(foundInCodeRegex(std::regex("_arr(\\d*)\\[2\\](.|\\r|\\n)*_arr(?!\\1)\\d*\\[2\\]")));224std::smatch m;225EXPECT_TRUE(foundInCodeRegex(std::regex("_arr(\\d)*\\[2\\]"), &m));226EXPECT_TRUE(m.size() == 2);227EXPECT_TRUE(m[0].str() != m[1].str());228}229230// Test that passing a non-struct member of a std140 structure to a function won't trigger the231// struct mapping.232TEST_F(HLSLOutputTest, NonStructMemberAsFunctionArgument)233{234constexpr char shaderString[] = R"(#version 300 es235precision highp float;236out vec4 my_FragColor;237238struct InstancingData239{240vec4 data;241};242243layout(std140) uniform InstanceBlock244{245InstancingData instances[8];246};247248void main()249{250int index = int(gl_FragCoord.x);251float result = dot(instances[index].data, vec4(1.0, 1.0, 1.0, 1.0));252my_FragColor = vec4(result, 0.0, 0.0, 1.0);253})";254255compile(shaderString);256EXPECT_FALSE(foundInCode("map_instances"));257}258259260