[WHLSL] Hook up common texture functions
[WebKit-https.git] / Source / WebCore / Modules / webgpu / WHLSL / WHLSLSynthesizeConstructors.cpp
1 /*
2  * Copyright (C) 2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WHLSLSynthesizeConstructors.h"
28
29 #if ENABLE(WEBGPU)
30
31 #include "WHLSLArrayType.h"
32 #include "WHLSLArrayReferenceType.h"
33 #include "WHLSLEnumerationDefinition.h"
34 #include "WHLSLInferTypes.h"
35 #include "WHLSLNativeFunctionDeclaration.h"
36 #include "WHLSLNativeTypeDeclaration.h"
37 #include "WHLSLPointerType.h"
38 #include "WHLSLProgram.h"
39 #include "WHLSLStructureDefinition.h"
40 #include "WHLSLTypeReference.h"
41 #include "WHLSLVariableDeclaration.h"
42 #include "WHLSLVisitor.h"
43
44 namespace WebCore {
45
46 namespace WHLSL {
47
48 class UnnamedTypeKey {
49 public:
50     UnnamedTypeKey() = default;
51     UnnamedTypeKey(WTF::HashTableDeletedValueType)
52     {
53         m_type = bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1));
54     }
55
56     UnnamedTypeKey(AST::UnnamedType& type)
57         : m_type(&type)
58     { }
59
60     bool isEmptyValue() const { return !m_type; }
61     bool isHashTableDeletedValue() const { return m_type == bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1)); }
62
63     unsigned hash() const { return m_type->hash(); }
64     bool operator==(const UnnamedTypeKey& other) const { return *m_type == *other.m_type; }
65     AST::UnnamedType& unnamedType() const { return *m_type; }
66
67     struct Hash {
68         static unsigned hash(const UnnamedTypeKey& key) { return key.hash(); }
69         static bool equal(const UnnamedTypeKey& a, const UnnamedTypeKey& b) { return a == b; }
70         static const bool safeToCompareToEmptyOrDeleted = false;
71         static const bool emptyValueIsZero = true;
72     };
73
74     struct Traits : public WTF::SimpleClassHashTraits<UnnamedTypeKey> {
75         static const bool hasIsEmptyValueFunction = true;
76         static bool isEmptyValue(const UnnamedTypeKey& key) { return key.isEmptyValue(); }
77     };
78
79 private:
80     AST::UnnamedType* m_type { nullptr };
81 };
82
83 class FindAllTypes : public Visitor {
84 public:
85     virtual ~FindAllTypes() = default;
86
87     void visit(AST::PointerType& pointerType) override
88     {
89         m_unnamedTypes.add(UnnamedTypeKey { pointerType });
90         Visitor::visit(pointerType);
91     }
92
93     void visit(AST::ArrayReferenceType& arrayReferenceType) override
94     {
95         m_unnamedTypes.add(UnnamedTypeKey { arrayReferenceType });
96         Visitor::visit(arrayReferenceType);
97     }
98
99     void visit(AST::ArrayType& arrayType) override
100     {
101         m_unnamedTypes.add(UnnamedTypeKey { arrayType });
102         Visitor::visit(arrayType);
103     }
104
105     void visit(AST::EnumerationDefinition& enumerationDefinition) override
106     {
107         appendNamedType(enumerationDefinition);
108         Visitor::visit(enumerationDefinition);
109     }
110
111     void visit(AST::StructureDefinition& structureDefinition) override
112     {
113         appendNamedType(structureDefinition);
114         Visitor::visit(structureDefinition);
115     }
116
117     void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) override
118     {
119         appendNamedType(nativeTypeDeclaration);
120         Visitor::visit(nativeTypeDeclaration);
121     }
122
123     HashSet<UnnamedTypeKey, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> takeUnnamedTypes()
124     {
125         return WTFMove(m_unnamedTypes);
126     }
127
128     Vector<std::reference_wrapper<AST::NamedType>> takeNamedTypes()
129     {
130         return WTFMove(m_namedTypes);
131     }
132
133 private:
134     void appendNamedType(AST::NamedType& type)
135     {
136         // The way we walk the AST ensures we should never visit a named type twice.
137 #if !ASSERT_DISABLED
138         for (auto& entry : m_namedTypes)
139             ASSERT(&entry.get().unifyNode() != &type.unifyNode());
140 #endif
141         m_namedTypes.append(type);
142     }
143
144     HashSet<UnnamedTypeKey, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> m_unnamedTypes;
145     Vector<std::reference_wrapper<AST::NamedType>> m_namedTypes;
146 };
147
148 bool synthesizeConstructors(Program& program)
149 {
150     FindAllTypes findAllTypes;
151     findAllTypes.checkErrorAndVisit(program);
152     auto unnamedTypes = findAllTypes.takeUnnamedTypes();
153     auto namedTypes = findAllTypes.takeNamedTypes();
154
155     bool isOperator = true;
156
157     for (auto& unnamedTypeKey : unnamedTypes) {
158         auto& unnamedType = unnamedTypeKey.unnamedType();
159
160         auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(unnamedType.origin()), AST::Qualifiers(), unnamedType.clone(), String(), WTF::nullopt, WTF::nullopt);
161         AST::VariableDeclarations parameters;
162         parameters.append(WTFMove(variableDeclaration));
163         AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator));
164         program.append(WTFMove(copyConstructor));
165
166         AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, AST::VariableDeclarations(), WTF::nullopt, isOperator));
167         if (!program.append(WTFMove(defaultConstructor)))
168             return false;
169     }
170
171     for (auto& namedType : namedTypes) {
172         if (matches(namedType, program.intrinsics().voidType()))
173             continue;
174         if (is<AST::NativeTypeDeclaration>(static_cast<AST::NamedType&>(namedType)) && downcast<AST::NativeTypeDeclaration>(static_cast<AST::NamedType&>(namedType)).isAtomic())
175             continue;
176
177         auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(namedType.get().origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get())), String(), WTF::nullopt, WTF::nullopt);
178         AST::VariableDeclarations parameters;
179         parameters.append(WTFMove(variableDeclaration));
180         AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(namedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator));
181         program.append(WTFMove(copyConstructor));
182
183         if (is<AST::NativeTypeDeclaration>(static_cast<AST::NamedType&>(namedType))) {
184             auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(static_cast<AST::NamedType&>(namedType));
185             if (nativeTypeDeclaration.isOpaqueType())
186                 continue;
187         }
188         AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(Lexer::Token(namedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()), "operator cast"_str, AST::VariableDeclarations(), WTF::nullopt, isOperator));
189         if (!program.append(WTFMove(defaultConstructor)))
190             return false;
191     }
192     return true;
193 }
194
195 } // namespace WHLSL
196
197 } // namespace WebCore
198
199 #endif // ENABLE(WEBGPU)