Changeset 246396 in webkit


Ignore:
Timestamp:
Jun 12, 2019 11:06:53 PM (5 years ago)
Author:
mmaxfield@apple.com
Message:

[WHLSL] Hook up compute
https://bugs.webkit.org/show_bug.cgi?id=198644

Reviewed by Saam Barati.

Source/WebCore:

This patch hooks up compute shaders in exactly the same way that vertex and fragment shaders
are hooked up. I've modified the two patchs (compute and rendering) to be almost exactly the
same code.

This patch also adds support for the WHLSL compiler to determine what the numthreads()
attribute in the shader says so that it can be hooked up to Metal's threads-per-threadgroup
argument in the dispatch call. There is some logic to make sure that there aren't two
numthreads() attributes on the same compute shader.

It also adds a little bit of type renaming. For built-in variables, sometimes Metal's type
doesn't always match WHLSL's (and HLSL's type). For example, in WHLSL and HLSL, SV_DispatchThreadID variables have to be a float3, but in Metal, they are a uint3.
Therefore, I've added a little bit of code during each entry point's pack and unpack stages
to handle this type conversion.

Test: webgpu/whlsl-compute.html

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

(WebCore::WHLSL::Metal::internalTypeForSemantic): Determine which Metal type corresponds to
each built-in variable.
(WebCore::WHLSL::Metal::EntryPointScaffolding::builtInsSignature): Perform the type
conversion.
(WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): Ditto.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::VertexEntryPointScaffolding): Ditto.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::helperTypes): Ditto.
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::pack): Ditto.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::FragmentEntryPointScaffolding): Ditto.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::helperTypes): Ditto.
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::pack): Ditto.
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::signature): Ditto.

  • Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:
  • Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp: Added. Add a pass to determine whether

or not any entry point has duplicate numthreads() attribute, and to determine what the
appropriate numthreads() values should be for the current entry point.
(WebCore::WHLSL::ComputeDimensionsVisitor::ComputeDimensionsVisitor):
(WebCore::WHLSL::ComputeDimensionsVisitor::computeDimensions const):
(WebCore::WHLSL::computeDimensions):

  • Modules/webgpu/WHLSL/WHLSLComputeDimensions.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h.
  • Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp:

(WebCore::WHLSL::gatherEntryPointItems): Compute shaders don't need to have a semantic for their return type.

  • Modules/webgpu/WHLSL/WHLSLPrepare.cpp:

(WebCore::WHLSL::prepare): Run the computeDimensions() pass.

  • Modules/webgpu/WHLSL/WHLSLPrepare.h:
  • Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp: In a left-value propertyAccessExpression,

the index expression can be a right-value. Treat it as such.
(WebCore::WHLSL::LeftValueSimplifier::finishVisiting):
(WebCore::WHLSL::LeftValueSimplifier::visit):

  • Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt: We need support for multiplication (for a

test) and float3 for SV_DispatchThreadID.

  • Sources.txt:
  • SourcesCocoa.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/gpu/GPUComputePipeline.h: Associate a compute dimensions with a particular

compute pipeline. This is how Metal knows what values to use for a dispatch.
(WebCore::GPUComputePipeline::computeDimensions const):

  • platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm: Use the saved compute dimensions.

(WebCore::GPUComputePassEncoder::dispatch):

  • platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm: Make the code match GPURenderPipelineMetal.

(WebCore::trySetMetalFunctions):
(WebCore::trySetFunctions):
(WebCore::convertComputePipelineDescriptor):
(WebCore::tryCreateMTLComputePipelineState):
(WebCore::GPUComputePipeline::tryCreate):
(WebCore::GPUComputePipeline::GPUComputePipeline):
(WebCore::tryCreateMtlComputeFunction): Deleted.

  • platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp: Added. Moved shared helper

functions to a file where they can be accessed by multiple places.
(WebCore::convertShaderStageFlags):
(WebCore::convertBindingType):
(WebCore::convertLayout):

  • platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h.
  • platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm: Delete the functions that were moved to GPUPipelineMetalConvertLayout.

(WebCore::trySetFunctions):
(WebCore::tryCreateMtlRenderPipelineState):
(WebCore::convertShaderStageFlags): Deleted.
(WebCore::convertBindingType): Deleted.
(WebCore::convertLayout): Deleted.

LayoutTests:

This doesn't thoroughly test compute, but it's at least enough to unblock the WHLSL testing effort.

  • webgpu/compute-squares-expected.txt: Deleted. Covered by webgpu/whlsl-compute.html.
  • webgpu/compute-squares.html: Deleted. Ditto.
  • webgpu/whlsl-compute-expected.txt: Added.
  • webgpu/whlsl-compute.html: Added.
Location:
trunk
Files:
4 added
2 deleted
16 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246394 r246396  
     12019-06-12  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        [WHLSL] Hook up compute
     4        https://bugs.webkit.org/show_bug.cgi?id=198644
     5
     6        Reviewed by Saam Barati.
     7
     8        This doesn't thoroughly test compute, but it's at least enough to unblock the WHLSL testing effort.
     9
     10        * webgpu/compute-squares-expected.txt: Deleted. Covered by webgpu/whlsl-compute.html.
     11        * webgpu/compute-squares.html: Deleted. Ditto.
     12        * webgpu/whlsl-compute-expected.txt: Added.
     13        * webgpu/whlsl-compute.html: Added.
     14
    1152019-06-12  Myles C. Maxfield  <mmaxfield@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r246394 r246396  
     12019-06-12  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        [WHLSL] Hook up compute
     4        https://bugs.webkit.org/show_bug.cgi?id=198644
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch hooks up compute shaders in exactly the same way that vertex and fragment shaders
     9        are hooked up. I've modified the two patchs (compute and rendering) to be almost exactly the
     10        same code.
     11
     12        This patch also adds support for the WHLSL compiler to determine what the numthreads()
     13        attribute in the shader says so that it can be hooked up to Metal's threads-per-threadgroup
     14        argument in the dispatch call. There is some logic to make sure that there aren't two
     15        numthreads() attributes on the same compute shader.
     16
     17        It also adds a little bit of type renaming. For built-in variables, sometimes Metal's type
     18        doesn't always match WHLSL's (and HLSL's type). For example, in WHLSL and HLSL,        SV_DispatchThreadID variables have to be a float3, but in Metal, they are a uint3.
     19        Therefore, I've added a little bit of code during each entry point's pack and unpack stages
     20        to handle this type conversion.
     21
     22        Test: webgpu/whlsl-compute.html
     23
     24        * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp:
     25        (WebCore::WHLSL::Metal::internalTypeForSemantic): Determine which Metal type corresponds to
     26        each built-in variable.
     27        (WebCore::WHLSL::Metal::EntryPointScaffolding::builtInsSignature): Perform the type
     28        conversion.
     29        (WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): Ditto.
     30        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::VertexEntryPointScaffolding): Ditto.
     31        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::helperTypes): Ditto.
     32        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::pack): Ditto.
     33        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::FragmentEntryPointScaffolding): Ditto.
     34        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::helperTypes): Ditto.
     35        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::pack): Ditto.
     36        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::signature): Ditto.
     37        * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:
     38        * Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp: Added. Add a pass to determine whether
     39        or not any entry point has duplicate numthreads() attribute, and to determine what the
     40        appropriate numthreads() values should be for the current entry point.
     41        (WebCore::WHLSL::ComputeDimensionsVisitor::ComputeDimensionsVisitor):
     42        (WebCore::WHLSL::ComputeDimensionsVisitor::computeDimensions const):
     43        (WebCore::WHLSL::computeDimensions):
     44        * Modules/webgpu/WHLSL/WHLSLComputeDimensions.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h.
     45        * Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp:
     46        (WebCore::WHLSL::gatherEntryPointItems): Compute shaders don't need to have a semantic for their return type.
     47        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
     48        (WebCore::WHLSL::prepare): Run the computeDimensions() pass.
     49        * Modules/webgpu/WHLSL/WHLSLPrepare.h:
     50        * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp: In a left-value propertyAccessExpression,
     51        the index expression can be a right-value. Treat it as such.
     52        (WebCore::WHLSL::LeftValueSimplifier::finishVisiting):
     53        (WebCore::WHLSL::LeftValueSimplifier::visit):
     54        * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt: We need support for multiplication (for a
     55        test) and float3 for SV_DispatchThreadID.
     56        * Sources.txt:
     57        * SourcesCocoa.txt:
     58        * WebCore.xcodeproj/project.pbxproj:
     59        * platform/graphics/gpu/GPUComputePipeline.h: Associate a compute dimensions with a particular
     60        compute pipeline. This is how Metal knows what values to use for a dispatch.
     61        (WebCore::GPUComputePipeline::computeDimensions const):
     62        * platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm: Use the saved compute dimensions.
     63        (WebCore::GPUComputePassEncoder::dispatch):
     64        * platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm: Make the code match GPURenderPipelineMetal.
     65        (WebCore::trySetMetalFunctions):
     66        (WebCore::trySetFunctions):
     67        (WebCore::convertComputePipelineDescriptor):
     68        (WebCore::tryCreateMTLComputePipelineState):
     69        (WebCore::GPUComputePipeline::tryCreate):
     70        (WebCore::GPUComputePipeline::GPUComputePipeline):
     71        (WebCore::tryCreateMtlComputeFunction): Deleted.
     72        * platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp: Added. Moved shared helper
     73        functions to a file where they can be accessed by multiple places.
     74        (WebCore::convertShaderStageFlags):
     75        (WebCore::convertBindingType):
     76        (WebCore::convertLayout):
     77        * platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h.
     78        * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm: Delete the functions that were moved to GPUPipelineMetalConvertLayout.
     79        (WebCore::trySetFunctions):
     80        (WebCore::tryCreateMtlRenderPipelineState):
     81        (WebCore::convertShaderStageFlags): Deleted.
     82        (WebCore::convertBindingType): Deleted.
     83        (WebCore::convertLayout): Deleted.
     84
    1852019-06-12  Myles C. Maxfield  <mmaxfield@apple.com>
    286
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp

    r246394 r246396  
    179179}
    180180
     181static String internalTypeForSemantic(const AST::BuiltInSemantic& builtInSemantic)
     182{
     183    switch (builtInSemantic.variable()) {
     184    case AST::BuiltInSemantic::Variable::SVInstanceID:
     185        return "uint"_str;
     186    case AST::BuiltInSemantic::Variable::SVVertexID:
     187        return "uint"_str;
     188    case AST::BuiltInSemantic::Variable::PSize:
     189        return "float"_str;
     190    case AST::BuiltInSemantic::Variable::SVPosition:
     191        return "float4"_str;
     192    case AST::BuiltInSemantic::Variable::SVIsFrontFace:
     193        return "bool"_str;
     194    case AST::BuiltInSemantic::Variable::SVSampleIndex:
     195        return "uint"_str;
     196    case AST::BuiltInSemantic::Variable::SVInnerCoverage:
     197        return "uint"_str;
     198    case AST::BuiltInSemantic::Variable::SVTarget:
     199        return String();
     200    case AST::BuiltInSemantic::Variable::SVDepth:
     201        return "float"_str;
     202    case AST::BuiltInSemantic::Variable::SVCoverage:
     203        return "uint"_str;
     204    case AST::BuiltInSemantic::Variable::SVDispatchThreadID:
     205        return "uint3"_str;
     206    case AST::BuiltInSemantic::Variable::SVGroupID:
     207        return "uint3"_str;
     208    case AST::BuiltInSemantic::Variable::SVGroupIndex:
     209        return "uint"_str;
     210    default:
     211        ASSERT(builtInSemantic.variable() == AST::BuiltInSemantic::Variable::SVGroupThreadID);
     212        return "uint3"_str;
     213    }
     214}
     215
    181216Optional<String> EntryPointScaffolding::builtInsSignature()
    182217{
     
    191226        auto& item = m_entryPointItems.inputs[namedBuiltIn.indexInEntryPointItems];
    192227        auto& builtInSemantic = WTF::get<AST::BuiltInSemantic>(*item.semantic);
    193         auto mangledTypeName = m_typeNamer.mangledNameForType(*item.unnamedType);
     228        auto internalType = internalTypeForSemantic(builtInSemantic);
     229        if (internalType.isNull())
     230            internalType = m_typeNamer.mangledNameForType(*item.unnamedType);
    194231        auto variableName = namedBuiltIn.variableName;
    195         stringBuilder.append(makeString(mangledTypeName, ' ', variableName, ' ', attributeForSemantic(builtInSemantic)));
     232        stringBuilder.append(makeString(internalType, ' ', variableName, ' ', attributeForSemantic(builtInSemantic)));
    196233    }
    197234    return stringBuilder.toString();
     
    300337
    301338    for (auto& namedBuiltIn : m_namedBuiltIns) {
    302         auto& path = m_entryPointItems.inputs[namedBuiltIn.indexInEntryPointItems].path;
     339        auto& item = m_entryPointItems.inputs[namedBuiltIn.indexInEntryPointItems];
     340        auto& path = item.path;
    303341        auto& variableName = namedBuiltIn.variableName;
    304         stringBuilder.append(makeString(mangledInputPath(path), " = ", variableName, ";\n"));
     342        auto mangledTypeName = m_typeNamer.mangledNameForType(*item.unnamedType);
     343        stringBuilder.append(makeString(mangledInputPath(path), " = ", mangledTypeName, '(', variableName, ");\n"));
    305344    }
    306345    return stringBuilder.toString();
     
    325364    m_namedOutputs.reserveInitialCapacity(m_entryPointItems.outputs.size());
    326365    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
     366        auto& outputItem = m_entryPointItems.outputs[i];
    327367        NamedOutput namedOutput;
    328368        namedOutput.elementName = m_typeNamer.generateNextStructureElementName();
     369        if (WTF::holds_alternative<AST::BuiltInSemantic>(*outputItem.semantic))
     370            namedOutput.internalTypeName = internalTypeForSemantic(WTF::get<AST::BuiltInSemantic>(*outputItem.semantic));
     371        if (namedOutput.internalTypeName.isNull())
     372            namedOutput.internalTypeName = m_typeNamer.mangledNameForType(*outputItem.unnamedType);
    329373        m_namedOutputs.uncheckedAppend(WTFMove(namedOutput));
    330374    }
     
    347391    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
    348392        auto& outputItem = m_entryPointItems.outputs[i];
    349         auto mangledTypeName = m_typeNamer.mangledNameForType(*outputItem.unnamedType);
     393        auto& internalTypeName = m_namedOutputs[i].internalTypeName;
    350394        auto elementName = m_namedOutputs[i].elementName;
    351395        auto attribute = attributeForSemantic(*outputItem.semantic);
    352         stringBuilder.append(makeString("    ", mangledTypeName, ' ', elementName, ' ', attribute, ";\n"));
     396        stringBuilder.append(makeString("    ", internalTypeName, ' ', elementName, ' ', attribute, ";\n"));
    353397    }
    354398    stringBuilder.append("};\n\n");
     
    399443    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
    400444        auto& elementName = m_namedOutputs[i].elementName;
     445        auto& internalTypeName = m_namedOutputs[i].internalTypeName;
    401446        auto& path = m_entryPointItems.outputs[i].path;
    402         stringBuilder.append(makeString(outputVariableName, '.', elementName, " = ", inputVariableName, mangledOutputPath(path), ";\n"));
     447        stringBuilder.append(makeString(outputVariableName, '.', elementName, " = ", internalTypeName, '(', inputVariableName, mangledOutputPath(path), ");\n"));
    403448    }
    404449    return stringBuilder.toString();
     
    425470    m_namedOutputs.reserveInitialCapacity(m_entryPointItems.outputs.size());
    426471    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
     472        auto& outputItem = m_entryPointItems.outputs[i];
    427473        NamedOutput namedOutput;
    428474        namedOutput.elementName = m_typeNamer.generateNextStructureElementName();
     475        if (WTF::holds_alternative<AST::BuiltInSemantic>(*outputItem.semantic))
     476            namedOutput.internalTypeName = internalTypeForSemantic(WTF::get<AST::BuiltInSemantic>(*outputItem.semantic));
     477        if (namedOutput.internalTypeName.isNull())
     478            namedOutput.internalTypeName = m_typeNamer.mangledNameForType(*outputItem.unnamedType);
    429479        m_namedOutputs.uncheckedAppend(WTFMove(namedOutput));
    430480    }
     
    447497    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
    448498        auto& outputItem = m_entryPointItems.outputs[i];
    449         auto mangledTypeName = m_typeNamer.mangledNameForType(*outputItem.unnamedType);
     499        auto& internalTypeName = m_namedOutputs[i].internalTypeName;
    450500        auto elementName = m_namedOutputs[i].elementName;
    451501        auto attribute = attributeForSemantic(*outputItem.semantic);
    452         stringBuilder.append(makeString("    ", mangledTypeName, ' ', elementName, ' ', attribute, ";\n"));
     502        stringBuilder.append(makeString("    ", internalTypeName, ' ', elementName, ' ', attribute, ";\n"));
    453503    }
    454504    stringBuilder.append("};\n\n");
     
    499549    for (size_t i = 0; i < m_entryPointItems.outputs.size(); ++i) {
    500550        auto& elementName = m_namedOutputs[i].elementName;
     551        auto& internalTypeName = m_namedOutputs[i].internalTypeName;
    501552        auto& path = m_entryPointItems.outputs[i].path;
    502         stringBuilder.append(makeString(outputVariableName, '.', elementName, " = ", inputVariableName, mangledOutputPath(path), ";\n"));
     553        stringBuilder.append(makeString(outputVariableName, '.', elementName, " = ", internalTypeName, '(', inputVariableName, mangledOutputPath(path), ");\n"));
    503554    }
    504555    return stringBuilder.toString();
     
    519570    StringBuilder stringBuilder;
    520571
    521     stringBuilder.append(makeString("compute void ", functionName, '('));
     572    stringBuilder.append(makeString("kernel void ", functionName, '('));
    522573    bool empty = true;
    523574    if (auto resourceSignature = this->resourceSignature()) {
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h

    r246394 r246396  
    130130    struct NamedOutput {
    131131        String elementName;
     132        String internalTypeName;
    132133    };
    133134    Vector<NamedOutput> m_namedOutputs;
     
    158159    struct NamedOutput {
    159160        String elementName;
     161        String internalTypeName;
    160162    };
    161163    Vector<NamedOutput> m_namedOutputs;
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.h

    r246394 r246396  
    2828#if ENABLE(WEBGPU)
    2929
    30 #include "WHLSLPipelineDescriptor.h"
    31 #include <wtf/text/WTFString.h>
     30#include "WHLSLPrepare.h"
    3231
    3332namespace WebCore {
     
    3534namespace WHLSL {
    3635
    37 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Generate descriptive error messages and return them here.
    38 struct RenderPrepareResult {
    39     String metalSource;
    40     String mangledVertexEntryPointName;
    41     String mangledFragmentEntryPointName;
    42 };
    43 Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor&);
     36class Program;
    4437
    45 struct ComputePrepareResult {
    46     String metalSource;
    47     String mangledEntryPointName;
    48 };
    49 Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor&);
     38Optional<ComputeDimensions> computeDimensions(Program&, AST::FunctionDefinition&);
    5039
    51 } // namespace WHLSL
     40}
    5241
    53 } // namespace WebCore
     42}
    5443
    55 #endif // ENABLE(WEBGPU)
     44#endif
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp

    r245680 r246396  
    176176    }
    177177    Gatherer outputGatherer(intrinsics, functionDefinition.semantic() ? &*functionDefinition.semantic() : nullptr);
    178     outputGatherer.checkErrorAndVisit(functionDefinition.type());
     178    if (*functionDefinition.entryPointType() != AST::EntryPointType::Compute)
     179        outputGatherer.checkErrorAndVisit(functionDefinition.type());
    179180    if (outputGatherer.error())
    180181        return WTF::nullopt;
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp

    r246273 r246396  
    3333#include "WHLSLCheckDuplicateFunctions.h"
    3434#include "WHLSLChecker.h"
     35#include "WHLSLComputeDimensions.h"
    3536#include "WHLSLFunctionStageChecker.h"
    3637#include "WHLSLHighZombieFinder.h"
     
    171172    if (!matchedSemantics)
    172173        return WTF::nullopt;
     174    auto computeDimensions = WHLSL::computeDimensions(*program, *matchedSemantics->shader);
     175    if (!computeDimensions)
     176        return WTF::nullopt;
    173177
    174178    auto generatedCode = Metal::generateMetalCode(*program, WTFMove(*matchedSemantics), computePipelineDescriptor.layout);
     
    177181    result.metalSource = WTFMove(generatedCode.metalSource);
    178182    result.mangledEntryPointName = WTFMove(generatedCode.mangledEntryPointName);
     183    result.computeDimensions = WTFMove(*computeDimensions);
    179184    return result;
    180185}
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h

    r245680 r246396  
    4343Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor&);
    4444
     45struct ComputeDimensions {
     46    unsigned width;
     47    unsigned height;
     48    unsigned depth;
     49};
     50
    4551struct ComputePrepareResult {
    4652    String metalSource;
    4753    String mangledEntryPointName;
     54    ComputeDimensions computeDimensions;
    4855};
    4956Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor&);
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp

    r246394 r246396  
    775775    ASSERT(propertyAccessExpression.anderFunction());
    776776
     777    Visitor::visit(propertyAccessExpression.base());
     778
    777779    Lexer::Token origin = propertyAccessExpression.origin();
    778780    auto* anderFunction = propertyAccessExpression.anderFunction();
     
    805807void LeftValueSimplifier::visit(AST::IndexExpression& indexExpression)
    806808{
    807     Visitor::visit(indexExpression);
    808809    PropertyResolver().Visitor::visit(indexExpression.indexExpression());
    809810    finishVisiting(indexExpression);
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt

    r246385 r246396  
    433433native operator float(half);
    434434
    435 native float operator.x(float4);
    436 native float operator.y(float4);
    437 native float operator.z(float4);
    438 native float operator.w(float4);
    439 native float4 operator.x=(float4, float);
    440 native float4 operator.y=(float4, float);
    441 native float4 operator.z=(float4, float);
    442 native float4 operator.w=(float4, float);
    443 
    444435native float operator+(float, float);
    445436native float operator-(float, float);
     
    449440native bool operator<(uint, uint);
    450441native bool operator<(float, float);
     442native float operator*(float, float);
     443
     444native bool operator.x(bool2);
     445native bool operator.y(bool2);
     446native bool operator.x(bool3);
     447native bool operator.y(bool3);
     448native bool operator.z(bool3);
     449native bool operator.x(bool4);
     450native bool operator.y(bool4);
     451native bool operator.z(bool4);
     452native bool operator.w(bool4);
     453native bool2 operator.x=(bool2, bool);
     454native bool2 operator.y=(bool2, bool);
     455native bool3 operator.x=(bool3, bool);
     456native bool3 operator.y=(bool3, bool);
     457native bool3 operator.z=(bool3, bool);
     458native bool4 operator.x=(bool4, bool);
     459native bool4 operator.y=(bool4, bool);
     460native bool4 operator.z=(bool4, bool);
     461native bool4 operator.w=(bool4, bool);
     462native uchar operator.x(uchar2);
     463native uchar operator.y(uchar2);
     464native uchar operator.x(uchar3);
     465native uchar operator.y(uchar3);
     466native uchar operator.z(uchar3);
     467native uchar operator.x(uchar4);
     468native uchar operator.y(uchar4);
     469native uchar operator.z(uchar4);
     470native uchar operator.w(uchar4);
     471native uchar2 operator.x=(uchar2, uchar);
     472native uchar2 operator.y=(uchar2, uchar);
     473native uchar3 operator.x=(uchar3, uchar);
     474native uchar3 operator.y=(uchar3, uchar);
     475native uchar3 operator.z=(uchar3, uchar);
     476native uchar4 operator.x=(uchar4, uchar);
     477native uchar4 operator.y=(uchar4, uchar);
     478native uchar4 operator.z=(uchar4, uchar);
     479native uchar4 operator.w=(uchar4, uchar);
     480native ushort operator.x(ushort2);
     481native ushort operator.y(ushort2);
     482native ushort operator.x(ushort3);
     483native ushort operator.y(ushort3);
     484native ushort operator.z(ushort3);
     485native ushort operator.x(ushort4);
     486native ushort operator.y(ushort4);
     487native ushort operator.z(ushort4);
     488native ushort operator.w(ushort4);
     489native ushort2 operator.x=(ushort2, ushort);
     490native ushort2 operator.y=(ushort2, ushort);
     491native ushort3 operator.x=(ushort3, ushort);
     492native ushort3 operator.y=(ushort3, ushort);
     493native ushort3 operator.z=(ushort3, ushort);
     494native ushort4 operator.x=(ushort4, ushort);
     495native ushort4 operator.y=(ushort4, ushort);
     496native ushort4 operator.z=(ushort4, ushort);
     497native ushort4 operator.w=(ushort4, ushort);
     498native uint operator.x(uint2);
     499native uint operator.y(uint2);
     500native uint operator.x(uint3);
     501native uint operator.y(uint3);
     502native uint operator.z(uint3);
     503native uint operator.x(uint4);
     504native uint operator.y(uint4);
     505native uint operator.z(uint4);
     506native uint operator.w(uint4);
     507native uint2 operator.x=(uint2, uint);
     508native uint2 operator.y=(uint2, uint);
     509native uint3 operator.x=(uint3, uint);
     510native uint3 operator.y=(uint3, uint);
     511native uint3 operator.z=(uint3, uint);
     512native uint4 operator.x=(uint4, uint);
     513native uint4 operator.y=(uint4, uint);
     514native uint4 operator.z=(uint4, uint);
     515native uint4 operator.w=(uint4, uint);
     516native char operator.x(char2);
     517native char operator.y(char2);
     518native char operator.x(char3);
     519native char operator.y(char3);
     520native char operator.z(char3);
     521native char operator.x(char4);
     522native char operator.y(char4);
     523native char operator.z(char4);
     524native char operator.w(char4);
     525native char2 operator.x=(char2, char);
     526native char2 operator.y=(char2, char);
     527native char3 operator.x=(char3, char);
     528native char3 operator.y=(char3, char);
     529native char3 operator.z=(char3, char);
     530native char4 operator.x=(char4, char);
     531native char4 operator.y=(char4, char);
     532native char4 operator.z=(char4, char);
     533native char4 operator.w=(char4, char);
     534native short operator.x(short2);
     535native short operator.y(short2);
     536native short operator.x(short3);
     537native short operator.y(short3);
     538native short operator.z(short3);
     539native short operator.x(short4);
     540native short operator.y(short4);
     541native short operator.z(short4);
     542native short operator.w(short4);
     543native short2 operator.x=(short2, short);
     544native short2 operator.y=(short2, short);
     545native short3 operator.x=(short3, short);
     546native short3 operator.y=(short3, short);
     547native short3 operator.z=(short3, short);
     548native short4 operator.x=(short4, short);
     549native short4 operator.y=(short4, short);
     550native short4 operator.z=(short4, short);
     551native short4 operator.w=(short4, short);
     552native int operator.x(int2);
     553native int operator.y(int2);
     554native int operator.x(int3);
     555native int operator.y(int3);
     556native int operator.z(int3);
     557native int operator.x(int4);
     558native int operator.y(int4);
     559native int operator.z(int4);
     560native int operator.w(int4);
     561native int2 operator.x=(int2, int);
     562native int2 operator.y=(int2, int);
     563native int3 operator.x=(int3, int);
     564native int3 operator.y=(int3, int);
     565native int3 operator.z=(int3, int);
     566native int4 operator.x=(int4, int);
     567native int4 operator.y=(int4, int);
     568native int4 operator.z=(int4, int);
     569native int4 operator.w=(int4, int);
     570native half operator.x(half2);
     571native half operator.y(half2);
     572native half operator.x(half3);
     573native half operator.y(half3);
     574native half operator.z(half3);
     575native half operator.x(half4);
     576native half operator.y(half4);
     577native half operator.z(half4);
     578native half operator.w(half4);
     579native half2 operator.x=(half2, half);
     580native half2 operator.y=(half2, half);
     581native half3 operator.x=(half3, half);
     582native half3 operator.y=(half3, half);
     583native half3 operator.z=(half3, half);
     584native half4 operator.x=(half4, half);
     585native half4 operator.y=(half4, half);
     586native half4 operator.z=(half4, half);
     587native half4 operator.w=(half4, half);
     588native float operator.x(float2);
     589native float operator.y(float2);
     590native float operator.x(float3);
     591native float operator.y(float3);
     592native float operator.z(float3);
     593native float operator.x(float4);
     594native float operator.y(float4);
     595native float operator.z(float4);
     596native float operator.w(float4);
     597native float2 operator.x=(float2, float);
     598native float2 operator.y=(float2, float);
     599native float3 operator.x=(float3, float);
     600native float3 operator.y=(float3, float);
     601native float3 operator.z=(float3, float);
     602native float4 operator.x=(float4, float);
     603native float4 operator.y=(float4, float);
     604native float4 operator.z=(float4, float);
     605native float4 operator.w=(float4, float);
    451606
    452607native float ddx(float);
  • trunk/Source/WebCore/Sources.txt

    r246273 r246396  
    307307Modules/webgpu/GPUCanvasContext.cpp
    308308Modules/webgpu/NavigatorGPU.cpp
     309Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp
    309310Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
    310311Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp
  • trunk/Source/WebCore/SourcesCocoa.txt

    r246270 r246396  
    327327platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm
    328328platform/graphics/gpu/cocoa/GPUDeviceMetal.mm
     329platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp
    329330platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm
    330331platform/graphics/gpu/cocoa/GPUQueueMetal.mm
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r246388 r246396  
    63956395                1C840B9A21EC400900D0500D /* WHLSLGatherEntryPointItems.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLGatherEntryPointItems.h; sourceTree = "<group>"; };
    63966396                1C840B9B21EC400900D0500D /* WHLSLChecker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLChecker.cpp; sourceTree = "<group>"; };
     6397                1C86CA4B22AA19FF001BF961 /* WHLSLComputeDimensions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLComputeDimensions.cpp; sourceTree = "<group>"; };
     6398                1C86CA4C22AA19FF001BF961 /* WHLSLComputeDimensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLComputeDimensions.h; sourceTree = "<group>"; };
     6399                1C86CA4E22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUPipelineMetalConvertLayout.cpp; sourceTree = "<group>"; };
     6400                1C86CA4F22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUPipelineMetalConvertLayout.h; sourceTree = "<group>"; };
    63976401                1C904DF90BA9D2C80081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
    63986402                1C9AE5CA21ED9DF50069D5F2 /* WHLSLHighZombieFinder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLHighZombieFinder.cpp; sourceTree = "<group>"; };
     
    2544925453                                1C840B9B21EC400900D0500D /* WHLSLChecker.cpp */,
    2545025454                                1C840B9721EC400700D0500D /* WHLSLChecker.h */,
     25455                                1C86CA4B22AA19FF001BF961 /* WHLSLComputeDimensions.cpp */,
     25456                                1C86CA4C22AA19FF001BF961 /* WHLSLComputeDimensions.h */,
    2545125457                                1CA0C2E421EED12A00A11860 /* WHLSLFunctionStageChecker.cpp */,
    2545225458                                1CA0C2E521EED12A00A11860 /* WHLSLFunctionStageChecker.h */,
     
    2598825994                                D089033B224179B500F3F440 /* GPUComputePipelineMetal.mm */,
    2598925995                                D087CE3C21ACA94200BDE174 /* GPUDeviceMetal.mm */,
     25996                                1C86CA4E22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.cpp */,
     25997                                1C86CA4F22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.h */,
    2599025998                                D087CE3B21ACA94200BDE174 /* GPUProgrammablePassEncoderMetal.mm */,
    2599125999                                D087CE3921ACA94200BDE174 /* GPUQueueMetal.mm */,
  • trunk/Source/WebCore/platform/graphics/gpu/GPUComputePipeline.h

    r243627 r246396  
    2828#if ENABLE(WEBGPU)
    2929
     30#include "WHLSLPrepare.h"
    3031#include <wtf/RefCounted.h>
    3132#include <wtf/RefPtr.h>
     
    4950    const PlatformComputePipeline* platformComputePipeline() const { return m_platformComputePipeline.get(); }
    5051
     52    WHLSL::ComputeDimensions computeDimensions() const { return m_computeDimensions; }
     53
    5154private:
    52     GPUComputePipeline(PlatformComputePipelineSmartPtr&&);
     55    GPUComputePipeline(PlatformComputePipelineSmartPtr&&, WHLSL::ComputeDimensions);
    5356
    5457    PlatformComputePipelineSmartPtr m_platformComputePipeline;
     58    WHLSL::ComputeDimensions m_computeDimensions { 0, 0, 0 };
    5559};
    5660
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm

    r244406 r246396  
    9898    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    9999
    100     auto w = pipelineState.threadExecutionWidth;
    101     auto h = pipelineState.maxTotalThreadsPerThreadgroup / w;
    102 
    103     // FIXME: This should be gleaned from the shader if not using MSL. For now, use the docs' example calculation.
    104     auto threadsPerThreadgroup = MTLSizeMake(w, h, 1);
     100    auto threadsPerThreadgroup = MTLSizeMake(m_pipeline->computeDimensions().width, m_pipeline->computeDimensions().height, m_pipeline->computeDimensions().depth);
    105101
    106102    auto threadgroupsPerGrid = MTLSizeMake(x, y, z);
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm

    r243627 r246396  
    3131#import "GPUComputePipelineDescriptor.h"
    3232#import "GPUDevice.h"
     33#import "GPUPipelineMetalConvertLayout.h"
    3334#import "Logging.h"
     35#import "WHLSLPrepare.h"
    3436#import <Metal/Metal.h>
    3537#import <wtf/BlockObjCExceptions.h>
    3638
    37 OBJC_PROTOCOL(MTLFunction);
    38 
    3939namespace WebCore {
    4040
    41 static RetainPtr<MTLFunction> tryCreateMtlComputeFunction(const GPUPipelineStageDescriptor& stage)
    42 {
    43     if (!stage.module->platformShaderModule() || stage.entryPoint.isNull()) {
    44         LOG(WebGPU, "GPUComputePipeline::tryCreate(): Invalid GPUShaderModule!");
    45         return nullptr;
    46     }
    47 
    48     RetainPtr<MTLFunction> function;
     41static bool trySetMetalFunctions(const char* const functionName, MTLLibrary *computeMetalLibrary, MTLComputePipelineDescriptor *mtlDescriptor, const String& computeEntryPointName)
     42{
     43#if LOG_DISABLED
     44    UNUSED_PARAM(functionName);
     45#endif
    4946
    5047    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    51     function = adoptNS([stage.module->platformShaderModule() newFunctionWithName:stage.entryPoint]);
     48
     49    if (!computeMetalLibrary) {
     50        LOG(WebGPU, "%s: MTLLibrary for compute stage does not exist!", functionName);
     51        return false;
     52    }
     53
     54    auto function = adoptNS([computeMetalLibrary newFunctionWithName:computeEntryPointName]);
     55    if (!function) {
     56        LOG(WebGPU, "%s: Cannot create compute MTLFunction \"%s\"!", functionName, computeEntryPointName.utf8().data());
     57        return false;
     58    }
     59
     60    [mtlDescriptor setComputeFunction:function.get()];
     61    return true;
     62
    5263    END_BLOCK_OBJC_EXCEPTIONS;
    5364
    54     if (!function)
    55         LOG(WebGPU, "GPUComputePipeline::tryCreate(): Cannot create compute MTLFunction \"%s\"!", stage.entryPoint.utf8().data());
    56 
    57     return function;
    58 }
    59 
    60 static RetainPtr<MTLComputePipelineState> tryCreateMTLComputePipelineState(const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor)
     65    return false;
     66}
     67
     68static Optional<WHLSL::ComputeDimensions> trySetFunctions(const char* const functionName, const GPUPipelineStageDescriptor& computeStage, const GPUDevice& device, MTLComputePipelineDescriptor* mtlDescriptor, Optional<WHLSL::ComputePipelineDescriptor>& whlslDescriptor)
     69{
     70#if LOG_DISABLED
     71    UNUSED_PARAM(functionName);
     72#endif
     73    RetainPtr<MTLLibrary> computeLibrary;
     74    String computeEntryPoint;
     75
     76    WHLSL::ComputeDimensions computeDimensions { 1, 1, 1 };
     77
     78    if (whlslDescriptor) {
     79        // WHLSL functions are compiled to MSL first.
     80        String whlslSource = computeStage.module->whlslSource();
     81        ASSERT(!whlslSource.isNull());
     82
     83        whlslDescriptor->entryPointName = computeStage.entryPoint;
     84
     85        auto whlslCompileResult = WHLSL::prepare(whlslSource, *whlslDescriptor);
     86        if (!whlslCompileResult)
     87            return WTF::nullopt;
     88        computeDimensions = whlslCompileResult->computeDimensions;
     89
     90        NSError *error = nil;
     91
     92        BEGIN_BLOCK_OBJC_EXCEPTIONS;
     93        computeLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource options:nil error:&error]);
     94        END_BLOCK_OBJC_EXCEPTIONS;
     95
     96        ASSERT(computeLibrary);
     97        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here.
     98
     99        computeEntryPoint = whlslCompileResult->mangledEntryPointName;
     100    } else {
     101        computeLibrary = computeStage.module->platformShaderModule();
     102        computeEntryPoint = computeStage.entryPoint;
     103    }
     104
     105    if (trySetMetalFunctions(functionName, computeLibrary.get(), mtlDescriptor, computeEntryPoint))
     106        return computeDimensions;
     107    return WTF::nullopt;
     108}
     109
     110struct ConvertResult {
     111    RetainPtr<MTLComputePipelineDescriptor> pipelineDescriptor;
     112    WHLSL::ComputeDimensions computeDimensions;
     113};
     114static Optional<ConvertResult> convertComputePipelineDescriptor(const char* const functionName, const GPUComputePipelineDescriptor& descriptor, const GPUDevice& device)
     115{
     116    RetainPtr<MTLComputePipelineDescriptor> mtlDescriptor;
     117
     118    BEGIN_BLOCK_OBJC_EXCEPTIONS;
     119
     120    mtlDescriptor = adoptNS([MTLComputePipelineDescriptor new]);
     121
     122    END_BLOCK_OBJC_EXCEPTIONS;
     123
     124    if (!mtlDescriptor) {
     125        LOG(WebGPU, "%s: Error creating MTLDescriptor!", functionName);
     126        return WTF::nullopt;
     127    }
     128
     129    const auto& computeStage = descriptor.computeStage;
     130
     131    bool isWhlsl = !computeStage.module->whlslSource().isNull();
     132
     133    Optional<WHLSL::ComputePipelineDescriptor> whlslDescriptor;
     134    if (isWhlsl)
     135        whlslDescriptor = WHLSL::ComputePipelineDescriptor();
     136
     137    if (descriptor.layout && whlslDescriptor) {
     138        if (auto layout = convertLayout(*descriptor.layout))
     139            whlslDescriptor->layout = WTFMove(*layout);
     140        else {
     141            LOG(WebGPU, "%s: Error converting GPUPipelineLayout!", functionName);
     142            return WTF::nullopt;
     143        }
     144    }
     145
     146    if (auto computeDimensions = trySetFunctions(functionName, computeStage, device, mtlDescriptor.get(), whlslDescriptor))
     147        return {{ mtlDescriptor, *computeDimensions }};
     148
     149    return WTF::nullopt;
     150}
     151
     152struct CreateResult {
     153    RetainPtr<MTLComputePipelineState> pipelineState;
     154    WHLSL::ComputeDimensions computeDimensions;
     155};
     156static Optional<CreateResult> tryCreateMTLComputePipelineState(const char* const functionName, const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor)
    61157{
    62158    if (!device.platformDevice()) {
    63159        LOG(WebGPU, "GPUComputePipeline::tryCreate(): Invalid GPUDevice!");
     160        return WTF::nullopt;
     161    }
     162
     163    auto convertResult = convertComputePipelineDescriptor(functionName, descriptor, device);
     164    if (!convertResult)
     165        return WTF::nullopt;
     166    ASSERT(convertResult->pipelineDescriptor);
     167    auto mtlDescriptor = convertResult->pipelineDescriptor;
     168
     169    RetainPtr<MTLComputePipelineState> pipeline;
     170
     171    BEGIN_BLOCK_OBJC_EXCEPTIONS;
     172
     173    NSError *error = nil;
     174    pipeline = adoptNS([device.platformDevice() newComputePipelineStateWithDescriptor:mtlDescriptor.get() options:MTLPipelineOptionNone reflection:nil error:&error]);
     175    if (!pipeline) {
     176        LOG(WebGPU, "GPUComputePipeline::tryCreate(): %s!", error ? error.localizedDescription.UTF8String : "Unable to create MTLComputePipelineState!");
     177        return WTF::nullopt;
     178    }
     179
     180    END_BLOCK_OBJC_EXCEPTIONS;
     181
     182    return {{ pipeline, convertResult->computeDimensions }};
     183}
     184
     185RefPtr<GPUComputePipeline> GPUComputePipeline::tryCreate(const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor)
     186{
     187    const char* const functionName = "GPURenderPipeline::create()";
     188
     189    auto createResult = tryCreateMTLComputePipelineState(functionName, device, descriptor);
     190    if (!createResult)
    64191        return nullptr;
    65     }
    66 
    67     auto computeFunction = tryCreateMtlComputeFunction(descriptor.computeStage);
    68     if (!computeFunction)
    69         return nullptr;
    70 
    71     RetainPtr<MTLComputePipelineState> pipelineState;
    72     NSError *error = nil;
    73 
    74     BEGIN_BLOCK_OBJC_EXCEPTIONS;
    75     pipelineState = adoptNS([device.platformDevice() newComputePipelineStateWithFunction:computeFunction.get() error:&error]);
    76     END_BLOCK_OBJC_EXCEPTIONS;
    77 
    78     if (!pipelineState)
    79         LOG(WebGPU, "GPUComputePipeline::tryCreate(): %s!", error ? error.localizedDescription.UTF8String : "Unable to create MTLComputePipelineState!");
    80 
    81     return pipelineState;
    82 }
    83 
    84 RefPtr<GPUComputePipeline> GPUComputePipeline::tryCreate(const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor)
    85 {
    86     auto mtlPipeline = tryCreateMTLComputePipelineState(device, descriptor);
    87     if (!mtlPipeline)
    88         return nullptr;
    89 
    90     return adoptRef(new GPUComputePipeline(WTFMove(mtlPipeline)));
    91 }
    92 
    93 GPUComputePipeline::GPUComputePipeline(RetainPtr<MTLComputePipelineState>&& pipeline)
     192
     193    return adoptRef(new GPUComputePipeline(WTFMove(createResult->pipelineState), createResult->computeDimensions));
     194}
     195
     196GPUComputePipeline::GPUComputePipeline(RetainPtr<MTLComputePipelineState>&& pipeline, WHLSL::ComputeDimensions computeDimensions)
    94197    : m_platformComputePipeline(WTFMove(pipeline))
     198    , m_computeDimensions(computeDimensions)
    95199{
    96200}
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.h

    r246394 r246396  
    2929
    3030#include "WHLSLPipelineDescriptor.h"
    31 #include <wtf/text/WTFString.h>
     31#include <wtf/Optional.h>
    3232
    3333namespace WebCore {
    3434
    35 namespace WHLSL {
     35class GPUPipelineLayout;
    3636
    37 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Generate descriptive error messages and return them here.
    38 struct RenderPrepareResult {
    39     String metalSource;
    40     String mangledVertexEntryPointName;
    41     String mangledFragmentEntryPointName;
    42 };
    43 Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor&);
     37Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout&);
    4438
    45 struct ComputePrepareResult {
    46     String metalSource;
    47     String mangledEntryPointName;
    48 };
    49 Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor&);
     39}
    5040
    51 } // namespace WHLSL
    52 
    53 } // namespace WebCore
    54 
    55 #endif // ENABLE(WEBGPU)
     41#endif
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm

    r246394 r246396  
    3131#import "GPUDevice.h"
    3232#import "GPULimits.h"
     33#import "GPUPipelineMetalConvertLayout.h"
    3334#import "GPUUtils.h"
    3435#import "Logging.h"
     
    9798        return WHLSL::VertexFormat::FloatR32;
    9899    }
    99 }
    100 
    101 static OptionSet<WHLSL::ShaderStage> convertShaderStageFlags(GPUShaderStageFlags flags)
    102 {
    103     OptionSet<WHLSL::ShaderStage> result;
    104     if (flags & GPUShaderStageBit::Flags::Vertex)
    105         result.add(WHLSL::ShaderStage::Vertex);
    106     if (flags & GPUShaderStageBit::Flags::Fragment)
    107         result.add(WHLSL::ShaderStage::Fragment);
    108     if (flags & GPUShaderStageBit::Flags::Compute)
    109         result.add(WHLSL::ShaderStage::Compute);
    110     return result;
    111 }
    112 
    113 static Optional<WHLSL::Binding::BindingDetails> convertBindingType(GPUBindGroupLayout::InternalBindingDetails internalBindingDetails)
    114 {
    115     return WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer uniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
    116         return { WHLSL::UniformBufferBinding { uniformBuffer.internalLengthName } };
    117     }, [&](GPUBindGroupLayout::DynamicUniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
    118         return WTF::nullopt;
    119     }, [&](GPUBindGroupLayout::Sampler) -> Optional<WHLSL::Binding::BindingDetails> {
    120         return { WHLSL::SamplerBinding { } };
    121     }, [&](GPUBindGroupLayout::SampledTexture) -> Optional<WHLSL::Binding::BindingDetails> {
    122         return { WHLSL::TextureBinding { } };
    123     }, [&](GPUBindGroupLayout::StorageBuffer storageBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
    124         return { WHLSL::StorageBufferBinding { storageBuffer.internalLengthName } };
    125     }, [&](GPUBindGroupLayout::DynamicStorageBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
    126         return WTF::nullopt;
    127     }), internalBindingDetails);
    128100}
    129101
     
    369341}
    370342
    371 static Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout& layout)
    372 {
    373     WHLSL::Layout result;
    374     if (layout.bindGroupLayouts().size() > std::numeric_limits<unsigned>::max())
    375         return WTF::nullopt;
    376     for (size_t i = 0; i < layout.bindGroupLayouts().size(); ++i) {
    377         const auto& bindGroupLayout = layout.bindGroupLayouts()[i];
    378         WHLSL::BindGroup bindGroup;
    379         bindGroup.name = static_cast<unsigned>(i);
    380         for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) {
    381             const auto& bindingDetails = keyValuePair.value;
    382             WHLSL::Binding binding;
    383             binding.visibility = convertShaderStageFlags(bindingDetails.externalBinding.visibility);
    384             if (auto bindingType = convertBindingType(bindingDetails.internalBindingDetails))
    385                 binding.binding = *bindingType;
    386             else
    387                 return WTF::nullopt;
    388             if (bindingDetails.externalBinding.binding > std::numeric_limits<unsigned>::max())
    389                 return WTF::nullopt;
    390             binding.externalName = bindingDetails.externalBinding.binding;
    391             binding.internalName = bindingDetails.internalName;
    392             bindGroup.bindings.append(WTFMove(binding));
    393         }
    394         result.append(WTFMove(bindGroup));
    395     }
    396     return result;
    397 }
    398 
    399343static bool trySetMetalFunctions(const char* const functionName, MTLLibrary *vertexMetalLibrary, MTLLibrary *fragmentMetalLibrary, MTLRenderPipelineDescriptor *mtlDescriptor, const String& vertexEntryPointName, const String& fragmentEntryPointName)
    400344{
     
    466410        if (!whlslCompileResult)
    467411            return false;
    468 
    469         WTFLogAlways("Metal Source: %s", whlslCompileResult->metalSource.utf8().data());
    470412
    471413        NSError *error = nil;
     
    543485static RetainPtr<MTLRenderPipelineState> tryCreateMtlRenderPipelineState(const char* const functionName, const GPURenderPipelineDescriptor& descriptor, const GPUDevice& device)
    544486{
     487    if (!device.platformDevice()) {
     488        LOG(WebGPU, "GPUComputePipeline::tryCreate(): Invalid GPUDevice!");
     489        return nullptr;
     490    }
     491
    545492    auto mtlDescriptor = convertRenderPipelineDescriptor(functionName, descriptor, device);
    546493    if (!mtlDescriptor)
     
    551498    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    552499
    553     NSError *error = [NSError errorWithDomain:@"com.apple.WebKit.GPU" code:1 userInfo:nil];
     500    NSError *error = nil;
    554501    pipeline = adoptNS([device.platformDevice() newRenderPipelineStateWithDescriptor:mtlDescriptor.get() error:&error]);
    555502    if (!pipeline)
Note: See TracChangeset for help on using the changeset viewer.