Diff
Modified: trunk/LayoutTests/ChangeLog (246578 => 246579)
--- trunk/LayoutTests/ChangeLog 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/LayoutTests/ChangeLog 2019-06-19 02:36:42 UTC (rev 246579)
@@ -1,3 +1,16 @@
+2019-06-18 Saam Barati <sbar...@apple.com>
+
+ [WHLSL] Support matrices
+ https://bugs.webkit.org/show_bug.cgi?id=198876
+ <rdar://problem/51768882>
+
+ Reviewed by Dean Jackson and Myles Maxfield.
+
+ * webgpu/whlsl-matrix-2-expected.txt: Added.
+ * webgpu/whlsl-matrix-2.html: Added.
+ * webgpu/whlsl-matrix-expected.txt: Added.
+ * webgpu/whlsl-matrix.html: Added.
+
2019-06-18 Russell Epstein <russel...@apple.com>
Layout Test imported/w3c/web-platform-tests/content-security-policy/reporting/report-only-in-meta.sub.html is failing.
Added: trunk/LayoutTests/webgpu/whlsl-matrix-2-expected.txt (0 => 246579)
--- trunk/LayoutTests/webgpu/whlsl-matrix-2-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-matrix-2-expected.txt 2019-06-19 02:36:42 UTC (rev 246579)
@@ -0,0 +1,12 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS resultsFloat32Array[0] is 2
+PASS resultsFloat32Array[1] is 4
+PASS resultsFloat32Array[2] is 6
+PASS resultsFloat32Array[3] is 8
+PASS resultsFloat32Array[4] is 5
+PASS resultsFloat32Array[5] is 6
+PASS resultsFloat32Array[6] is 7
+PASS resultsFloat32Array[7] is 8
+
Added: trunk/LayoutTests/webgpu/whlsl-matrix-2.html (0 => 246579)
--- trunk/LayoutTests/webgpu/whlsl-matrix-2.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-matrix-2.html 2019-06-19 02:36:42 UTC (rev 246579)
@@ -0,0 +1,152 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+const shaderSource = `
+bool allEqual(float4x4 mat, float value)
+{
+ for (uint i = 0; i < 4; i = i + 1) {
+ for (uint j = 0; j < 4; j = j + 1) {
+ if (mat[i][j] != value)
+ return false;
+ }
+ }
+ return true;
+}
+
+bool fill(thread float4x4* mat, float value)
+{
+ float4x4 result;
+ for (uint i = 0; i < 4; i = i + 1) {
+ result[i] = float4(value, value, value, value);
+ }
+ *mat = result;
+ return true;
+}
+
+bool fill(thread float4* vec, float value)
+{
+ float4 result;
+ for (uint i = 0; i < 4; i = i + 1) {
+ result[i] = value;
+ }
+ *vec = result;
+ return true;
+}
+
+bool allEqual(float4 vec, float value)
+{
+ for (uint i = 0; i < 4; i = i + 1) {
+ if (vec[i] != value)
+ return false;
+ }
+ return true;
+}
+
+[numthreads(1, 1, 1)]
+compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+ float4x4 mat;
+ fill(&mat, 1);
+ if (!allEqual(mat, 1))
+ return;
+
+ float4 vec;
+ fill(&vec, 1);
+ if (!allEqual(vec, 1))
+ return;
+
+ float4 vec2 = mul(mat, vec);
+ if (!allEqual(vec2, 4))
+ return;
+
+ float4x4 mat2 = mul(mat, mat);
+ if (!allEqual(mat2, 4))
+ return;
+
+ mat2 = mul(mat2, mat2);
+ if (!allEqual(mat2, 64))
+ 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=""
+</body>
+</html>
Added: trunk/LayoutTests/webgpu/whlsl-matrix-expected.txt (0 => 246579)
--- trunk/LayoutTests/webgpu/whlsl-matrix-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-matrix-expected.txt 2019-06-19 02:36:42 UTC (rev 246579)
@@ -0,0 +1,12 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS resultsFloat32Array[0] is 2
+PASS resultsFloat32Array[1] is 4
+PASS resultsFloat32Array[2] is 6
+PASS resultsFloat32Array[3] is 8
+PASS resultsFloat32Array[4] is 5
+PASS resultsFloat32Array[5] is 6
+PASS resultsFloat32Array[6] is 7
+PASS resultsFloat32Array[7] is 8
+
Added: trunk/LayoutTests/webgpu/whlsl-matrix.html (0 => 246579)
--- trunk/LayoutTests/webgpu/whlsl-matrix.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-matrix.html 2019-06-19 02:36:42 UTC (rev 246579)
@@ -0,0 +1,164 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</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;
+
+ foo = foo + foo;
+ if (!allEqual(foo, 8))
+ return;
+
+ float3 fourtyTwo;
+ fourtyTwo.x = 42;
+ fourtyTwo.y = 42;
+ fourtyTwo.z = 42;
+
+ foo[0] = fourtyTwo;
+ foo[1] = fourtyTwo;
+ if (!allEqual(foo, 42))
+ return;
+
+ foo[1337] = fourtyTwo;
+ if (!allEqual(foo, 42))
+ return;
+
+ foo[1000000] = fourtyTwo;
+ if (!allEqual(foo, 42))
+ return;
+
+ fourtyTwo[1337] = 50;
+ foo[1] = fourtyTwo;
+ if (!allEqual(foo, 42))
+ return;
+
+ fourtyTwo[1000000] = 50;
+ foo[1] = fourtyTwo;
+ if (!allEqual(foo, 42))
+ return;
+
+ float3 shouldBeZero = foo[100000];
+ if (shouldBeZero.x != 0 || shouldBeZero.y != 0 || shouldBeZero.z != 0)
+ return;
+
+ if (fourtyTwo[10000000] != 0)
+ 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=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (246578 => 246579)
--- trunk/Source/WebCore/ChangeLog 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/Source/WebCore/ChangeLog 2019-06-19 02:36:42 UTC (rev 246579)
@@ -1,3 +1,48 @@
+2019-06-18 Saam Barati <sbar...@apple.com>
+
+ [WHLSL] Support matrices
+ https://bugs.webkit.org/show_bug.cgi?id=198876
+ <rdar://problem/51768882>
+
+ Reviewed by Dean Jackson and Myles Maxfield.
+
+ This patch adds in support for matrices to WHLSL. Most matrix related code
+ is defined by the standard library. This patch just needed to add support
+ for the native functions operator[] and operator[]= on matrix types. The only
+ native functions that are named operator[] and operator[]= are for matrix
+ operations, so we strongly assume when generating code for native operator[] and
+ operator[]= that we're dealing with matrix types.
+
+ operator[]= ignores the write if the index is out of bounds. operator[]
+ returns a zeroed vector if the index is out of bounds.
+
+ This patch also incorporates two bug fixes:
+ 1. This patch takes Robin's patch in https://bugs.webkit.org/show_bug.cgi?id=198313 to ensure
+ we don't have pointers to values in a hash map. This was needed in this patch
+ otherwise we'd crash parsing the standard library.
+
+ 2. This patch fixes how we handle "break" in metal codegen. When I first
+ implemented break, I strongly assumed we were in a loop. However, break
+ can be either from a loop or from switch. This patch teaches the metal code
+ generator to track which context we're in and to emit code accordingly.
+
+ Tests: webgpu/whlsl-matrix-2.html
+ webgpu/whlsl-matrix.html
+
+ * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
+ (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
+ (WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
+ * Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp:
+ (WebCore::WHLSL::Metal::generateMetalCodeShared):
+ * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+ (WebCore::WHLSL::Metal::writeNativeFunction):
+ * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+ (WebCore::WHLSL::Checker::assignTypes):
+ (WebCore::WHLSL::Checker::getInfo):
+ (WebCore::WHLSL::Checker::assignType):
+ (WebCore::WHLSL::Checker::forwardType):
+ * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
+
2019-06-18 Yusuke Suzuki <ysuz...@apple.com>
[JSC] JSLock should be WebThread aware
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp (246578 => 246579)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp 2019-06-19 02:36:42 UTC (rev 246579)
@@ -191,6 +191,13 @@
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::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 @@
}
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,9 @@
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();
}
void FunctionDefinitionWriter::visit(AST::Trap&)
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp (246578 => 246579)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp 2019-06-19 02:36:42 UTC (rev 246579)
@@ -30,6 +30,7 @@
#include "WHLSLFunctionWriter.h"
#include "WHLSLTypeNamer.h"
+#include <wtf/DataLog.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -38,6 +39,8 @@
namespace Metal {
+static constexpr bool dumpMetalCode = false;
+
static String generateMetalCodeShared(String&& metalTypes, String&& metalFunctions)
{
StringBuilder stringBuilder;
@@ -53,6 +56,12 @@
stringBuilder.append(WTFMove(metalTypes));
stringBuilder.append(WTFMove(metalFunctions));
+
+ if (dumpMetalCode) {
+ dataLogLn("Generated Metal code: ");
+ dataLogLn(stringBuilder.toString());
+ }
+
return stringBuilder.toString();
}
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp (246578 => 246579)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp 2019-06-19 02:36:42 UTC (rev 246579)
@@ -225,6 +225,39 @@
return stringBuilder.toString();
}
+ auto numberOfMatrixRows = [&] {
+ 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 < ", numberOfMatrixRows(), ") return m[i];\n"));
+ stringBuilder.append(makeString(" return ", metalReturnName, "(0);\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 < ", numberOfMatrixRows(), ") 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());
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (246578 => 246579)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp 2019-06-19 02:36:42 UTC (rev 246579)
@@ -507,7 +507,7 @@
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 @@
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 @@
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::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_& _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::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));
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt (246578 => 246579)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt 2019-06-19 01:19:41 UTC (rev 246578)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt 2019-06-19 02:36:42 UTC (rev 246579)
@@ -625,4 +625,227 @@
return result;
}
+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;
+}
+
+typedef float4x4 = matrix<float, 4, 4>;
+native float4 operator[](float4x4, uint);
+native float4x4 operator[]=(float4x4, uint, float4);
+
+float operator[](float4 v, uint index) {
+ switch (index) {
+ case 0:
+ return v.x;
+ case 1:
+ return v.y;
+ case 2:
+ return v.z;
+ case 3:
+ return v.w;
+ default:
+ break;
+ }
+ float result;
+ return result;
+}
+
+float4 operator[]=(float4 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;
+ case 3:
+ v.w = a;
+ break;
+ default:
+ break;
+ }
+ return v;
+}
+
+float4 mul(float4x4 x, float4 y) {
+ float4 result;
+ result[0] = 0;
+ result[0] = result[0] + x[0][0] * y[0];
+ result[0] = result[0] + x[0][1] * y[1];
+ result[0] = result[0] + x[0][2] * y[2];
+ result[0] = result[0] + x[0][3] * y[3];
+ result[1] = 0;
+ result[1] = result[1] + x[1][0] * y[0];
+ result[1] = result[1] + x[1][1] * y[1];
+ result[1] = result[1] + x[1][2] * y[2];
+ result[1] = result[1] + x[1][3] * y[3];
+ result[2] = 0;
+ result[2] = result[2] + x[2][0] * y[0];
+ result[2] = result[2] + x[2][1] * y[1];
+ result[2] = result[2] + x[2][2] * y[2];
+ result[2] = result[2] + x[2][3] * y[3];
+ result[3] = 0;
+ result[3] = result[3] + x[3][0] * y[0];
+ result[3] = result[3] + x[3][1] * y[1];
+ result[3] = result[3] + x[3][2] * y[2];
+ result[3] = result[3] + x[3][3] * y[3];
+ return result;
+}
+
+float4x4 mul(float4x4 x, float4x4 y) {
+ float4x4 result;
+ result[0][0] = 0;
+ result[0][0] = result[0][0] + x[0][0] * y[0][0];
+ result[0][0] = result[0][0] + x[0][1] * y[1][0];
+ result[0][0] = result[0][0] + x[0][2] * y[2][0];
+ result[0][0] = result[0][0] + x[0][3] * y[3][0];
+ result[0][1] = 0;
+ result[0][1] = result[0][1] + x[0][0] * y[0][1];
+ result[0][1] = result[0][1] + x[0][1] * y[1][1];
+ result[0][1] = result[0][1] + x[0][2] * y[2][1];
+ result[0][1] = result[0][1] + x[0][3] * y[3][1];
+ result[0][2] = 0;
+ result[0][2] = result[0][2] + x[0][0] * y[0][2];
+ result[0][2] = result[0][2] + x[0][1] * y[1][2];
+ result[0][2] = result[0][2] + x[0][2] * y[2][2];
+ result[0][2] = result[0][2] + x[0][3] * y[3][2];
+ result[0][3] = 0;
+ result[0][3] = result[0][3] + x[0][0] * y[0][3];
+ result[0][3] = result[0][3] + x[0][1] * y[1][3];
+ result[0][3] = result[0][3] + x[0][2] * y[2][3];
+ result[0][3] = result[0][3] + x[0][3] * y[3][3];
+ result[1][0] = 0;
+ result[1][0] = result[1][0] + x[1][0] * y[0][0];
+ result[1][0] = result[1][0] + x[1][1] * y[1][0];
+ result[1][0] = result[1][0] + x[1][2] * y[2][0];
+ result[1][0] = result[1][0] + x[1][3] * y[3][0];
+ result[1][1] = 0;
+ result[1][1] = result[1][1] + x[1][0] * y[0][1];
+ result[1][1] = result[1][1] + x[1][1] * y[1][1];
+ result[1][1] = result[1][1] + x[1][2] * y[2][1];
+ result[1][1] = result[1][1] + x[1][3] * y[3][1];
+ result[1][2] = 0;
+ result[1][2] = result[1][2] + x[1][0] * y[0][2];
+ result[1][2] = result[1][2] + x[1][1] * y[1][2];
+ result[1][2] = result[1][2] + x[1][2] * y[2][2];
+ result[1][2] = result[1][2] + x[1][3] * y[3][2];
+ result[1][3] = 0;
+ result[1][3] = result[1][3] + x[1][0] * y[0][3];
+ result[1][3] = result[1][3] + x[1][1] * y[1][3];
+ result[1][3] = result[1][3] + x[1][2] * y[2][3];
+ result[1][3] = result[1][3] + x[1][3] * y[3][3];
+ result[2][0] = 0;
+ result[2][0] = result[2][0] + x[2][0] * y[0][0];
+ result[2][0] = result[2][0] + x[2][1] * y[1][0];
+ result[2][0] = result[2][0] + x[2][2] * y[2][0];
+ result[2][0] = result[2][0] + x[2][3] * y[3][0];
+ result[2][1] = 0;
+ result[2][1] = result[2][1] + x[2][0] * y[0][1];
+ result[2][1] = result[2][1] + x[2][1] * y[1][1];
+ result[2][1] = result[2][1] + x[2][2] * y[2][1];
+ result[2][1] = result[2][1] + x[2][3] * y[3][1];
+ result[2][2] = 0;
+ result[2][2] = result[2][2] + x[2][0] * y[0][2];
+ result[2][2] = result[2][2] + x[2][1] * y[1][2];
+ result[2][2] = result[2][2] + x[2][2] * y[2][2];
+ result[2][2] = result[2][2] + x[2][3] * y[3][2];
+ result[2][3] = 0;
+ result[2][3] = result[2][3] + x[2][0] * y[0][3];
+ result[2][3] = result[2][3] + x[2][1] * y[1][3];
+ result[2][3] = result[2][3] + x[2][2] * y[2][3];
+ result[2][3] = result[2][3] + x[2][3] * y[3][3];
+ result[3][0] = 0;
+ result[3][0] = result[3][0] + x[3][0] * y[0][0];
+ result[3][0] = result[3][0] + x[3][1] * y[1][0];
+ result[3][0] = result[3][0] + x[3][2] * y[2][0];
+ result[3][0] = result[3][0] + x[3][3] * y[3][0];
+ result[3][1] = 0;
+ result[3][1] = result[3][1] + x[3][0] * y[0][1];
+ result[3][1] = result[3][1] + x[3][1] * y[1][1];
+ result[3][1] = result[3][1] + x[3][2] * y[2][1];
+ result[3][1] = result[3][1] + x[3][3] * y[3][1];
+ result[3][2] = 0;
+ result[3][2] = result[3][2] + x[3][0] * y[0][2];
+ result[3][2] = result[3][2] + x[3][1] * y[1][2];
+ result[3][2] = result[3][2] + x[3][2] * y[2][2];
+ result[3][2] = result[3][2] + x[3][3] * y[3][2];
+ result[3][3] = 0;
+ result[3][3] = result[3][3] + x[3][0] * y[0][3];
+ result[3][3] = result[3][3] + x[3][1] * y[1][3];
+ result[3][3] = result[3][3] + x[3][2] * y[2][3];
+ result[3][3] = result[3][3] + x[3][3] * y[3][3];
+ return result;
+}
+
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=192890 Insert the rest of the standard library once the parser is fast enough