⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 248307 in webkit


Ignore:
Timestamp:
Aug 6, 2019, 12:04:00 PM (7 years ago)
Author:
weinig@apple.com
Message:

WHLSL Metal code generation unnecessarily does string copies by passing partial results as Strings
https://bugs.webkit.org/show_bug.cgi?id=200471

Reviewed by Saam Barati.

Avoid string copies by passing a single StringBuilder all the way through Metal code
generation and only converting to a String when passing the constructed shader to Metal
API.

Where possible, use StringView in lieu of String for temporary strings being passed to
the StringBuilder to avoid the allocation overhead of StringImpl.

  • Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h:

(WebCore::WHLSL::AST::toString):
Switch to StringView.

  • Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h:

(WebCore::WHLSL::AST::BuiltInSemantic::toString const):
Switch to StringView.

  • Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h:

(WebCore::WHLSL::AST::toString):
Switch to StringView.

  • Modules/webgpu/WHLSL/AST/WHLSLPointerType.h:

Remove unnecessary "private:".

  • Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h:

(WebCore::WHLSL::AST::ResourceSemantic::toString):
Switch to StringView.

  • Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp:

(WebCore::WHLSL::Metal::EntryPointScaffolding::emitResourceHelperTypes):
(WebCore::WHLSL::Metal::EntryPointScaffolding::emitResourceSignature):
(WebCore::WHLSL::Metal::EntryPointScaffolding::emitBuiltInsSignature):
(WebCore::WHLSL::Metal::EntryPointScaffolding::emitMangledInputPath):
(WebCore::WHLSL::Metal::EntryPointScaffolding::emitMangledOutputPath):
(WebCore::WHLSL::Metal::EntryPointScaffolding::emitUnpackResourcesAndNamedBuiltIns):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitHelperTypes):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitSignature):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitUnpack):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitPack):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitHelperTypes):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitSignature):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitUnpack):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitPack):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitHelperTypes):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitSignature):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitUnpack):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitPack):
(WebCore::WHLSL::Metal::EntryPointScaffolding::resourceHelperTypes): Deleted.
(WebCore::WHLSL::Metal::EntryPointScaffolding::resourceSignature): Deleted.
(WebCore::WHLSL::Metal::EntryPointScaffolding::builtInsSignature): Deleted.
(WebCore::WHLSL::Metal::EntryPointScaffolding::mangledInputPath): Deleted.
(WebCore::WHLSL::Metal::EntryPointScaffolding::mangledOutputPath): Deleted.
(WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): Deleted.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::helperTypes): Deleted.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::signature): Deleted.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::unpack): Deleted.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::pack): Deleted.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::helperTypes): Deleted.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::signature): Deleted.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::unpack): Deleted.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::pack): Deleted.
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::helperTypes): Deleted.
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::signature): Deleted.
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::unpack): Deleted.
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::pack): Deleted.

  • Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:

Rather than have scaffolding return strings, pass in StringBuilders everywhere.

  • Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:

(WebCore::WHLSL::Metal::FunctionDefinitionWriter::FunctionDefinitionWriter):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitConstantExpressionString):
(WebCore::WHLSL::Metal::generateMetalFunctionsMapping):
(WebCore::WHLSL::Metal::emitSharedMetalFunctions):
(WebCore::WHLSL::Metal::emitMetalFunctions):
(WebCore::WHLSL::Metal::FunctionDeclarationWriter::FunctionDeclarationWriter): Deleted.
(WebCore::WHLSL::Metal::FunctionDeclarationWriter::toString): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::toString): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::constantExpressionString): Deleted.
(WebCore::WHLSL::Metal::RenderFunctionDefinitionWriter::RenderFunctionDefinitionWriter): Deleted.
(WebCore::WHLSL::Metal::ComputeFunctionDefinitionWriter::ComputeFunctionDefinitionWriter): Deleted.
(WebCore::WHLSL::Metal::sharedMetalFunctions): Deleted.
(WebCore::WHLSL::Metal::metalFunctions): Deleted.

  • Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.h:

Rather than returning Strings from function generation functions, pass in StringBuilders everywhere.

  • Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp:

(WebCore::WHLSL::Metal::metalCodeProlog):
(WebCore::WHLSL::Metal::dumpMetalCodeIfNeeded):
(WebCore::WHLSL::Metal::generateMetalCode):
(WebCore::WHLSL::Metal::generateMetalCodeShared): Deleted.

  • Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.h:

Switch RenderMetalCode and ComputeMetalCode to contain StringBuilders to allow
delaying conversion to String to the latest point possible.

  • Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:

(WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDeclarations):
(WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
(WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
(WebCore::WHLSL::Metal::TypeNamer::emitAllUnnamedTypeDefinitions):
(WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDefinitions):
(WebCore::WHLSL::Metal::TypeNamer::emitMetalTypes):
(WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::MetalTypeDeclarationWriter): Deleted.
(WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::toString): Deleted.
(WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::visit): Deleted.
(WebCore::WHLSL::Metal::TypeNamer::metalTypeDeclarations): Deleted.
(WebCore::WHLSL::Metal::TypeNamer::metalTypeDefinitions): Deleted.
(WebCore::WHLSL::Metal::TypeNamer::metalTypes): Deleted.

  • Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:

Rather than returning Strings from function generation functions, pass in StringBuilders everywhere.

  • Modules/webgpu/WHLSL/WHLSLParser.cpp:

(WebCore::WHLSL::Parser::parseResourceSemantic):
Remove use of _str, which allocates a String, and just use a StringView directly.

  • Modules/webgpu/WHLSL/WHLSLPrepare.h:

Switch RenderPrepareResult and ComputePrepareResult to contain StringBuilders to allow
delaying conversion to String to the latest point possible.

  • platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:

(WebCore::trySetFunctions):

  • platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm:

(WebCore::trySetFunctions):
Convert StringBuilders to String at the last moment necessary. Adds a FIXME to improve
in the future by adding direct conversion from StringBuilder to NSString to avoid another
copy.

Location:
trunk/Source/WebCore
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r248303 r248307  
     12019-08-06  Sam Weinig  <weinig@apple.com>
     2
     3        WHLSL Metal code generation unnecessarily does string copies by passing partial results as Strings
     4        https://bugs.webkit.org/show_bug.cgi?id=200471
     5
     6        Reviewed by Saam Barati.
     7
     8        Avoid string copies by passing a single StringBuilder all the way through Metal code
     9        generation and only converting to a String when passing the constructed shader to Metal
     10        API.
     11       
     12        Where possible, use StringView in lieu of String for temporary strings being passed to
     13        the StringBuilder to avoid the allocation overhead of StringImpl.
     14
     15        * Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h:
     16        (WebCore::WHLSL::AST::toString):
     17        Switch to StringView.
     18
     19        * Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h:
     20        (WebCore::WHLSL::AST::BuiltInSemantic::toString const):
     21        Switch to StringView.
     22
     23        * Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h:
     24        (WebCore::WHLSL::AST::toString):
     25        Switch to StringView.
     26
     27        * Modules/webgpu/WHLSL/AST/WHLSLPointerType.h:
     28        Remove unnecessary "private:".
     29   
     30        * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h:
     31        (WebCore::WHLSL::AST::ResourceSemantic::toString):
     32        Switch to StringView.
     33
     34        * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp:
     35        (WebCore::WHLSL::Metal::EntryPointScaffolding::emitResourceHelperTypes):
     36        (WebCore::WHLSL::Metal::EntryPointScaffolding::emitResourceSignature):
     37        (WebCore::WHLSL::Metal::EntryPointScaffolding::emitBuiltInsSignature):
     38        (WebCore::WHLSL::Metal::EntryPointScaffolding::emitMangledInputPath):
     39        (WebCore::WHLSL::Metal::EntryPointScaffolding::emitMangledOutputPath):
     40        (WebCore::WHLSL::Metal::EntryPointScaffolding::emitUnpackResourcesAndNamedBuiltIns):
     41        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitHelperTypes):
     42        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitSignature):
     43        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitUnpack):
     44        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::emitPack):
     45        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitHelperTypes):
     46        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitSignature):
     47        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitUnpack):
     48        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::emitPack):
     49        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitHelperTypes):
     50        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitSignature):
     51        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitUnpack):
     52        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::emitPack):
     53        (WebCore::WHLSL::Metal::EntryPointScaffolding::resourceHelperTypes): Deleted.
     54        (WebCore::WHLSL::Metal::EntryPointScaffolding::resourceSignature): Deleted.
     55        (WebCore::WHLSL::Metal::EntryPointScaffolding::builtInsSignature): Deleted.
     56        (WebCore::WHLSL::Metal::EntryPointScaffolding::mangledInputPath): Deleted.
     57        (WebCore::WHLSL::Metal::EntryPointScaffolding::mangledOutputPath): Deleted.
     58        (WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): Deleted.
     59        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::helperTypes): Deleted.
     60        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::signature): Deleted.
     61        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::unpack): Deleted.
     62        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::pack): Deleted.
     63        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::helperTypes): Deleted.
     64        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::signature): Deleted.
     65        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::unpack): Deleted.
     66        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::pack): Deleted.
     67        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::helperTypes): Deleted.
     68        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::signature): Deleted.
     69        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::unpack): Deleted.
     70        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::pack): Deleted.
     71        * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:
     72        Rather than have scaffolding return strings, pass in StringBuilders everywhere.
     73
     74        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
     75        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::FunctionDefinitionWriter):
     76        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
     77        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitConstantExpressionString):
     78        (WebCore::WHLSL::Metal::generateMetalFunctionsMapping):
     79        (WebCore::WHLSL::Metal::emitSharedMetalFunctions):
     80        (WebCore::WHLSL::Metal::emitMetalFunctions):
     81        (WebCore::WHLSL::Metal::FunctionDeclarationWriter::FunctionDeclarationWriter): Deleted.
     82        (WebCore::WHLSL::Metal::FunctionDeclarationWriter::toString): Deleted.
     83        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::toString): Deleted.
     84        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::constantExpressionString): Deleted.
     85        (WebCore::WHLSL::Metal::RenderFunctionDefinitionWriter::RenderFunctionDefinitionWriter): Deleted.
     86        (WebCore::WHLSL::Metal::ComputeFunctionDefinitionWriter::ComputeFunctionDefinitionWriter): Deleted.
     87        (WebCore::WHLSL::Metal::sharedMetalFunctions): Deleted.
     88        (WebCore::WHLSL::Metal::metalFunctions): Deleted.
     89        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.h:
     90        Rather than returning Strings from function generation functions, pass in StringBuilders everywhere.
     91
     92        * Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp:
     93        (WebCore::WHLSL::Metal::metalCodeProlog):
     94        (WebCore::WHLSL::Metal::dumpMetalCodeIfNeeded):
     95        (WebCore::WHLSL::Metal::generateMetalCode):
     96        (WebCore::WHLSL::Metal::generateMetalCodeShared): Deleted.
     97        * Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.h:
     98        Switch RenderMetalCode and ComputeMetalCode to contain StringBuilders to allow
     99        delaying conversion to String to the latest point possible.
     100       
     101        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
     102        (WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDeclarations):
     103        (WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
     104        (WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
     105        (WebCore::WHLSL::Metal::TypeNamer::emitAllUnnamedTypeDefinitions):
     106        (WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDefinitions):
     107        (WebCore::WHLSL::Metal::TypeNamer::emitMetalTypes):
     108        (WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::MetalTypeDeclarationWriter): Deleted.
     109        (WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::toString): Deleted.
     110        (WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::visit): Deleted.
     111        (WebCore::WHLSL::Metal::TypeNamer::metalTypeDeclarations): Deleted.
     112        (WebCore::WHLSL::Metal::TypeNamer::metalTypeDefinitions): Deleted.
     113        (WebCore::WHLSL::Metal::TypeNamer::metalTypes): Deleted.
     114        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
     115        Rather than returning Strings from function generation functions, pass in StringBuilders everywhere.
     116
     117        * Modules/webgpu/WHLSL/WHLSLParser.cpp:
     118        (WebCore::WHLSL::Parser::parseResourceSemantic):
     119        Remove use of _str, which allocates a String, and just use a StringView directly.
     120
     121        * Modules/webgpu/WHLSL/WHLSLPrepare.h:
     122        Switch RenderPrepareResult and ComputePrepareResult to contain StringBuilders to allow
     123        delaying conversion to String to the latest point possible.
     124
     125        * platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
     126        (WebCore::trySetFunctions):
     127        * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm:
     128        (WebCore::trySetFunctions):
     129        Convert StringBuilders to String at the last moment necessary. Adds a FIXME to improve
     130        in the future by adding direct conversion from StringBuilder to NSString to avoid another
     131        copy.
     132
    11332019-08-06  Saam Barati  <sbarati@apple.com>
    2134
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h

    r248021 r248307  
    4545};
    4646
    47 ALWAYS_INLINE String toString(AddressSpace addressSpace)
     47ALWAYS_INLINE StringView toString(AddressSpace addressSpace)
    4848{
    4949    switch (addressSpace) {
    5050    case AddressSpace::Constant:
    51         return "constant"_str;
     51        return "constant";
    5252    case AddressSpace::Device:
    53         return "device"_str;
     53        return "device";
    5454    case AddressSpace::Threadgroup:
    55         return "threadgroup"_str;
     55        return "threadgroup";
    5656    default:
    5757        ASSERT(addressSpace == AddressSpace::Thread);
    58         return "thread"_str;
     58        return "thread";
    5959    }
    6060}
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h

    r247834 r248307  
    8484    }
    8585
    86     String toString() const
     86    StringView toString() const
    8787    {
    8888        switch (m_variable) {
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h

    r246385 r248307  
    4242};
    4343
    44 ALWAYS_INLINE String toString(EntryPointType type)
     44ALWAYS_INLINE StringView toString(EntryPointType type)
    4545{
    4646    switch (type) {
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h

    r248083 r248307  
    5050    {
    5151    }
     52
    5253public:
    53 
    5454    static Ref<PointerType> create(CodeLocation location, AddressSpace addressSpace, Ref<UnnamedType> elementType)
    5555    {
     
    7979        return makeString(elementType().toString(), '*');
    8080    }
    81 
    82 private:
    8381};
    8482
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h

    r247834 r248307  
    6161    ResourceSemantic(ResourceSemantic&&) = default;
    6262
    63     String toString()
     63    StringView toString()
    6464    {
    6565        switch (m_mode) {
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp

    r248266 r248307  
    140140}
    141141
    142 String EntryPointScaffolding::resourceHelperTypes()
    143 {
    144     StringBuilder stringBuilder;
     142void EntryPointScaffolding::emitResourceHelperTypes(StringBuilder& stringBuilder)
     143{
    145144    for (size_t i = 0; i < m_layout.size(); ++i) {
    146145        stringBuilder.flexibleAppend("struct ", m_namedBindGroups[i].structName, " {\n");
     
    175174        stringBuilder.append("};\n\n");
    176175    }
    177     return stringBuilder.toString();
    178 }
    179 
    180 Optional<String> EntryPointScaffolding::resourceSignature()
     176}
     177
     178bool EntryPointScaffolding::emitResourceSignature(StringBuilder& stringBuilder, IncludePrecedingComma includePrecedingComma)
    181179{
    182180    if (!m_layout.size())
    183         return WTF::nullopt;
    184 
    185     StringBuilder stringBuilder;
     181        return false;
     182
     183    if (includePrecedingComma == IncludePrecedingComma::Yes)
     184        stringBuilder.append(", ");
     185
    186186    for (size_t i = 0; i < m_layout.size(); ++i) {
    187187        if (i)
     
    190190        stringBuilder.flexibleAppend("device ", namedBindGroup.structName, "& ", namedBindGroup.variableName, " [[buffer(", namedBindGroup.argumentBufferIndex, ")]]");
    191191    }
    192     return stringBuilder.toString();
     192    return true;
    193193}
    194194
     
    228228}
    229229
    230 Optional<String> EntryPointScaffolding::builtInsSignature()
     230bool EntryPointScaffolding::emitBuiltInsSignature(StringBuilder& stringBuilder, IncludePrecedingComma includePrecedingComma)
    231231{
    232232    if (!m_namedBuiltIns.size())
    233         return WTF::nullopt;
    234 
    235     StringBuilder stringBuilder;
     233        return false;
     234
     235    if (includePrecedingComma == IncludePrecedingComma::Yes)
     236        stringBuilder.append(", ");
     237
    236238    for (size_t i = 0; i < m_namedBuiltIns.size(); ++i) {
    237239        if (i)
     
    247249        stringBuilder.flexibleAppend(' ', namedBuiltIn.variableName, ' ', attributeForSemantic(builtInSemantic));
    248250    }
    249     return stringBuilder.toString();
    250 }
    251 
    252 String EntryPointScaffolding::mangledInputPath(Vector<String>& path)
     251    return true;
     252}
     253
     254void EntryPointScaffolding::emitMangledInputPath(StringBuilder& stringBuilder, Vector<String>& path)
    253255{
    254256    ASSERT(!path.isEmpty());
    255     StringBuilder stringBuilder;
    256257    bool found = false;
    257258    AST::StructureDefinition* structureDefinition = nullptr;
     
    283284        }
    284285    }
    285 
    286     return stringBuilder.toString();
    287 }
    288 
    289 String EntryPointScaffolding::mangledOutputPath(Vector<String>& path)
    290 {
    291     StringBuilder stringBuilder;
    292 
     286}
     287
     288void EntryPointScaffolding::emitMangledOutputPath(StringBuilder& stringBuilder, Vector<String>& path)
     289{
    293290    AST::StructureDefinition* structureDefinition = nullptr;
    294291    auto& unifyNode = m_functionDefinition.type().unifyNode();
     
    307304        }
    308305    }
    309 
    310     return stringBuilder.toString();
    311 }
    312 
    313 String EntryPointScaffolding::unpackResourcesAndNamedBuiltIns()
    314 {
    315     StringBuilder stringBuilder;
     306}
     307
     308void EntryPointScaffolding::emitUnpackResourcesAndNamedBuiltIns(StringBuilder& stringBuilder)
     309{
    316310    for (size_t i = 0; i < m_functionDefinition.parameters().size(); ++i)
    317311        stringBuilder.flexibleAppend(m_typeNamer.mangledNameForType(*m_functionDefinition.parameters()[i]->type()), ' ', m_parameterVariables[i], ";\n");
     
    337331                    lengthTemporaryName, " = ", lengthTemporaryName, " | ", variableName, '.', lengthElementName, ".x;\n",
    338332                    lengthTemporaryName, " = ", lengthTemporaryName, " / sizeof(", mangledTypeName, ");\n",
    339                     "if (", lengthTemporaryName, " > 0xFFFFFFFF) ", lengthTemporaryName, " = 0xFFFFFFFF;\n",
    340                     mangledInputPath(path), " = { ", variableName, '.', elementName, ", static_cast<uint32_t>(", lengthTemporaryName, ") };\n"
     333                    "if (", lengthTemporaryName, " > 0xFFFFFFFF) ", lengthTemporaryName, " = 0xFFFFFFFF;\n"
     334                );
     335                   
     336                emitMangledInputPath(stringBuilder, path);
     337                stringBuilder.flexibleAppend(
     338                    " = { ", variableName, '.', elementName, ", static_cast<uint32_t>(", lengthTemporaryName, ") };\n"
    341339                );
    342340            } else {
    343341                auto& path = m_entryPointItems.inputs[iterator->value].path;
    344342                auto elementName = m_namedBindGroups[i].namedBindings[j].elementName;
    345                 stringBuilder.flexibleAppend(mangledInputPath(path), " = ", variableName, '.', elementName, ";\n");
     343               
     344                emitMangledInputPath(stringBuilder, path);
     345                stringBuilder.flexibleAppend(" = ", variableName, '.', elementName, ";\n");
    346346            }
    347347        }
     
    353353        auto& variableName = namedBuiltIn.variableName;
    354354        auto mangledTypeName = m_typeNamer.mangledNameForType(*item.unnamedType);
    355         stringBuilder.flexibleAppend(mangledInputPath(path), " = ", mangledTypeName, '(', variableName, ");\n");
    356     }
    357     return stringBuilder.toString();
     355
     356        emitMangledInputPath(stringBuilder, path);
     357        stringBuilder.flexibleAppend(" = ", mangledTypeName, '(', variableName, ");\n");
     358    }
    358359}
    359360
     
    390391}
    391392
    392 String VertexEntryPointScaffolding::helperTypes()
    393 {
    394     StringBuilder stringBuilder;
    395 
     393void VertexEntryPointScaffolding::emitHelperTypes(StringBuilder& stringBuilder)
     394{
    396395    stringBuilder.flexibleAppend("struct ", m_stageInStructName, " {\n");
    397396    for (auto& namedStageIn : m_namedStageIns) {
     
    412411        stringBuilder.flexibleAppend("    ", internalTypeName, ' ', elementName, ' ', attribute, ";\n");
    413412    }
    414     stringBuilder.flexibleAppend(
    415         "};\n\n",
    416         resourceHelperTypes()
     413    stringBuilder.append(
     414        "};\n\n"
    417415    );
    418 
    419     return stringBuilder.toString();
    420 }
    421 
    422 String VertexEntryPointScaffolding::signature(MangledFunctionName functionName)
    423 {
    424     StringBuilder stringBuilder;
    425 
     416   
     417    emitResourceHelperTypes(stringBuilder);
     418}
     419
     420void VertexEntryPointScaffolding::emitSignature(StringBuilder& stringBuilder, MangledFunctionName functionName)
     421{
    426422    stringBuilder.flexibleAppend("vertex ", m_returnStructName, ' ', functionName, '(', m_stageInStructName, ' ', m_stageInParameterName, " [[stage_in]]");
    427     if (auto resourceSignature = this->resourceSignature())
    428         stringBuilder.flexibleAppend(", ", *resourceSignature);
    429     if (auto builtInsSignature = this->builtInsSignature())
    430         stringBuilder.flexibleAppend(", ", *builtInsSignature);
     423    emitResourceSignature(stringBuilder, IncludePrecedingComma::Yes);
     424    emitBuiltInsSignature(stringBuilder, IncludePrecedingComma::Yes);
    431425    stringBuilder.append(')');
    432 
    433     return stringBuilder.toString();
    434 }
    435 
    436 String VertexEntryPointScaffolding::unpack()
    437 {
    438     StringBuilder stringBuilder;
    439 
    440     stringBuilder.append(unpackResourcesAndNamedBuiltIns());
     426}
     427
     428void VertexEntryPointScaffolding::emitUnpack(StringBuilder& stringBuilder)
     429{
     430    emitUnpackResourcesAndNamedBuiltIns(stringBuilder);
    441431
    442432    for (auto& namedStageIn : m_namedStageIns) {
    443433        auto& path = m_entryPointItems.inputs[namedStageIn.indexInEntryPointItems].path;
    444434        auto& elementName = namedStageIn.elementName;
    445         stringBuilder.flexibleAppend(mangledInputPath(path), " = ", m_stageInParameterName, '.', elementName, ";\n");
    446     }
    447 
    448     return stringBuilder.toString();
    449 }
    450 
    451 String VertexEntryPointScaffolding::pack(MangledVariableName inputVariableName, MangledVariableName outputVariableName)
    452 {
    453     StringBuilder stringBuilder;
    454 
     435        emitMangledInputPath(stringBuilder, path);
     436        stringBuilder.flexibleAppend(" = ", m_stageInParameterName, '.', elementName, ";\n");
     437    }
     438}
     439
     440void VertexEntryPointScaffolding::emitPack(StringBuilder& stringBuilder, MangledVariableName inputVariableName, MangledVariableName outputVariableName)
     441{
    455442    stringBuilder.flexibleAppend(m_returnStructName, ' ', outputVariableName, ";\n");
    456443    if (m_entryPointItems.outputs.size() == 1 && !m_entryPointItems.outputs[0].path.size()) {
    457444        auto& elementName = m_namedOutputs[0].elementName;
    458445        stringBuilder.flexibleAppend(outputVariableName, '.', elementName, " = ", inputVariableName, ";\n");
    459         return stringBuilder.toString();
     446        return;
    460447    }
    461448    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
     
    463450        auto& internalTypeName = m_namedOutputs[i].internalTypeName;
    464451        auto& path = m_entryPointItems.outputs[i].path;
    465         stringBuilder.flexibleAppend(outputVariableName, '.', elementName, " = ", internalTypeName, '(', inputVariableName, mangledOutputPath(path), ");\n");
    466     }
    467     return stringBuilder.toString();
     452        stringBuilder.flexibleAppend(outputVariableName, '.', elementName, " = ", internalTypeName, '(', inputVariableName);
     453        emitMangledOutputPath(stringBuilder, path);
     454        stringBuilder.flexibleAppend(");\n");
     455    }
    468456}
    469457
     
    502490}
    503491
    504 String FragmentEntryPointScaffolding::helperTypes()
    505 {
    506     StringBuilder stringBuilder;
    507 
     492void FragmentEntryPointScaffolding::emitHelperTypes(StringBuilder& stringBuilder)
     493{
    508494    stringBuilder.flexibleAppend("struct ", m_stageInStructName, " {\n");
    509495    for (auto& namedStageIn : m_namedStageIns) {
     
    524510        stringBuilder.flexibleAppend("    ", internalTypeName, ' ', elementName, ' ', attribute, ";\n");
    525511    }
    526     stringBuilder.flexibleAppend(
    527         "};\n\n",
    528         resourceHelperTypes()
     512    stringBuilder.append(
     513        "};\n\n"
    529514    );
    530515
    531     return stringBuilder.toString();
    532 }
    533 
    534 String FragmentEntryPointScaffolding::signature(MangledFunctionName functionName)
    535 {
    536     StringBuilder stringBuilder;
    537 
     516    emitResourceHelperTypes(stringBuilder);
     517}
     518
     519void FragmentEntryPointScaffolding::emitSignature(StringBuilder& stringBuilder, MangledFunctionName functionName)
     520{
    538521    stringBuilder.flexibleAppend("fragment ", m_returnStructName, ' ', functionName, '(', m_stageInStructName, ' ', m_stageInParameterName, " [[stage_in]]");
    539     if (auto resourceSignature = this->resourceSignature())
    540         stringBuilder.flexibleAppend(", ", *resourceSignature);
    541     if (auto builtInsSignature = this->builtInsSignature())
    542         stringBuilder.flexibleAppend(", ", *builtInsSignature);
     522    emitResourceSignature(stringBuilder, IncludePrecedingComma::Yes);
     523    emitBuiltInsSignature(stringBuilder, IncludePrecedingComma::Yes);
    543524    stringBuilder.append(')');
    544 
    545     return stringBuilder.toString();
    546 }
    547 
    548 String FragmentEntryPointScaffolding::unpack()
    549 {
    550     StringBuilder stringBuilder;
    551 
    552     stringBuilder.append(unpackResourcesAndNamedBuiltIns());
     525}
     526
     527void FragmentEntryPointScaffolding::emitUnpack(StringBuilder& stringBuilder)
     528{
     529    emitUnpackResourcesAndNamedBuiltIns(stringBuilder);
    553530
    554531    for (auto& namedStageIn : m_namedStageIns) {
    555532        auto& path = m_entryPointItems.inputs[namedStageIn.indexInEntryPointItems].path;
    556533        auto& elementName = namedStageIn.elementName;
    557         stringBuilder.flexibleAppend(mangledInputPath(path), " = ", m_stageInParameterName, '.', elementName, ";\n");
    558     }
    559 
    560     return stringBuilder.toString();
    561 }
    562 
    563 String FragmentEntryPointScaffolding::pack(MangledVariableName inputVariableName, MangledVariableName outputVariableName)
    564 {
    565     StringBuilder stringBuilder;
    566 
     534        emitMangledInputPath(stringBuilder, path);
     535        stringBuilder.flexibleAppend(" = ", m_stageInParameterName, '.', elementName, ";\n");
     536    }
     537}
     538
     539void FragmentEntryPointScaffolding::emitPack(StringBuilder& stringBuilder, MangledVariableName inputVariableName, MangledVariableName outputVariableName)
     540{
    567541    stringBuilder.flexibleAppend(m_returnStructName, ' ', outputVariableName, ";\n");
    568542    if (m_entryPointItems.outputs.size() == 1 && !m_entryPointItems.outputs[0].path.size()) {
    569543        auto& elementName = m_namedOutputs[0].elementName;
    570544        stringBuilder.flexibleAppend(outputVariableName, '.', elementName, " = ", inputVariableName, ";\n");
    571         return stringBuilder.toString();
     545        return;
    572546    }
    573547    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
     
    575549        auto& internalTypeName = m_namedOutputs[i].internalTypeName;
    576550        auto& path = m_entryPointItems.outputs[i].path;
    577         stringBuilder.flexibleAppend(outputVariableName, '.', elementName, " = ", internalTypeName, '(', inputVariableName, mangledOutputPath(path), ");\n");
    578     }
    579     return stringBuilder.toString();
     551        stringBuilder.flexibleAppend(outputVariableName, '.', elementName, " = ", internalTypeName, '(', inputVariableName);
     552        emitMangledOutputPath(stringBuilder, path);
     553        stringBuilder.flexibleAppend(");\n");
     554    }
    580555}
    581556
     
    585560}
    586561
    587 String ComputeEntryPointScaffolding::helperTypes()
    588 {
    589     return resourceHelperTypes();
    590 }
    591 
    592 String ComputeEntryPointScaffolding::signature(MangledFunctionName functionName)
    593 {
    594     StringBuilder stringBuilder;
    595 
     562void ComputeEntryPointScaffolding::emitHelperTypes(StringBuilder& stringBuilder)
     563{
     564    emitResourceHelperTypes(stringBuilder);
     565}
     566
     567void ComputeEntryPointScaffolding::emitSignature(StringBuilder& stringBuilder, MangledFunctionName functionName)
     568{
    596569    stringBuilder.flexibleAppend("kernel void ", functionName, '(');
    597     bool empty = true;
    598     if (auto resourceSignature = this->resourceSignature()) {
    599         empty = false;
    600         stringBuilder.append(*resourceSignature);
    601     }
    602     if (auto builtInsSignature = this->builtInsSignature()) {
    603         if (!empty)
    604             stringBuilder.append(", ");
    605         stringBuilder.append(*builtInsSignature);
    606     }
     570    bool addedToSignature = emitResourceSignature(stringBuilder, IncludePrecedingComma::No);
     571    emitBuiltInsSignature(stringBuilder, addedToSignature ? IncludePrecedingComma::Yes : IncludePrecedingComma::No);
    607572    stringBuilder.append(')');
    608 
    609     return stringBuilder.toString();
    610 }
    611 
    612 String ComputeEntryPointScaffolding::unpack()
    613 {
    614     return unpackResourcesAndNamedBuiltIns();
    615 }
    616 
    617 String ComputeEntryPointScaffolding::pack(MangledVariableName, MangledVariableName)
     573}
     574
     575void ComputeEntryPointScaffolding::emitUnpack(StringBuilder& stringBuilder)
     576{
     577    emitUnpackResourcesAndNamedBuiltIns(stringBuilder);
     578}
     579
     580void ComputeEntryPointScaffolding::emitPack(StringBuilder&, MangledVariableName, MangledVariableName)
    618581{
    619582    ASSERT_NOT_REACHED();
    620     return String();
    621583}
    622584
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h

    r248266 r248307  
    5454    virtual ~EntryPointScaffolding() = default;
    5555
    56     virtual String helperTypes() = 0;
    57     virtual String signature(MangledFunctionName) = 0;
    58     virtual String unpack() = 0;
    59     virtual String pack(MangledVariableName existingVariableName, MangledVariableName) = 0;
     56    virtual void emitHelperTypes(StringBuilder&) = 0;
     57    virtual void emitSignature(StringBuilder&, MangledFunctionName) = 0;
     58    virtual void emitUnpack(StringBuilder&) = 0;
     59    virtual void emitPack(StringBuilder&, MangledVariableName existingVariableName, MangledVariableName) = 0;
    6060
    6161    Vector<MangledVariableName>& parameterVariables() { return m_parameterVariables; }
     
    6464    EntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName);
    6565
    66     String resourceHelperTypes();
    67     Optional<String> resourceSignature();
    68     Optional<String> builtInsSignature();
     66    void emitResourceHelperTypes(StringBuilder&);
    6967
    70     String mangledInputPath(Vector<String>& path);
    71     String mangledOutputPath(Vector<String>& path);
    72     String unpackResourcesAndNamedBuiltIns();
     68    enum class IncludePrecedingComma {
     69        Yes,
     70        No
     71    };
     72    bool emitResourceSignature(StringBuilder&, IncludePrecedingComma);
     73    bool emitBuiltInsSignature(StringBuilder&, IncludePrecedingComma);
     74
     75    void emitMangledInputPath(StringBuilder&, Vector<String>& path);
     76    void emitMangledOutputPath(StringBuilder&, Vector<String>& path);
     77    void emitUnpackResourcesAndNamedBuiltIns(StringBuilder&);
    7378
    7479    AST::FunctionDefinition& m_functionDefinition;
     
    107112};
    108113
    109 class VertexEntryPointScaffolding : public EntryPointScaffolding {
     114class VertexEntryPointScaffolding final : public EntryPointScaffolding {
    110115public:
    111116    VertexEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName, HashMap<VertexAttribute*, size_t>& matchedVertexAttributes);
    112117    virtual ~VertexEntryPointScaffolding() = default;
    113118
    114     String helperTypes() override;
    115     String signature(MangledFunctionName) override;
    116     String unpack() override;
    117     String pack(MangledVariableName existingVariableName, MangledVariableName) override;
     119private:
     120    void emitHelperTypes(StringBuilder&) override;
     121    void emitSignature(StringBuilder&, MangledFunctionName) override;
     122    void emitUnpack(StringBuilder&) override;
     123    void emitPack(StringBuilder&, MangledVariableName existingVariableName, MangledVariableName) override;
    118124
    119 private:
    120125    HashMap<VertexAttribute*, size_t>& m_matchedVertexAttributes;
    121126    MangledTypeName m_stageInStructName;
     
    137142};
    138143
    139 class FragmentEntryPointScaffolding : public EntryPointScaffolding {
     144class FragmentEntryPointScaffolding final : public EntryPointScaffolding {
    140145public:
    141146    FragmentEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName, HashMap<AttachmentDescriptor*, size_t>& matchedColorAttachments);
    142147    virtual ~FragmentEntryPointScaffolding() = default;
    143148
    144     String helperTypes() override;
    145     String signature(MangledFunctionName) override;
    146     String unpack() override;
    147     String pack(MangledVariableName existingVariableName, MangledVariableName) override;
     149private:
     150    void emitHelperTypes(StringBuilder&) override;
     151    void emitSignature(StringBuilder&, MangledFunctionName) override;
     152    void emitUnpack(StringBuilder&) override;
     153    void emitPack(StringBuilder&, MangledVariableName existingVariableName, MangledVariableName) override;
    148154
    149 private:
    150155    MangledTypeName m_stageInStructName;
    151156    MangledTypeName m_returnStructName;
     
    166171};
    167172
    168 class ComputeEntryPointScaffolding : public EntryPointScaffolding {
     173class ComputeEntryPointScaffolding final : public EntryPointScaffolding {
    169174public:
    170175    ComputeEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName);
    171176    virtual ~ComputeEntryPointScaffolding() = default;
    172177
    173     String helperTypes() override;
    174     String signature(MangledFunctionName) override;
    175     String unpack() override;
    176     String pack(MangledVariableName existingVariableName, MangledVariableName) override;
     178private:
     179    void emitHelperTypes(StringBuilder&) override;
     180    void emitSignature(StringBuilder&, MangledFunctionName) override;
     181    void emitUnpack(StringBuilder&) override;
     182    void emitPack(StringBuilder&, MangledVariableName existingVariableName, MangledVariableName) override;
    177183};
    178184
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp

    r248280 r248307  
    4848namespace Metal {
    4949
    50 class FunctionDeclarationWriter : public Visitor {
     50class FunctionDeclarationWriter final : public Visitor {
    5151public:
    52     FunctionDeclarationWriter(TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping)
     52    FunctionDeclarationWriter(StringBuilder& stringBuilder, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping)
    5353        : m_typeNamer(typeNamer)
    5454        , m_functionMapping(functionMapping)
     55        , m_stringBuilder(stringBuilder)
    5556    {
    5657    }
    5758
    5859    virtual ~FunctionDeclarationWriter() = default;
    59 
    60     String toString() { return m_stringBuilder.toString(); }
    6160
    6261    void visit(AST::FunctionDeclaration&) override;
     
    6564    TypeNamer& m_typeNamer;
    6665    HashMap<AST::FunctionDeclaration*, MangledFunctionName>& m_functionMapping;
    67     StringBuilder m_stringBuilder;
     66    StringBuilder& m_stringBuilder;
    6867};
    6968
     
    8685class FunctionDefinitionWriter : public Visitor {
    8786public:
    88     FunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, Layout& layout)
    89         : m_intrinsics(intrinsics)
     87    FunctionDefinitionWriter(StringBuilder& stringBuilder, Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, Layout& layout)
     88        : m_stringBuilder(stringBuilder)
     89        , m_intrinsics(intrinsics)
    9090        , m_typeNamer(typeNamer)
    9191        , m_functionMapping(functionMapping)
     
    9595
    9696    virtual ~FunctionDefinitionWriter() = default;
    97 
    98     String toString() { return m_stringBuilder.toString(); }
    9997
    10098    void visit(AST::NativeFunctionDeclaration&) override;
     
    149147    void emitLoop(LoopConditionLocation, AST::Expression* conditionExpression, AST::Expression* increment, AST::Statement& body);
    150148
    151     String constantExpressionString(AST::ConstantExpression&);
     149    void emitConstantExpressionString(AST::ConstantExpression&);
    152150
    153151    MangledVariableName generateNextVariableName() { return { m_variableCount++ }; }
     
    216214    Optional<BreakContext> m_currentBreakContext;
    217215
     216    StringBuilder& m_stringBuilder;
    218217    Intrinsics& m_intrinsics;
    219218    TypeNamer& m_typeNamer;
    220219    HashMap<AST::FunctionDeclaration*, MangledFunctionName>& m_functionMapping;
    221220    HashMap<AST::VariableDeclaration*, MangledVariableName> m_variableMapping;
    222     StringBuilder m_stringBuilder;
    223221
    224222    Vector<StackItem> m_stack;
     
    243241            return;
    244242        m_entryPointScaffolding = WTFMove(entryPointScaffolding);
    245         m_stringBuilder.flexibleAppend(
    246             m_entryPointScaffolding->helperTypes(), '\n',
    247             m_entryPointScaffolding->signature(iterator->value), " {\n",
    248             m_entryPointScaffolding->unpack()
    249         );
     243        m_entryPointScaffolding->emitHelperTypes(m_stringBuilder);
     244        m_stringBuilder.append('\n');
     245        m_entryPointScaffolding->emitSignature(m_stringBuilder, iterator->value);
     246        m_stringBuilder.append(" {\n");
     247        m_entryPointScaffolding->emitUnpack(m_stringBuilder);
     248   
    250249        for (size_t i = 0; i < functionDefinition.parameters().size(); ++i) {
    251250            auto addResult = m_variableMapping.add(&functionDefinition.parameters()[i], m_entryPointScaffolding->parameterVariables()[i]);
     
    407406        if (m_entryPointScaffolding) {
    408407            auto variableName = generateNextVariableName();
    409             m_stringBuilder.flexibleAppend(
    410                 m_entryPointScaffolding->pack(takeLastValue(), variableName),
    411                 "return ", variableName, ";\n"
    412             );
     408            m_entryPointScaffolding->emitPack(m_stringBuilder, takeLastValue(), variableName);
     409            m_stringBuilder.flexibleAppend("return ", variableName, ";\n");
    413410        } else
    414411            m_stringBuilder.flexibleAppend("return ", takeLastValue(), ";\n");
     
    429426void FunctionDefinitionWriter::visit(AST::SwitchCase& switchCase)
    430427{
    431     if (switchCase.value())
    432         m_stringBuilder.flexibleAppend("case ", constantExpressionString(*switchCase.value()), ":\n");
    433     else
     428    if (switchCase.value()) {
     429        m_stringBuilder.flexibleAppend("case ");
     430        emitConstantExpressionString(*switchCase.value());
     431        m_stringBuilder.flexibleAppend(":\n");
     432    } else
    434433        m_stringBuilder.append("default:\n");
    435434    SetForScope<Optional<BreakContext>> breakContext(m_currentBreakContext, BreakContext::Switch);
     
    736735}
    737736
    738 String FunctionDefinitionWriter::constantExpressionString(AST::ConstantExpression& constantExpression)
    739 {
    740     return constantExpression.visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) -> String {
    741         return makeString("", integerLiteral.value());
    742     }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) -> String {
    743         return makeString("", unsignedIntegerLiteral.value());
    744     }, [&](AST::FloatLiteral& floatLiteral) -> String {
    745         return makeString("", floatLiteral.value());
    746     }, [&](AST::NullLiteral&) -> String {
    747         return "nullptr"_str;
    748     }, [&](AST::BooleanLiteral& booleanLiteral) -> String {
    749         return booleanLiteral.value() ? "true"_str : "false"_str;
    750     }, [&](AST::EnumerationMemberLiteral& enumerationMemberLiteral) -> String {
    751         ASSERT(enumerationMemberLiteral.enumerationDefinition());
    752         ASSERT(enumerationMemberLiteral.enumerationDefinition());
    753         return makeString(m_typeNamer.mangledNameForType(*enumerationMemberLiteral.enumerationDefinition()), "::", m_typeNamer.mangledNameForEnumerationMember(*enumerationMemberLiteral.enumerationMember()));
    754     }));
    755 }
    756 
    757 class RenderFunctionDefinitionWriter : public FunctionDefinitionWriter {
     737void FunctionDefinitionWriter::emitConstantExpressionString(AST::ConstantExpression& constantExpression)
     738{
     739    constantExpression.visit(WTF::makeVisitor(
     740        [&](AST::IntegerLiteral& integerLiteral) {
     741            m_stringBuilder.flexibleAppend(integerLiteral.value());
     742        },
     743        [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) {
     744            m_stringBuilder.flexibleAppend(unsignedIntegerLiteral.value());
     745        },
     746        [&](AST::FloatLiteral& floatLiteral) {
     747            m_stringBuilder.flexibleAppend(floatLiteral.value());
     748        },
     749        [&](AST::NullLiteral&) {
     750            m_stringBuilder.flexibleAppend("nullptr");
     751        },
     752        [&](AST::BooleanLiteral& booleanLiteral) {
     753            if (booleanLiteral.value())
     754                m_stringBuilder.flexibleAppend("true");
     755            else
     756                m_stringBuilder.flexibleAppend("false");
     757        },
     758        [&](AST::EnumerationMemberLiteral& enumerationMemberLiteral) {
     759            ASSERT(enumerationMemberLiteral.enumerationDefinition());
     760            ASSERT(enumerationMemberLiteral.enumerationDefinition());
     761            m_stringBuilder.flexibleAppend(m_typeNamer.mangledNameForType(*enumerationMemberLiteral.enumerationDefinition()), "::", m_typeNamer.mangledNameForEnumerationMember(*enumerationMemberLiteral.enumerationMember()));
     762        }
     763    ));
     764}
     765
     766class RenderFunctionDefinitionWriter final : public FunctionDefinitionWriter {
    758767public:
    759     RenderFunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
    760         : FunctionDefinitionWriter(intrinsics, typeNamer, functionMapping, layout)
     768    RenderFunctionDefinitionWriter(StringBuilder& stringBuilder, Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
     769        : FunctionDefinitionWriter(stringBuilder, intrinsics, typeNamer, functionMapping, layout)
    761770        , m_matchedSemantics(WTFMove(matchedSemantics))
    762771    {
     
    781790}
    782791
    783 class ComputeFunctionDefinitionWriter : public FunctionDefinitionWriter {
     792class ComputeFunctionDefinitionWriter final : public FunctionDefinitionWriter {
    784793public:
    785     ComputeFunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
    786         : FunctionDefinitionWriter(intrinsics, typeNamer, functionMapping, layout)
     794    ComputeFunctionDefinitionWriter(StringBuilder& stringBuilder, Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
     795        : FunctionDefinitionWriter(stringBuilder, intrinsics, typeNamer, functionMapping, layout)
    787796        , m_matchedSemantics(WTFMove(matchedSemantics))
    788797    {
     
    805814}
    806815
    807 struct SharedMetalFunctionsResult {
    808     HashMap<AST::FunctionDeclaration*, MangledFunctionName> functionMapping;
    809     String metalFunctions;
    810 };
    811 static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNamer& typeNamer, const HashSet<AST::FunctionDeclaration*>& reachableFunctions)
    812 {
    813     StringBuilder stringBuilder;
    814 
     816static HashMap<AST::FunctionDeclaration*, MangledFunctionName> generateMetalFunctionsMapping(Program& program)
     817{
    815818    unsigned numFunctions = 0;
    816819    HashMap<AST::FunctionDeclaration*, MangledFunctionName> functionMapping;
     
    820823    }
    821824
    822     {
    823         FunctionDeclarationWriter functionDeclarationWriter(typeNamer, functionMapping);
    824         for (auto& functionDefinition : program.functionDefinitions()) {
    825             if (!functionDefinition->entryPointType() && reachableFunctions.contains(&functionDefinition))
    826                 functionDeclarationWriter.visit(functionDefinition);
    827         }
    828         stringBuilder.append(functionDeclarationWriter.toString());
     825    return functionMapping;
     826}
     827
     828static void emitSharedMetalFunctions(StringBuilder& stringBuilder, Program& program, TypeNamer& typeNamer, const HashSet<AST::FunctionDeclaration*>& reachableFunctions, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping)
     829{
     830    FunctionDeclarationWriter functionDeclarationWriter(stringBuilder, typeNamer, functionMapping);
     831    for (auto& functionDefinition : program.functionDefinitions()) {
     832        if (!functionDefinition->entryPointType() && reachableFunctions.contains(&functionDefinition))
     833            functionDeclarationWriter.visit(functionDefinition);
    829834    }
    830835
    831836    stringBuilder.append('\n');
    832     return { WTFMove(functionMapping), stringBuilder.toString() };
    833 }
    834 
    835 class ReachableFunctionsGatherer : public Visitor {
     837}
     838
     839class ReachableFunctionsGatherer final : public Visitor {
    836840public:
    837841    void visit(AST::FunctionDeclaration& functionDeclaration) override
     
    856860};
    857861
    858 RenderMetalFunctions metalFunctions(Program& program, TypeNamer& typeNamer, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
     862RenderMetalFunctionEntryPoints emitMetalFunctions(StringBuilder& stringBuilder, Program& program, TypeNamer& typeNamer, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
    859863{
    860864    auto& vertexShaderEntryPoint = *matchedSemantics.vertexShader;
     
    866870    auto reachableFunctions = reachableFunctionsGatherer.takeReachableFunctions();
    867871
    868     auto sharedMetalFunctions = Metal::sharedMetalFunctions(program, typeNamer, reachableFunctions);
    869 
    870     StringBuilder stringBuilder;
    871     stringBuilder.append(sharedMetalFunctions.metalFunctions);
    872 
    873     RenderFunctionDefinitionWriter functionDefinitionWriter(program.intrinsics(), typeNamer, sharedMetalFunctions.functionMapping, WTFMove(matchedSemantics), layout);
     872    auto functionMapping = generateMetalFunctionsMapping(program);
     873   
     874    emitSharedMetalFunctions(stringBuilder, program, typeNamer, reachableFunctions, functionMapping);
     875
     876    RenderFunctionDefinitionWriter functionDefinitionWriter(stringBuilder, program.intrinsics(), typeNamer, functionMapping, WTFMove(matchedSemantics), layout);
    874877    for (auto& functionDefinition : program.functionDefinitions()) {
    875878        if (reachableFunctions.contains(&functionDefinition))
    876879            functionDefinitionWriter.visit(functionDefinition);
    877880    }
    878     stringBuilder.append(functionDefinitionWriter.toString());
    879 
    880     RenderMetalFunctions result;
    881     result.metalSource = stringBuilder.toString();
    882     result.mangledVertexEntryPointName = sharedMetalFunctions.functionMapping.get(&vertexShaderEntryPoint);
    883     result.mangledFragmentEntryPointName = sharedMetalFunctions.functionMapping.get(&fragmentShaderEntryPoint);
    884     return result;
    885 }
    886 
    887 ComputeMetalFunctions metalFunctions(Program& program, TypeNamer& typeNamer, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
     881
     882    return { functionMapping.get(&vertexShaderEntryPoint), functionMapping.get(&fragmentShaderEntryPoint) };
     883}
     884
     885ComputeMetalFunctionEntryPoints emitMetalFunctions(StringBuilder& stringBuilder, Program& program, TypeNamer& typeNamer, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
    888886{
    889887    auto& entryPoint = *matchedSemantics.shader;
     
    893891    auto reachableFunctions = reachableFunctionsGatherer.takeReachableFunctions();
    894892
    895     auto sharedMetalFunctions = Metal::sharedMetalFunctions(program, typeNamer, reachableFunctions);
    896 
    897     StringBuilder stringBuilder;
    898     stringBuilder.append(sharedMetalFunctions.metalFunctions);
    899 
    900     ComputeFunctionDefinitionWriter functionDefinitionWriter(program.intrinsics(), typeNamer, sharedMetalFunctions.functionMapping, WTFMove(matchedSemantics), layout);
     893    auto functionMapping = generateMetalFunctionsMapping(program);
     894    emitSharedMetalFunctions(stringBuilder, program, typeNamer, reachableFunctions, functionMapping);
     895
     896    ComputeFunctionDefinitionWriter functionDefinitionWriter(stringBuilder, program.intrinsics(), typeNamer, functionMapping, WTFMove(matchedSemantics), layout);
    901897    for (auto& functionDefinition : program.functionDefinitions()) {
    902898        if (reachableFunctions.contains(&functionDefinition))
    903899            functionDefinitionWriter.visit(functionDefinition);
    904900    }
    905     stringBuilder.append(functionDefinitionWriter.toString());
    906 
    907     ComputeMetalFunctions result;
    908     result.metalSource = stringBuilder.toString();
    909     result.mangledEntryPointName = sharedMetalFunctions.functionMapping.get(&entryPoint);
    910     return result;
     901
     902    return { functionMapping.get(&entryPoint) };
    911903}
    912904
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.h

    r248266 r248307  
    4141class TypeNamer;
    4242
    43 struct RenderMetalFunctions {
    44     String metalSource;
     43struct RenderMetalFunctionEntryPoints {
    4544    MangledFunctionName mangledVertexEntryPointName;
    4645    MangledFunctionName mangledFragmentEntryPointName;
    4746};
    48 RenderMetalFunctions metalFunctions(Program&, TypeNamer&, MatchedRenderSemantics&&, Layout&);
     47RenderMetalFunctionEntryPoints emitMetalFunctions(StringBuilder&, Program&, TypeNamer&, MatchedRenderSemantics&&, Layout&);
    4948
    50 struct ComputeMetalFunctions {
    51     String metalSource;
     49struct ComputeMetalFunctionEntryPoints {
    5250    MangledFunctionName mangledEntryPointName;
    5351};
    54 ComputeMetalFunctions metalFunctions(Program&, TypeNamer&, MatchedComputeSemantics&&, Layout&);
     52ComputeMetalFunctionEntryPoints emitMetalFunctions(StringBuilder&, Program&, TypeNamer&, MatchedComputeSemantics&&, Layout&);
    5553
    5654}
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp

    r247917 r248307  
    4242static constexpr bool dumpMetalCode = false;
    4343
    44 static String generateMetalCodeShared(String&& metalTypes, String&& metalFunctions)
     44static StringView metalCodeProlog()
    4545{
    46     auto generatedMetalCode = makeString(
     46    return StringView {
    4747        "#include <metal_stdlib>\n"
    4848        "#include <metal_atomic>\n"
     
    5353        "\n"
    5454        "using namespace metal;\n"
    55         "\n",
     55        "\n"
     56    };
     57}
    5658
    57         WTFMove(metalTypes),
    58         WTFMove(metalFunctions)
    59     );
    60 
     59static void dumpMetalCodeIfNeeded(StringBuilder& stringBuilder)
     60{
    6161    if (dumpMetalCode) {
    6262        dataLogLn("Generated Metal code: ");
    63         dataLogLn(generatedMetalCode);
     63        dataLogLn(stringBuilder.toString());
    6464    }
    65 
    66     return generatedMetalCode;
    6765}
    6866
    6967RenderMetalCode generateMetalCode(Program& program, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
    7068{
     69    StringBuilder stringBuilder;
     70    stringBuilder.append(metalCodeProlog());
     71
    7172    TypeNamer typeNamer(program);
    72     auto metalTypes = typeNamer.metalTypes();
    73     auto metalFunctions = Metal::metalFunctions(program, typeNamer, WTFMove(matchedSemantics), layout);
    74     auto metalCode = generateMetalCodeShared(WTFMove(metalTypes), WTFMove(metalFunctions.metalSource));
    75     return { WTFMove(metalCode), WTFMove(metalFunctions.mangledVertexEntryPointName), WTFMove(metalFunctions.mangledFragmentEntryPointName) };
     73    typeNamer.emitMetalTypes(stringBuilder);
     74   
     75    auto metalFunctionEntryPoints = Metal::emitMetalFunctions(stringBuilder, program, typeNamer, WTFMove(matchedSemantics), layout);
     76
     77    dumpMetalCodeIfNeeded(stringBuilder);
     78
     79    return { WTFMove(stringBuilder), WTFMove(metalFunctionEntryPoints.mangledVertexEntryPointName), WTFMove(metalFunctionEntryPoints.mangledFragmentEntryPointName) };
    7680}
    7781
    7882ComputeMetalCode generateMetalCode(Program& program, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
    7983{
     84    StringBuilder stringBuilder;
     85    stringBuilder.append(metalCodeProlog());
     86
    8087    TypeNamer typeNamer(program);
    81     auto metalTypes = typeNamer.metalTypes();
    82     auto metalFunctions = Metal::metalFunctions(program, typeNamer, WTFMove(matchedSemantics), layout);
    83     auto metalCode = generateMetalCodeShared(WTFMove(metalTypes), WTFMove(metalFunctions.metalSource));
    84     return { WTFMove(metalCode), WTFMove(metalFunctions.mangledEntryPointName) };
     88    typeNamer.emitMetalTypes(stringBuilder);
     89
     90    auto metalFunctionEntryPoints = Metal::emitMetalFunctions(stringBuilder, program, typeNamer, WTFMove(matchedSemantics), layout);
     91
     92    dumpMetalCodeIfNeeded(stringBuilder);
     93
     94    return { WTFMove(stringBuilder), WTFMove(metalFunctionEntryPoints.mangledEntryPointName) };
    8595}
    8696
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.h

    r248266 r248307  
    3131#include "WHLSLPipelineDescriptor.h"
    3232#include "WHLSLSemanticMatcher.h"
    33 #include <wtf/Variant.h>
    34 #include <wtf/text/WTFString.h>
     33#include <wtf/text/StringBuilder.h>
    3534
    3635namespace WebCore {
     
    4342
    4443struct RenderMetalCode {
    45     String metalSource;
     44    StringBuilder metalSource;
    4645    MangledFunctionName mangledVertexEntryPointName;
    4746    MangledFunctionName mangledFragmentEntryPointName;
     
    5150
    5251struct ComputeMetalCode {
    53     String metalSource;
     52    StringBuilder metalSource;
    5453    MangledFunctionName mangledEntryPointName;
    5554};
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp

    r248266 r248307  
    352352}
    353353
    354 class MetalTypeDeclarationWriter : public Visitor {
     354class MetalTypeDeclarationWriter final : public Visitor {
    355355    WTF_MAKE_FAST_ALLOCATED;
    356356public:
    357     MetalTypeDeclarationWriter(std::function<MangledOrNativeTypeName(AST::NamedType&)>&& mangledNameForNamedType)
     357    MetalTypeDeclarationWriter(StringBuilder& stringBuilder, std::function<MangledOrNativeTypeName(AST::NamedType&)>&& mangledNameForNamedType)
    358358        : m_mangledNameForNamedType(WTFMove(mangledNameForNamedType))
    359     {
    360     }
    361 
    362     String toString() { return m_stringBuilder.toString(); }
     359        , m_stringBuilder(stringBuilder)
     360    {
     361    }
    363362
    364363private:
    365     void visit(AST::StructureDefinition& structureDefinition)
     364    void visit(AST::StructureDefinition& structureDefinition) override
    366365    {
    367366        m_stringBuilder.flexibleAppend("struct ", m_mangledNameForNamedType(structureDefinition), ";\n");
     
    369368
    370369    std::function<MangledOrNativeTypeName(AST::NamedType&)> m_mangledNameForNamedType;
    371     StringBuilder m_stringBuilder;
     370    StringBuilder& m_stringBuilder;
    372371};
    373372
    374 String TypeNamer::metalTypeDeclarations()
    375 {
    376     MetalTypeDeclarationWriter metalTypeDeclarationWriter([&](AST::NamedType& namedType) -> MangledOrNativeTypeName {
     373void TypeNamer::emitMetalTypeDeclarations(StringBuilder& stringBuilder)
     374{
     375    MetalTypeDeclarationWriter metalTypeDeclarationWriter(stringBuilder, [&](AST::NamedType& namedType) -> MangledOrNativeTypeName {
    377376        return mangledNameForType(namedType);
    378377    });
    379378    metalTypeDeclarationWriter.Visitor::visit(m_program);
    380     return metalTypeDeclarationWriter.toString();
    381 }
    382 
    383 void TypeNamer::emitUnnamedTypeDefinition(BaseTypeNameNode& baseTypeNameNode, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
     379}
     380
     381void TypeNamer::emitUnnamedTypeDefinition(StringBuilder& stringBuilder, BaseTypeNameNode& baseTypeNameNode, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes)
    384382{
    385383    if (emittedUnnamedTypes.contains(&baseTypeNameNode))
    386384        return;
    387385    if (baseTypeNameNode.parent())
    388         emitUnnamedTypeDefinition(*baseTypeNameNode.parent(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
     386        emitUnnamedTypeDefinition(stringBuilder, *baseTypeNameNode.parent(), emittedNamedTypes, emittedUnnamedTypes);
    389387    if (is<ReferenceTypeNameNode>(baseTypeNameNode)) {
    390388        auto& namedType = downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType();
    391         emitNamedTypeDefinition(namedType, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
     389        emitNamedTypeDefinition(stringBuilder, namedType, emittedNamedTypes, emittedUnnamedTypes);
    392390        stringBuilder.flexibleAppend("typedef ", mangledNameForType(namedType), ' ', baseTypeNameNode.mangledName(), ";\n");
    393391    } else if (is<PointerTypeNameNode>(baseTypeNameNode)) {
     
    412410}
    413411
    414 void TypeNamer::emitNamedTypeDefinition(AST::NamedType& namedType, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
     412void TypeNamer::emitNamedTypeDefinition(StringBuilder& stringBuilder, AST::NamedType& namedType, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes)
    415413{
    416414    if (emittedNamedTypes.contains(&namedType))
     
    419417    ASSERT(iterator != m_dependencyGraph.end());
    420418    for (auto& baseTypeNameNode : iterator->value)
    421         emitUnnamedTypeDefinition(baseTypeNameNode, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
     419        emitUnnamedTypeDefinition(stringBuilder, baseTypeNameNode, emittedNamedTypes, emittedUnnamedTypes);
    422420    if (is<AST::EnumerationDefinition>(namedType)) {
    423421        auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(namedType);
     
    442440}
    443441
    444 void TypeNamer::emitAllUnnamedTypeDefinitions(Vector<UniqueRef<BaseTypeNameNode>>& nodes, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
     442void TypeNamer::emitAllUnnamedTypeDefinitions(StringBuilder& stringBuilder, Vector<UniqueRef<BaseTypeNameNode>>& nodes, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes)
    445443{
    446444    for (auto& node : nodes) {
    447         emitUnnamedTypeDefinition(node, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
    448         emitAllUnnamedTypeDefinitions(node->children(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
    449     }
    450 }
    451 
    452 String TypeNamer::metalTypeDefinitions()
     445        emitUnnamedTypeDefinition(stringBuilder, node, emittedNamedTypes, emittedUnnamedTypes);
     446        emitAllUnnamedTypeDefinitions(stringBuilder, node->children(), emittedNamedTypes, emittedUnnamedTypes);
     447    }
     448}
     449
     450void TypeNamer::emitMetalTypeDefinitions(StringBuilder& stringBuilder)
    453451{
    454452    HashSet<AST::NamedType*> emittedNamedTypes;
    455453    HashSet<BaseTypeNameNode*> emittedUnnamedTypes;
    456     StringBuilder stringBuilder;
    457454    for (auto& keyValuePair : m_dependencyGraph)
    458         emitNamedTypeDefinition(*keyValuePair.key, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
    459     emitAllUnnamedTypeDefinitions(m_trie, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
    460     return stringBuilder.toString();
     455        emitNamedTypeDefinition(stringBuilder, *keyValuePair.key, emittedNamedTypes, emittedUnnamedTypes);
     456    emitAllUnnamedTypeDefinitions(stringBuilder, m_trie, emittedNamedTypes, emittedUnnamedTypes);
    461457}
    462458
     
    490486}
    491487
    492 String TypeNamer::metalTypes()
     488void TypeNamer::emitMetalTypes(StringBuilder& stringBuilder)
    493489{
    494490    Visitor::visit(m_program);
    495     return makeString(metalTypeDeclarations(), '\n', metalTypeDefinitions());
     491
     492    emitMetalTypeDeclarations(stringBuilder);
     493    stringBuilder.append('\n');
     494    emitMetalTypeDefinitions(stringBuilder);
    496495}
    497496
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h

    r248266 r248307  
    6060    virtual ~TypeNamer();
    6161
    62     String metalTypes();
     62    void emitMetalTypes(StringBuilder&);
    6363
    6464    // Must be called after calling metalTypes().
     
    8383    MangledEnumerationMemberName generateNextEnumerationMemberName() { return { m_enumerationMemberCount++ }; }
    8484
    85     void emitNamedTypeDefinition(AST::NamedType&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder&);
    86     void emitUnnamedTypeDefinition(BaseTypeNameNode&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder&);
    87     void emitAllUnnamedTypeDefinitions(Vector<UniqueRef<BaseTypeNameNode>>&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder&);
    88     String metalTypeDeclarations();
    89     String metalTypeDefinitions();
     85    void emitNamedTypeDefinition(StringBuilder&, AST::NamedType&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes);
     86    void emitUnnamedTypeDefinition(StringBuilder&, BaseTypeNameNode&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes);
     87    void emitAllUnnamedTypeDefinitions(StringBuilder&, Vector<UniqueRef<BaseTypeNameNode>>&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes);
     88    void emitMetalTypeDeclarations(StringBuilder&);
     89    void emitMetalTypeDefinitions(StringBuilder&);
    9090
    9191    UniqueRef<BaseTypeNameNode> createNameNode(AST::UnnamedType&, BaseTypeNameNode* parent);
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp

    r248303 r248307  
    696696        CONSUME_TYPE(spaceToken, Identifier);
    697697        auto spaceTokenStringView = spaceToken->stringView(m_lexer);
    698         auto prefix = "space"_str;
    699         if (!spaceTokenStringView.startsWith(StringView(prefix)))
     698        StringView prefix { "space" };
     699        if (!spaceTokenStringView.startsWith(prefix))
    700700            return Unexpected<Error>(Error(makeString("Second argument to resource semantic ", spaceTokenStringView, " needs be of the form 'space0'")));
    701701        if (spaceTokenStringView.length() <= prefix.length())
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h

    r248277 r248307  
    3131#include "WHLSLMangledNames.h"
    3232#include "WHLSLPipelineDescriptor.h"
     33#include <wtf/text/StringBuilder.h>
    3334#include <wtf/text/WTFString.h>
    3435
     
    4041
    4142struct RenderPrepareResult {
    42     String metalSource;
     43    StringBuilder metalSource;
    4344    Metal::MangledFunctionName mangledVertexEntryPointName;
    4445    Metal::MangledFunctionName mangledFragmentEntryPointName;
     
    5354
    5455struct ComputePrepareResult {
    55     String metalSource;
     56    StringBuilder metalSource;
    5657    Metal::MangledFunctionName mangledEntryPointName;
    5758    ComputeDimensions computeDimensions;
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm

    r248277 r248307  
    9191        if (WHLSL::dumpMetalCompileTimes)
    9292            startTime = MonotonicTime::now();
    93         computeLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource options:nil error:&error]);
     93        // FIXME: https://webkit.org/b/200474 Add direct StringBuilder -> NSString conversion to avoid extra copy into a WTF::String
     94        computeLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource.toString() options:nil error:&error]);
    9495        if (WHLSL::dumpMetalCompileTimes)
    9596            dataLogLn("Metal compile times: ", (MonotonicTime::now() - startTime).milliseconds(), " ms");
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm

    r248277 r248307  
    403403        if (WHLSL::dumpMetalCompileTimes)
    404404            startTime = MonotonicTime::now();
    405         vertexLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource options:nil error:&error]);
     405        // FIXME: https://webkit.org/b/200474 Add direct StringBuilder -> NSString conversion to avoid extra copy into a WTF::String
     406        vertexLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource.toString() options:nil error:&error]);
    406407        if (WHLSL::dumpMetalCompileTimes)
    407408            dataLogLn("Metal compile times: ", (MonotonicTime::now() - startTime).milliseconds(), " ms");
Note: See TracChangeset for help on using the changeset viewer.