WebKit Bugzilla
Attachment 372404 Details for
Bug 198876
: [WHLSL] Support matrices
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
c-backup.diff (text/plain), 17.82 KB, created by
Saam Barati
on 2019-06-18 16:32:04 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2019-06-18 16:32:04 PDT
Size:
17.82 KB
patch
obsolete
>Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (revision 246549) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (working copy) >@@ -507,7 +507,7 @@ private: > > void finishVisiting(AST::PropertyAccessExpression&, ResolvingType* additionalArgumentType = nullptr); > >- HashMap<AST::Expression*, ResolvingType> m_typeMap; >+ HashMap<AST::Expression*, std::unique_ptr<ResolvingType>> m_typeMap; > HashMap<AST::Expression*, AST::TypeAnnotation> m_typeAnnotations; > HashSet<String> m_vertexEntryPoints; > HashSet<String> m_fragmentEntryPoints; >@@ -537,7 +537,7 @@ void Checker::visit(Program& program) > bool Checker::assignTypes() > { > for (auto& keyValuePair : m_typeMap) { >- auto success = keyValuePair.value.visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >+ auto success = keyValuePair.value->visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { > keyValuePair.key->setType(unnamedType->clone()); > return true; > }, [&](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> bool { >@@ -780,7 +780,7 @@ auto Checker::getInfo(AST::Expression& e > setError(); > return WTF::nullopt; > } >- return {{ typeIterator->value, typeAnnotationIterator->value }}; >+ return {{ *typeIterator->value, typeAnnotationIterator->value }}; > } > > void Checker::visit(AST::VariableDeclaration& variableDeclaration) >@@ -802,7 +802,7 @@ void Checker::visit(AST::VariableDeclara > > void Checker::assignType(AST::Expression& expression, UniqueRef<AST::UnnamedType>&& unnamedType, AST::TypeAnnotation typeAnnotation = AST::RightValue()) > { >- auto addResult = m_typeMap.add(&expression, WTFMove(unnamedType)); >+ auto addResult = m_typeMap.add(&expression, std::make_unique<ResolvingType>(WTFMove(unnamedType))); > ASSERT_UNUSED(addResult, addResult.isNewEntry); > auto typeAnnotationAddResult = m_typeAnnotations.add(&expression, WTFMove(typeAnnotation)); > ASSERT_UNUSED(typeAnnotationAddResult, typeAnnotationAddResult.isNewEntry); >@@ -810,7 +810,7 @@ void Checker::assignType(AST::Expression > > void Checker::assignType(AST::Expression& expression, RefPtr<ResolvableTypeReference>&& resolvableTypeReference, AST::TypeAnnotation typeAnnotation = AST::RightValue()) > { >- auto addResult = m_typeMap.add(&expression, WTFMove(resolvableTypeReference)); >+ auto addResult = m_typeMap.add(&expression, std::make_unique<ResolvingType>(WTFMove(resolvableTypeReference))); > ASSERT_UNUSED(addResult, addResult.isNewEntry); > auto typeAnnotationAddResult = m_typeAnnotations.add(&expression, WTFMove(typeAnnotation)); > ASSERT_UNUSED(typeAnnotationAddResult, typeAnnotationAddResult.isNewEntry); >@@ -819,10 +819,10 @@ void Checker::assignType(AST::Expression > void Checker::forwardType(AST::Expression& expression, ResolvingType& resolvingType, AST::TypeAnnotation typeAnnotation = AST::RightValue()) > { > resolvingType.visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& result) { >- auto addResult = m_typeMap.add(&expression, result->clone()); >+ auto addResult = m_typeMap.add(&expression, std::make_unique<ResolvingType>(result->clone())); > ASSERT_UNUSED(addResult, addResult.isNewEntry); > }, [&](RefPtr<ResolvableTypeReference>& result) { >- auto addResult = m_typeMap.add(&expression, result.copyRef()); >+ auto addResult = m_typeMap.add(&expression, std::make_unique<ResolvingType>(result.copyRef())); > ASSERT_UNUSED(addResult, addResult.isNewEntry); > })); > auto typeAnnotationAddResult = m_typeAnnotations.add(&expression, WTFMove(typeAnnotation)); >Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp (revision 246550) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp (working copy) >@@ -59,7 +59,7 @@ namespace WHLSL { > > static constexpr bool dumpASTBeforeEachPass = false; > static constexpr bool dumpASTAfterParsing = false; >-static constexpr bool dumpASTAtEnd = false; >+static constexpr bool dumpASTAtEnd = true; > static constexpr bool alwaysDumpPassFailures = false; > static constexpr bool dumpPassFailure = dumpASTBeforeEachPass || dumpASTAfterParsing || dumpASTAtEnd || alwaysDumpPassFailures; > >Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt (revision 246549) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt (working copy) >@@ -626,3 +626,75 @@ operator float4(float x, float y, float > } > > // FIXME: https://bugs.webkit.org/show_bug.cgi?id=192890 Insert the rest of the standard library once the parser is fast enough >+ >+native float3 operator[](float2x3, uint); >+native float2x3 operator[]=(float2x3, uint, float3); >+float operator[](float3 v, uint index) { >+ switch (index) { >+ case 0: >+ return v.x; >+ case 1: >+ return v.y; >+ case 2: >+ return v.z; >+ default: >+ break; >+ } >+ return 0.0; >+} >+float3 operator[]=(float3 v, uint index, float a) { >+ switch (index) { >+ case 0: >+ v.x = a; >+ break; >+ case 1: >+ v.y = a; >+ break; >+ case 2: >+ v.z = a; >+ break; >+ default: >+ break; >+ } >+ return v; >+} >+float2x3 operator+(float2x3 a, float2x3 b) { >+ float2x3 result; >+ result[0][0] = a[0][0] + b[0][0]; >+ result[0][1] = a[0][1] + b[0][1]; >+ result[0][2] = a[0][2] + b[0][2]; >+ result[1][0] = a[1][0] + b[1][0]; >+ result[1][1] = a[1][1] + b[1][1]; >+ result[1][2] = a[1][2] + b[1][2]; >+ return result; >+} >+float2x3 operator*(float2x3 a, float b) { >+ float2x3 result; >+ result[0][0] = a[0][0] * b; >+ result[0][1] = a[0][1] * b; >+ result[0][2] = a[0][2] * b; >+ result[1][0] = a[1][0] * b; >+ result[1][1] = a[1][1] * b; >+ result[1][2] = a[1][2] * b; >+ return result; >+} >+float2x3 operator+(float2x3 a, float b) { >+ float2x3 result; >+ result[0][0] = a[0][0] + b; >+ result[0][1] = a[0][1] + b; >+ result[0][2] = a[0][2] + b; >+ result[1][0] = a[1][0] + b; >+ result[1][1] = a[1][1] + b; >+ result[1][2] = a[1][2] + b; >+ return result; >+} >+float2x3 operator-(float2x3 a, float b) { >+ float2x3 result; >+ result[0][0] = a[0][0] - b; >+ result[0][1] = a[0][1] - b; >+ result[0][2] = a[0][2] - b; >+ result[1][0] = a[1][0] - b; >+ result[1][1] = a[1][1] - b; >+ result[1][2] = a[1][2] - b; >+ return result; >+} >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp (revision 246549) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp (working copy) >@@ -191,6 +191,13 @@ protected: > return m_stack.takeLast().leftValue; > } > >+ enum class BreakContext { >+ Loop, >+ Switch >+ }; >+ >+ Optional<BreakContext> m_currentBreakContext; >+ > Intrinsics& m_intrinsics; > TypeNamer& m_typeNamer; > HashMap<AST::FunctionDeclaration*, String>& m_functionMapping; >@@ -271,9 +278,17 @@ void FunctionDefinitionWriter::visit(AST > > void FunctionDefinitionWriter::visit(AST::Break&) > { >- ASSERT(m_breakOutOfCurrentLoopEarlyVariable.length()); >- m_stringBuilder.append(makeString(m_breakOutOfCurrentLoopEarlyVariable, " = true;\n")); >- m_stringBuilder.append("break;\n"); >+ ASSERT(m_currentBreakContext); >+ switch (*m_currentBreakContext) { >+ case BreakContext::Switch: >+ m_stringBuilder.append("break;\n"); >+ break; >+ case BreakContext::Loop: >+ ASSERT(m_breakOutOfCurrentLoopEarlyVariable.length()); >+ m_stringBuilder.append(makeString(m_breakOutOfCurrentLoopEarlyVariable, " = true;\n")); >+ m_stringBuilder.append("break;\n"); >+ break; >+ } > } > > void FunctionDefinitionWriter::visit(AST::Continue&) >@@ -307,6 +322,7 @@ void FunctionDefinitionWriter::emitLoop( > } > > m_stringBuilder.append("do {\n"); >+ SetForScope<Optional<BreakContext>> breakContext(m_currentBreakContext, BreakContext::Loop); > checkErrorAndVisit(body); > m_stringBuilder.append("} while(false); \n"); > m_stringBuilder.append(makeString("if (", m_breakOutOfCurrentLoopEarlyVariable, ") break;\n")); >@@ -393,9 +409,10 @@ void FunctionDefinitionWriter::visit(AST > m_stringBuilder.append(makeString("case ", constantExpressionString(*switchCase.value()), ":\n")); > else > m_stringBuilder.append("default:\n"); >+ SetForScope<Optional<BreakContext>> breakContext(m_currentBreakContext, BreakContext::Switch); > checkErrorAndVisit(switchCase.block()); > // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195812 Figure out whether we need to break or fallthrough. >- notImplemented(); >+ // notImplemented(); > } > > void FunctionDefinitionWriter::visit(AST::Trap&) >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp (revision 246549) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp (working copy) >@@ -32,6 +32,8 @@ > #include "WHLSLTypeNamer.h" > #include <wtf/text/StringBuilder.h> > >+#include <wtf/DataLog.h> >+ > namespace WebCore { > > namespace WHLSL { >@@ -71,6 +73,7 @@ ComputeMetalCode generateMetalCode(Progr > auto metalTypes = typeNamer.metalTypes(); > auto metalFunctions = Metal::metalFunctions(program, typeNamer, WTFMove(matchedSemantics), layout); > auto metalCode = generateMetalCodeShared(WTFMove(metalTypes), WTFMove(metalFunctions.metalSource)); >+ dataLogLn(metalCode); > return { WTFMove(metalCode), WTFMove(metalFunctions.mangledEntryPointName) }; > } > >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp (revision 246549) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp (working copy) >@@ -42,6 +42,8 @@ > #include "WHLSLVariableDeclaration.h" > #include <wtf/text/StringBuilder.h> > >+#include <wtf/DataLog.h> >+ > namespace WebCore { > > namespace WHLSL { >@@ -225,6 +227,41 @@ String writeNativeFunction(AST::NativeFu > return stringBuilder.toString(); > } > >+ auto matrixRowSize = [&] { >+ auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto& matrixType = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType()); >+ ASSERT(matrixType.name() == "matrix"); >+ ASSERT(matrixType.typeArguments().size() == 3); >+ return String::number(WTF::get<AST::ConstantExpression>(matrixType.typeArguments()[1]).integerLiteral().value()); >+ }; >+ >+ if (nativeFunctionDeclaration.name() == "operator[]") { >+ ASSERT(nativeFunctionDeclaration.parameters().size() == 2); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); >+ auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); >+ stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i) {\n")); >+ stringBuilder.append(makeString(" if (i < ", matrixRowSize(), ") return m[i];\n")); >+ stringBuilder.append(makeString(" ", metalReturnName, " vectorResult;\n")); >+ stringBuilder.append(makeString(" ", memsetZeroFunctionName, "(vectorResult);\n")); >+ stringBuilder.append(" return vectorResult;\n"); >+ stringBuilder.append("}\n"); >+ return stringBuilder.toString(); >+ } >+ >+ if (nativeFunctionDeclaration.name() == "operator[]=") { >+ ASSERT(nativeFunctionDeclaration.parameters().size() == 3); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); >+ auto metalParameter3Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2]->type()); >+ auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); >+ stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i, ", metalParameter3Name, " v) {\n")); >+ stringBuilder.append(makeString(" if (i < ", matrixRowSize(), ") m[i] = v;\n")); >+ stringBuilder.append(" return m;\n"); >+ stringBuilder.append("}\n"); >+ return stringBuilder.toString(); >+ } >+ > if (nativeFunctionDeclaration.isOperator()) { > if (nativeFunctionDeclaration.parameters().size() == 1) { > auto operatorName = nativeFunctionDeclaration.name().substring("operator"_str.length()); >Index: LayoutTests/webgpu/whlsl-matrix.html >=================================================================== >--- LayoutTests/webgpu/whlsl-matrix.html (nonexistent) >+++ LayoutTests/webgpu/whlsl-matrix.html (working copy) >@@ -0,0 +1,125 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../resources/js-test-pre.js"></script> >+</head> >+<body> >+<script> >+const shaderSource = ` >+bool allEqual(float2x3 mat, float value) >+{ >+ for (uint i = 0; i < 2; i = i + 1) { >+ for (uint j = 0; j < 3; j = j + 1) { >+ if (mat[i][j] != value) >+ return false; >+ } >+ } >+ return true; >+} >+ >+[numthreads(1, 1, 1)] >+compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) { >+ float2x3 foo; >+ if (!allEqual(foo, 0)) >+ return; >+ >+ foo = foo + 1.0; >+ if (!allEqual(foo, 1)) >+ return; >+ >+ foo = foo * 8.5; >+ if (!allEqual(foo, 8.5)) >+ return; >+ >+ foo = foo - 7.5; >+ if (!allEqual(foo, 1)) >+ return; >+ >+ foo = foo + 1.0; >+ if (!allEqual(foo, 2)) >+ return; >+ >+ foo = foo + foo; >+ if (!allEqual(foo, 4)) >+ return; >+ >+ buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0; >+} >+`; >+let resultsFloat32Array; >+async function start() { >+ const adapter = await navigator.gpu.requestAdapter(); >+ const device = await adapter.requestDevice(); >+ >+ const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true}); >+ const computeStage = {module: shaderModule, entryPoint: "computeShader"}; >+ >+ const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]}; >+ const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); >+ const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]}; >+ const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); >+ >+ const computePipelineDescriptor = {computeStage, layout: pipelineLayout}; >+ const computePipeline = device.createComputePipeline(computePipelineDescriptor); >+ >+ const size = Float32Array.BYTES_PER_ELEMENT * 8; >+ >+ const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC}; >+ const buffer = device.createBuffer(bufferDescriptor); >+ const bufferArrayBuffer = await buffer.mapWriteAsync(); >+ const bufferFloat32Array = new Float32Array(bufferArrayBuffer); >+ bufferFloat32Array[0] = 1; >+ bufferFloat32Array[1] = 2; >+ bufferFloat32Array[2] = 3; >+ bufferFloat32Array[3] = 4; >+ bufferFloat32Array[4] = 5; >+ bufferFloat32Array[5] = 6; >+ bufferFloat32Array[6] = 7; >+ bufferFloat32Array[7] = 8; >+ buffer.unmap(); >+ >+ const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ}; >+ const resultsBuffer = device.createBuffer(resultsBufferDescriptor); >+ >+ const bufferBinding = {buffer: resultsBuffer, size}; >+ const bindGroupBinding = {binding: 0, resource: bufferBinding}; >+ const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]}; >+ const bindGroup = device.createBindGroup(bindGroupDescriptor); >+ >+ const commandEncoder = device.createCommandEncoder(); // {} >+ commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size); >+ const computePassEncoder = commandEncoder.beginComputePass(); >+ computePassEncoder.setPipeline(computePipeline); >+ computePassEncoder.setBindGroup(0, bindGroup); >+ computePassEncoder.dispatch(4, 1, 1); >+ computePassEncoder.endPass(); >+ const commandBuffer = commandEncoder.finish(); >+ device.getQueue().submit([commandBuffer]); >+ >+ const resultsArrayBuffer = await resultsBuffer.mapReadAsync(); >+ resultsFloat32Array = new Float32Array(resultsArrayBuffer); >+ shouldBe("resultsFloat32Array[0]", "2"); >+ shouldBe("resultsFloat32Array[1]", "4"); >+ shouldBe("resultsFloat32Array[2]", "6"); >+ shouldBe("resultsFloat32Array[3]", "8"); >+ shouldBe("resultsFloat32Array[4]", "5"); >+ shouldBe("resultsFloat32Array[5]", "6"); >+ shouldBe("resultsFloat32Array[6]", "7"); >+ shouldBe("resultsFloat32Array[7]", "8"); >+ resultsBuffer.unmap(); >+} >+if (window.testRunner) >+ testRunner.waitUntilDone(); >+window.addEventListener("load", function() { >+ start().then(function() { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }, function() { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }); >+}); >+</script> >+<script src="../resources/js-test-post.js"></script> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198876
:
372404
|
372409
|
372418