Hash :
7ba69645
Author :
Date :
2024-11-14T10:07:31
Fix unnamed outs w/ initializeUninitializedLocals Fix translator initializeUninitializedLocals pass for anonymous out parameters. The parameters should be initialized to zero, similar to named but unassigned parameters. Initialization would be skipped on GLSL output, assert on Metal. Functions need to be replaced if their parameter names change. In case the function had a prototype declaration, that has to be replaced too. All calls to old functions must be replaced with calls to new function. Bug: angleproject:378584780 Change-Id: I9a990fa3840f6e26cd30f35bf6c99d9a8816f272 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6020245 Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Auto-Submit: Kimmo Kinnunen <kkinnunen@apple.com> Commit-Queue: Kimmo Kinnunen <kkinnunen@apple.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//
// Copyright 2017 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.
//
// InitializeUninitializedVariables_test.cpp: Tests InitializeUninitializedVariables pass.
//
#include "common/angleutils.h"
#include "tests/test_utils/compiler_test.h"
namespace sh
{
namespace
{
class InitializeUninitializedVariables : public MatchOutputCodeTest
{
public:
InitializeUninitializedVariables() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
{
ShCompileOptions options{};
options.intermediateTree = true;
options.initializeUninitializedLocals = true;
options.validateAST = true;
setDefaultCompileOptions(options);
}
};
// Tests that when unnamed variables must be initialized, the variables get internal names.
TEST_F(InitializeUninitializedVariables, VariableNamesInPrototypesUnnamedOut)
{
const char kShader[] = R"(#version 300 es
precision highp float;
out vec4 o;
void f(out float, out float);
void main()
{
o = vec4(0.5);
f(o.r, o.g);
}
void f(out float r, out float)
{
r = 1.0;
}
)";
const char kExpected[] = R"(#version 300 es
out highp vec4 _uo;
void _uf(out highp float _ur, out highp float sbc2);
void main(){
(_uo = vec4(0.5, 0.5, 0.5, 0.5));
_uf(_uo.x, _uo.y);
}
void _uf(out highp float _ur, out highp float sbc2){
(_ur = 0.0);
(sbc2 = 0.0);
(_ur = 1.0);
}
)";
compile(kShader);
EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
}
// Tests that when unnamed variables must be initialized, the variables get internal names.
TEST_F(InitializeUninitializedVariables, VariableNamesInPrototypesUnnamedOut2)
{
const char kShader[] = R"(#version 300 es
precision highp float;
out vec4 o;
void f(out float, out float);
void g(out float a, out float b)
{
f(a, b);
}
void main()
{
o = vec4(0.5);
g(o.r, o.g);
}
void f(out float r, out float)
{
r = 1.0;
}
)";
const char kExpected[] = R"(#version 300 es
out highp vec4 _uo;
void _uf(out highp float _ur, out highp float sbc5);
void _ug(out highp float _ua, out highp float _ub){
(_ua = 0.0);
(_ub = 0.0);
_uf(_ua, _ub);
}
void main(){
(_uo = vec4(0.5, 0.5, 0.5, 0.5));
_ug(_uo.x, _uo.y);
}
void _uf(out highp float _ur, out highp float sbc5){
(_ur = 0.0);
(sbc5 = 0.0);
(_ur = 1.0);
}
)";
compile(kShader);
EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
}
// Tests that when unnamed variables must be initialized, the variables get internal names.
// Tests the case where local z is initialized with a function f, when f must be rewritten.
TEST_F(InitializeUninitializedVariables, VariableNamesInPrototypesUnnamedOut3)
{
const char kShader[] = R"(#version 300 es
precision highp float;
out vec4 o;
float f(out float r, out float)
{
r = 1.0;
return 3.0;
}
void main()
{
o = vec4(0.5);
float z = f(o.r, o.g);
}
)";
const char kExpected[] = R"(#version 300 es
out highp vec4 _uo;
highp float _uf(out highp float _ur, out highp float sbc0){
(_ur = 0.0);
(sbc0 = 0.0);
(_ur = 1.0);
return 3.0;
}
void main(){
(_uo = vec4(0.5, 0.5, 0.5, 0.5));
highp float _uz = _uf(_uo.x, _uo.y);
}
)";
compile(kShader);
EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
}
} // namespace
} // namespace sh