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 "WHLSLPrepare.h"
28
29#if ENABLE(WEBGPU)
30
31#include "WHLSLCheckDuplicateFunctions.h"
32#include "WHLSLChecker.h"
33#include "WHLSLFunctionStageChecker.h"
34#include "WHLSLHighZombieFinder.h"
35#include "WHLSLLiteralTypeChecker.h"
36#include "WHLSLMetalCodeGenerator.h"
37#include "WHLSLNameResolver.h"
38#include "WHLSLParser.h"
39#include "WHLSLProgram.h"
40#include "WHLSLRecursionChecker.h"
41#include "WHLSLRecursiveTypeChecker.h"
42#include "WHLSLSemanticMatcher.h"
43#include "WHLSLStandardLibrary.h"
44#include "WHLSLStatementBehaviorChecker.h"
45#include "WHLSLSynthesizeArrayOperatorLength.h"
46#include "WHLSLSynthesizeConstructors.h"
47#include "WHLSLSynthesizeEnumerationFunctions.h"
48#include "WHLSLSynthesizeStructureAccessors.h"
49#include <wtf/Optional.h>
50
51namespace WebCore {
52
53namespace WHLSL {
54
55static Optional<Program> prepareShared(String& whlslSource)
56{
57 Program program;
58 Parser parser;
59 auto standardLibrary = String::fromUTF8(WHLSLStandardLibrary, sizeof(WHLSLStandardLibrary));
60 auto failure = static_cast<bool>(parser.parse(program, standardLibrary, Parser::Mode::StandardLibrary));
61 ASSERT_UNUSED(failure, !failure);
62 if (parser.parse(program, whlslSource, Parser::Mode::User))
63 return WTF::nullopt;
64 NameResolver nameResolver(program.nameContext());
65 if (!resolveNamesInTypes(program, nameResolver))
66 return WTF::nullopt;
67 if (!checkRecursiveTypes(program))
68 return WTF::nullopt;
69 if (!synthesizeStructureAccessors(program))
70 return WTF::nullopt;
71 if (!synthesizeEnumerationFunctions(program))
72 return WTF::nullopt;
73 if (!synthesizeArrayOperatorLength(program))
74 return WTF::nullopt;
75 if (!synthesizeConstructors(program))
76 return WTF::nullopt;
77 if (!resolveNamesInFunctions(program, nameResolver))
78 return WTF::nullopt;
79 if (!checkDuplicateFunctions(program))
80 return WTF::nullopt;
81
82 if (!check(program))
83 return WTF::nullopt;
84 checkLiteralTypes(program);
85 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Resolve properties here
86 findHighZombies(program);
87 if (!checkStatementBehavior(program))
88 return WTF::nullopt;
89 if (!checkRecursion(program))
90 return WTF::nullopt;
91 if (!checkFunctionStages(program))
92 return WTF::nullopt;
93 return program;
94}
95
96Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor& renderPipelineDescriptor)
97{
98 auto program = prepareShared(whlslSource);
99 if (!program)
100 return WTF::nullopt;
101 auto matchedSemantics = matchSemantics(*program, renderPipelineDescriptor);
102 if (!matchedSemantics)
103 return WTF::nullopt;
104
105 auto generatedCode = Metal::generateMetalCode(*program, WTFMove(*matchedSemantics), renderPipelineDescriptor.layout);
106
107 RenderPrepareResult result;
108 result.metalSource = WTFMove(generatedCode.metalSource);
109 result.mangledVertexEntryPointName = WTFMove(generatedCode.mangledVertexEntryPointName);
110 result.mangledFragmentEntryPointName = WTFMove(generatedCode.mangledFragmentEntryPointName);
111 return result;
112}
113
114Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor& computePipelineDescriptor)
115{
116 auto program = prepareShared(whlslSource);
117 if (!program)
118 return WTF::nullopt;
119 auto matchedSemantics = matchSemantics(*program, computePipelineDescriptor);
120 if (!matchedSemantics)
121 return WTF::nullopt;
122
123 auto generatedCode = Metal::generateMetalCode(*program, WTFMove(*matchedSemantics), computePipelineDescriptor.layout);
124
125 ComputePrepareResult result;
126 result.metalSource = WTFMove(generatedCode.metalSource);
127 result.mangledEntryPointName = WTFMove(generatedCode.mangledEntryPointName);
128 return result;
129}
130
131} // namespace WHLSL
132
133} // namespace WebCore
134
135#endif // ENABLE(WEBGPU)
136