Hash :
4397ff2f
Author :
Date :
2024-10-25T16:55:30
Metal: SeparateCompoundStructDeclarations fails validation
Consider GLSL:
struct S { int i; } s;
s=s;
SeparateCompoundStructDeclarations would rewrite this to:
struct S { int i; };
S s';
s=s;
The interm rewrite would rewrite the specification and declaration of s,
but not the use sites. The use sites would use the old type, and thus
something that was not in the tree anymore. This would fail the
validation.
This kind of bug was previously fixed for SeparateDeclarations
in commit 18fa02bebf901dd8501de3176f6052ae4ce984be.
Fix by adding the logic to SeparateDeclarations, as it is already
doing almost the exact task, separating `struct S { ..} a, b`.
The separation is tested in GLSLTests.StructInShader and various
other draw tests. These pass with MSL, but these would also fail
validation if that was enabled.
Bug: angleproject:375523825
Change-Id: I1697103d0ba47616dbd3159f36f9e71cb2831c4b
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5964899
Auto-Submit: Kimmo Kinnunen <kkinnunen@apple.com>
Commit-Queue: Kimmo Kinnunen <kkinnunen@apple.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
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
//
// Copyright 2002 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.
//
#ifndef COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
#define COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
#include "common/angleutils.h"
namespace sh
{
class TCompiler;
class TIntermBlock;
// Transforms declarations so that in the end each declaration contains only one declarator.
// This is useful as an intermediate step when initialization needs to be separated from
// declaration, or when things need to be unfolded out of the initializer.
// Examples:
// Input:
// int a[1] = int[1](1), b[1] = int[1](2);
// Output:
// int a[1] = int[1](1);
// int b[1] = int[1](2);
// Input:
// struct S { vec3 d; } a, b;
// Output:
// struct S { vec3 d; } a;
// S b;
// Input:
// struct { vec3 d; } a;
// Output (note: no change):
// struct { vec3 d; } a;
// Input:
// struct { vec3 d; } a, b;
// Output:
// struct s1234 { vec3 d; } a;
// s1234 b;
// Input with separateCompoundStructDeclarations=true:
// struct S { vec3 d; } a;
// Output:
// struct S { vec3 d; };
// S a;
// Input with separateCompoundStructDeclarations=true:
// struct S { vec3 d; } a, b;
// Output:
// struct S { vec3 d; };
// S a;
// S b;
// Input with separateCompoundStructDeclarations=true:
// struct { vec3 d; } a, b;
// Output:
// struct s1234 { vec3 d; };
// s1234 a;
// s1234 b;
// Input with separateCompoundStructDeclarations=true:
// struct { vec3 d; } a;
// Output (note: now, changes):
// struct s1234 { vec3 d; };
// s1234 a;
[[nodiscard]] bool SeparateDeclarations(TCompiler &compiler,
TIntermBlock &root,
bool separateCompoundStructDeclarations);
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_