[WHLSL] The checker needs to resolve types for the anonymous variables in ReadModifyWrite expressions
https://bugs.webkit.org/show_bug.cgi?id=198988
Reviewed by Dean Jackson and Myles C. Maxfield.
Source/WebCore:
This patch makes it so that the Checker assigns types to the internal variables
in a read modify write expression. These were the only variables that didn't have
types ascribed to them.
This patch also does a fly by fix where we kept pointers to value types
in a HashMap in the checker. This is wrong precisely when the HashMap gets
resized. Instead, we now just store the value itself since we're just
dealing with a simple Variant that wraps either an empty struct or an
enum.
Test: webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html
* Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h:
(WebCore::WHLSL::AST::VariableDeclaration::setType):
(WebCore::WHLSL::AST::VariableDeclaration::type const):
* Modules/webgpu/WHLSL/WHLSLASTDumper.cpp: Make it obvious that read
modify write expressions are such by prefixing them with "RMW".
(WebCore::WHLSL::ASTDumper::visit):
* Modules/webgpu/WHLSL/WHLSLChecker.cpp:
(WebCore::WHLSL::Checker::visit):
LayoutTests:
* webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables-expected.txt: Added.
* webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@246625 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c431591..5b88616 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2019-06-19 Saam Barati <sbarati@apple.com>
+
+ [WHLSL] The checker needs to resolve types for the anonymous variables in ReadModifyWrite expressions
+ https://bugs.webkit.org/show_bug.cgi?id=198988
+
+ Reviewed by Dean Jackson and Myles C. Maxfield.
+
+ * webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables-expected.txt: Added.
+ * webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html: Added.
+
2019-06-19 Nikita Vasilyev <nvasilyev@apple.com>
REGRESSION(r240946): Web Inspector: Styles: Pasting multiple properties has issues
diff --git a/LayoutTests/webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables-expected.txt b/LayoutTests/webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables-expected.txt
new file mode 100644
index 0000000..4660202
--- /dev/null
+++ b/LayoutTests/webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables-expected.txt
@@ -0,0 +1,5 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS resultsFloat32Array[0] is 42
+
diff --git a/LayoutTests/webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html b/LayoutTests/webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html
new file mode 100644
index 0000000..464e268
--- /dev/null
+++ b/LayoutTests/webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+const shaderSource = `
+[numthreads(1, 1, 1)]
+compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+ float4 vec;
+ vec[0] += 42.0;
+ buffer[uint(threadID.x)] = vec[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 * 1;
+
+ 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] = 0;
+ 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(1, 1, 1);
+ computePassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+
+ const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+ resultsFloat32Array = new Float32Array(resultsArrayBuffer);
+ shouldBe("resultsFloat32Array[0]", "42");
+ 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>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index b7435ef..4861d5b 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,31 @@
+2019-06-19 Saam Barati <sbarati@apple.com>
+
+ [WHLSL] The checker needs to resolve types for the anonymous variables in ReadModifyWrite expressions
+ https://bugs.webkit.org/show_bug.cgi?id=198988
+
+ Reviewed by Dean Jackson and Myles C. Maxfield.
+
+ This patch makes it so that the Checker assigns types to the internal variables
+ in a read modify write expression. These were the only variables that didn't have
+ types ascribed to them.
+
+ This patch also does a fly by fix where we kept pointers to value types
+ in a HashMap in the checker. This is wrong precisely when the HashMap gets
+ resized. Instead, we now just store the value itself since we're just
+ dealing with a simple Variant that wraps either an empty struct or an
+ enum.
+
+ Test: webgpu/whlsl-checker-should-set-type-of-read-modify-write-variables.html
+
+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h:
+ (WebCore::WHLSL::AST::VariableDeclaration::setType):
+ (WebCore::WHLSL::AST::VariableDeclaration::type const):
+ * Modules/webgpu/WHLSL/WHLSLASTDumper.cpp: Make it obvious that read
+ modify write expressions are such by prefixing them with "RMW".
+ (WebCore::WHLSL::ASTDumper::visit):
+ * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+ (WebCore::WHLSL::Checker::visit):
+
2019-06-19 Devin Rousso <drousso@apple.com>
Web Inspector: Network: replace CFNetwork SPI with new API where able
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h
index 9f8d99b..37ea386 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h
@@ -64,7 +64,15 @@
String& name() { return m_name; }
- const Optional<UniqueRef<UnnamedType>>& type() const { return m_type; } // Anonymous variables inside ReadModifyWriteExpressions have their type set by the type checker.
+ // We use this for ReadModifyWrite expressions, since we don't know the type of their
+ // internal variables until the checker runs. All other variables should start life out
+ // with a type.
+ void setType(UniqueRef<UnnamedType> type)
+ {
+ ASSERT(!m_type);
+ m_type = WTFMove(type);
+ }
+ const Optional<UniqueRef<UnnamedType>>& type() const { return m_type; }
UnnamedType* type() { return m_type ? &*m_type : nullptr; }
Optional<Semantic>& semantic() { return m_semantic; }
Expression* initializer() { return m_initializer ? &*m_initializer : nullptr; }
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
index 2ebf862..5cfc8e2 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
@@ -639,7 +639,7 @@
auto oldVariable = readModifyWriteExpression.oldVariableReference();
auto newVariable = readModifyWriteExpression.newVariableReference();
- m_out.print("(");
+ m_out.print("RMW(");
visit(oldVariable.get());
m_out.print(" = ");
visit(readModifyWriteExpression.leftValue());
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
index d894b92..c05c733 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
@@ -463,7 +463,7 @@
bool isBoolType(ResolvingType&);
struct RecurseInfo {
ResolvingType& resolvingType;
- AST::TypeAnnotation& typeAnnotation;
+ const AST::TypeAnnotation typeAnnotation;
};
Optional<RecurseInfo> recurseAndGetInfo(AST::Expression&, bool requiresLeftValue = false);
Optional<RecurseInfo> getInfo(AST::Expression&, bool requiresLeftValue = false);
@@ -859,13 +859,15 @@
if (!leftValueInfo)
return;
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198166 Figure out what to do with the ReadModifyWriteExpression's AnonymousVariables.
+ readModifyWriteExpression.oldValue().setType(leftValueInfo->resolvingType.getUnnamedType()->clone());
auto newValueInfo = recurseAndGetInfo(readModifyWriteExpression.newValueExpression());
if (!newValueInfo)
return;
- if (!matchAndCommit(leftValueInfo->resolvingType, newValueInfo->resolvingType)) {
+ if (Optional<UniqueRef<AST::UnnamedType>> matchedType = matchAndCommit(leftValueInfo->resolvingType, newValueInfo->resolvingType))
+ readModifyWriteExpression.newValue().setType(WTFMove(matchedType.value()));
+ else {
setError();
return;
}
@@ -1131,8 +1133,7 @@
ASSERT(variableReference.variable()->type());
AST::TypeAnnotation typeAnnotation = AST::RightValue();
- if (!variableReference.variable()->isAnonymous()) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198166 This doesn't seem right.
- typeAnnotation = AST::LeftValue { AST::AddressSpace::Thread };
+ typeAnnotation = AST::LeftValue { AST::AddressSpace::Thread };
assignType(variableReference, variableReference.variable()->type()->clone(), WTFMove(typeAnnotation));
}