Changeset 247468 in webkit


Ignore:
Timestamp:
Jul 15, 2019 8:50:25 PM (5 years ago)
Author:
sbarati@apple.com
Message:

[WHLSL] Matrix memory layout should match HLSL by laying out columns linearly
https://bugs.webkit.org/show_bug.cgi?id=199215

Reviewed by Myles C. Maxfield.

Source/WebCore:

This patch makes it so that we lay out matrices in memory in the same
way HLSL does. This is by laying out columns linearly in memory. So a float4x4
composed by this series of floats in memory:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

composes this logical matrix:
[[ 0, 4, 8, 12]

[ 1, 5, 9, 13]
[ 2, 6, 10, 14]
[ 3, 7, 11, 15]]

To implement this, we switch to using an array to represent the memory
contents linear memory layout of a matrix. So the matrix float4x3 will now
be an array<float, 12> in metal. Then, we change the indexed getter and
setter methods for matrices to load and store from and to the correct
memory locations. The memory layout of matrices is observable to WHLSL
when using a matrix as an input/output to a shader.

Test: webgpu/whlsl-matrix-memory-layout.html

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

(WebCore::WHLSL::Metal::writeNativeFunction):

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

(WebCore::WHLSL::Metal::writeNativeType):

LayoutTests:

  • webgpu/whlsl-matrix-memory-layout-expected.txt: Added.
  • webgpu/whlsl-matrix-memory-layout.html: Added.
  • webgpu/whlsl-test-harness-test.html:
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r247467 r247468  
     12019-07-15  Saam Barati  <sbarati@apple.com>
     2
     3        [WHLSL] Matrix memory layout should match HLSL by laying out columns linearly
     4        https://bugs.webkit.org/show_bug.cgi?id=199215
     5
     6        Reviewed by Myles C. Maxfield.
     7
     8        * webgpu/whlsl-matrix-memory-layout-expected.txt: Added.
     9        * webgpu/whlsl-matrix-memory-layout.html: Added.
     10        * webgpu/whlsl-test-harness-test.html:
     11
    1122019-07-15  Wenson Hsieh  <wenson_hsieh@apple.com>
    213
  • trunk/LayoutTests/webgpu/whlsl-test-harness-test.html

    r247289 r247468  
    4343};
    4444
    45 const float4x4expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
    46 const float4expected = float4x4expected.slice(0, 4);
     45const float4x4expected = [0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15];
     46const float4x4ColumnExpected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
     47const float4expected = [0, 1, 2, 3];
    4748
    4849let whlslTests = {};
     
    173174        multiple4x4args.push(arg);
    174175    }
    175     checkArrays("float4x4", "return in0 + in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10 + in11 + in12 + in13 + in14 + in15;", multiple4x4args, float4x4expected);
     176    checkArrays("float4x4", "return in0 + in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10 + in11 + in12 + in13 + in14 + in15;", multiple4x4args, float4x4ColumnExpected);
    176177    checkArrays("float4x4", "return in0[0];", [[float4x4expected]], float4x4expected);
    177178};
  • trunk/Source/WebCore/ChangeLog

    r247467 r247468  
     12019-07-15  Saam Barati  <sbarati@apple.com>
     2
     3        [WHLSL] Matrix memory layout should match HLSL by laying out columns linearly
     4        https://bugs.webkit.org/show_bug.cgi?id=199215
     5
     6        Reviewed by Myles C. Maxfield.
     7
     8        This patch makes it so that we lay out matrices in memory in the same
     9        way HLSL does. This is by laying out columns linearly in memory. So a float4x4
     10        composed by this series of floats in memory:
     11        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
     12       
     13        composes this logical matrix:
     14        [[ 0,  4,  8, 12]
     15         [ 1,  5,  9, 13]
     16         [ 2,  6, 10, 14]
     17         [ 3,  7, 11, 15]]
     18       
     19        To implement this, we switch to using an array to represent the memory
     20        contents linear memory layout of a matrix. So the matrix float4x3 will now
     21        be an array<float, 12> in metal. Then, we change the indexed getter and
     22        setter methods for matrices to load and store from and to the correct
     23        memory locations. The memory layout of matrices is observable to WHLSL
     24        when using a matrix as an input/output to a shader.
     25
     26        Test: webgpu/whlsl-matrix-memory-layout.html
     27
     28        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
     29        (WebCore::WHLSL::Metal::writeNativeFunction):
     30        * Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp:
     31        (WebCore::WHLSL::Metal::writeNativeType):
     32
    1332019-07-15  Wenson Hsieh  <wenson_hsieh@apple.com>
    234
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp

    r247174 r247468  
    251251    }
    252252
    253     auto numberOfMatrixRows = [&] {
     253    auto matrixDimension = [&] (unsigned typeArgumentIndex) -> unsigned {
    254254        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
    255255        auto& matrixType = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType());
    256256        ASSERT(matrixType.name() == "matrix");
    257257        ASSERT(matrixType.typeArguments().size() == 3);
    258         return String::number(WTF::get<AST::ConstantExpression>(matrixType.typeArguments()[1]).integerLiteral().value());
     258        return WTF::get<AST::ConstantExpression>(matrixType.typeArguments()[typeArgumentIndex]).integerLiteral().value();
     259    };
     260    auto numberOfMatrixRows = [&] {
     261        return matrixDimension(1);
     262    };
     263    auto numberOfMatrixColumns = [&] {
     264        return matrixDimension(2);
    259265    };
    260266
     
    264270        auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
    265271        auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
     272
     273        unsigned numberOfRows = numberOfMatrixRows();
     274        unsigned numberOfColumns = numberOfMatrixColumns();
     275
    266276        stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i) {\n"));
    267         stringBuilder.append(makeString("    if (i < ", numberOfMatrixRows(), ") return m[i];\n"));
    268         stringBuilder.append(makeString("    return ", metalReturnName, "(0);\n"));
     277        stringBuilder.append(makeString("    if (i >= ", numberOfRows, ") return ", metalReturnName, "(0);\n"));
     278        stringBuilder.append(makeString("    ", metalReturnName, " result;\n"));
     279        stringBuilder.append("    result[0] = m[i];\n");
     280        stringBuilder.append(makeString("    result[1] = m[i + ", numberOfRows, "];\n"));
     281        if (numberOfColumns >= 3)
     282            stringBuilder.append(makeString("    result[2] = m[i + ", numberOfRows * 2, "];\n"));
     283        if (numberOfColumns >= 4)
     284            stringBuilder.append(makeString("    result[3] = m[i + ", numberOfRows * 3, "];\n"));
     285        stringBuilder.append("    return result;\n");
    269286        stringBuilder.append("}\n");
    270287        return stringBuilder.toString();
     
    277294        auto metalParameter3Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2]->type());
    278295        auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
     296
     297        unsigned numberOfRows = numberOfMatrixRows();
     298        unsigned numberOfColumns = numberOfMatrixColumns();
     299
    279300        stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i, ", metalParameter3Name, " v) {\n"));
    280         stringBuilder.append(makeString("    if (i < ", numberOfMatrixRows(), ") m[i] = v;\n"));
    281         stringBuilder.append("    return m;\n");
     301        stringBuilder.append(makeString("    if (i >= ", numberOfRows, ") return m;\n"));
     302        stringBuilder.append(makeString("    m[i] = v[0];\n"));
     303        stringBuilder.append(makeString("    m[i + ", numberOfRows, "] = v[1];\n"));
     304        if (numberOfColumns >= 3)
     305            stringBuilder.append(makeString("    m[i + ", numberOfRows * 2, "] = v[2];\n"));
     306        if (numberOfColumns >= 4)
     307            stringBuilder.append(makeString("    m[i + ", numberOfRows * 3, "] = v[3];\n"));
     308        stringBuilder.append("    return m;");
    282309        stringBuilder.append("}\n");
    283310        return stringBuilder.toString();
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp

    r246631 r247468  
    123123            return "float";
    124124        })();
     125
    125126        ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]));
    126127        auto& constantExpression1 = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]);
    127128        auto& integerLiteral1 = constantExpression1.integerLiteral();
    128         auto middle = ([&]() -> String {
    129             switch (integerLiteral1.value()) {
    130             case 2:
    131                 return "2"_str;
    132             case 3:
    133                 return "3"_str;
    134             default:
    135                 ASSERT(integerLiteral1.value() == 4);
    136                 return "4"_str;
    137             }
    138         })();
     129        unsigned rows = integerLiteral1.value();
     130        ASSERT(rows == 2 || rows == 3 || rows == 4);
     131
    139132        ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2]));
    140133        auto& constantExpression2 = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2]);
    141134        auto& integerLiteral2 = constantExpression2.integerLiteral();
    142         auto suffix = ([&]() -> String {
    143             switch (integerLiteral2.value()) {
    144             case 2:
    145                 return "2"_str;
    146             case 3:
    147                 return "3"_str;
    148             default:
    149                 ASSERT(integerLiteral2.value() == 4);
    150                 return "4"_str;
    151             }
    152         })();
    153         return makeString(prefix, middle, 'x', suffix);
     135        unsigned columns = integerLiteral2.value();
     136        ASSERT(columns == 2 || columns == 3 || columns == 4);
     137        return makeString("array<", prefix, ", ", columns * rows, ">");
    154138    }
    155139    ASSERT(nativeTypeDeclaration.typeArguments().size() == 1);
Note: See TracChangeset for help on using the changeset viewer.