WebKit Bugzilla
Attachment 373006 Details for
Bug 198414
: [WHLSL] Implement arrays and MakeArrayReference
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for landing
b-backup.diff (text/plain), 38.23 KB, created by
Saam Barati
on 2019-06-27 00:35:12 PDT
(
hide
)
Description:
patch for landing
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2019-06-27 00:35:12 PDT
Size:
38.23 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 246873) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,53 @@ >+2019-06-27 Saam Barati <sbarati@apple.com> >+ >+ [WHLSL] Implement arrays and MakeArrayReference >+ https://bugs.webkit.org/show_bug.cgi?id=198414 >+ >+ Reviewed by Myles C. Maxfield. >+ >+ This patch implements WHLSL arrays. The main implementation detail is that >+ arrays get compiled to use Metal's array type. To make everything work, this >+ patch also fixes a few bugs: >+ - The checker now allows "operator.length" to be called on arrays. Prior to >+ this patch, it was just allowed on array references. >+ >+ - The preserve variable lifetimes pass now looks at MakeArrayReference nodes. >+ Prior to this patch, it just looked at MakePointerExpression. >+ >+ - We were producing the wrong type for ander arguments for indexed accesses >+ on array types. We were saying the argument that was produced was a reference >+ to an array instead of an array reference to the element type. >+ >+ - The trie we compose for the reverse type hierarchy was inserting elements >+ into the wrong "children" vector. We were always inserting things into the >+ top level vector. This is wrong when we have a nesting of types > 1. >+ >+ I also found a bug with having arrays of pointers when writing this patch. >+ Work on this will take place in a follow up: https://bugs.webkit.org/show_bug.cgi?id=199197 >+ >+ Tests: webgpu/whlsl-huge-array.html >+ webgpu/whlsl-make-array-reference.html >+ webgpu/whlsl-simple-arrays.html >+ webgpu/whlsl-two-dimensional-array.html >+ >+ * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp: >+ (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit): >+ * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp: >+ (WebCore::WHLSL::Metal::writeNativeFunction): >+ * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp: >+ (WebCore::WHLSL::Metal::TypeNamer::insert): >+ (WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition): >+ * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h: >+ * Modules/webgpu/WHLSL/WHLSLChecker.cpp: >+ (WebCore::WHLSL::resolveByInstantiation): >+ (WebCore::WHLSL::Checker::visit): >+ * Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp: >+ (WebCore::WHLSL::EscapedVariableCollector::escapeVariableUse): >+ * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp: >+ (WebCore::WHLSL::wrapAnderCallArgument): >+ (WebCore::WHLSL::anderCallArgument): >+ * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt: >+ > 2019-06-26 Simon Fraser <simon.fraser@apple.com> > > [Async overflow scrolling] Fix missing or misplaced content inside overflow:scroll >Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (working copy) >@@ -183,7 +183,7 @@ static Optional<AST::NativeFunctionDecla > return resolveWithOperatorAnderIndexer(origin, *firstArgumentArrayRef, intrinsics); > } else if (name == "operator.length" && types.size() == 1) { > auto* firstArgumentReference = types[0].get().visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::UnnamedType* { >- if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType))) >+ if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)) || is<AST::ArrayType>(static_cast<AST::UnnamedType&>(unnamedType))) > return &unnamedType; > return nullptr; > }, [](RefPtr<ResolvableTypeReference>&) -> AST::UnnamedType* { >@@ -1132,9 +1132,7 @@ void Checker::visit(AST::VariableReferen > ASSERT(variableReference.variable()); > ASSERT(variableReference.variable()->type()); > >- AST::TypeAnnotation typeAnnotation = AST::RightValue(); >- typeAnnotation = AST::LeftValue { AST::AddressSpace::Thread }; >- assignType(variableReference, variableReference.variable()->type()->clone(), WTFMove(typeAnnotation)); >+ assignType(variableReference, variableReference.variable()->type()->clone(), AST::LeftValue { AST::AddressSpace::Thread }); > } > > void Checker::visit(AST::Return& returnStatement) >Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp (working copy) >@@ -55,17 +55,17 @@ namespace WHLSL { > class EscapedVariableCollector : public Visitor { > using Base = Visitor; > public: >- void visit(AST::MakePointerExpression& makePointerExpression) override >+ >+ void escapeVariableUse(AST::Expression& expression) > { >- if (!is<AST::VariableReference>(makePointerExpression.leftValue())) { >+ if (!is<AST::VariableReference>(expression)) { > // FIXME: Are we missing any interesting productions here? > // https://bugs.webkit.org/show_bug.cgi?id=198311 >- Base::visit(makePointerExpression.leftValue()); >+ Base::visit(expression); > return; > } > >- auto& variableReference = downcast<AST::VariableReference>(makePointerExpression.leftValue()); >- auto* variable = variableReference.variable(); >+ auto* variable = downcast<AST::VariableReference>(expression).variable(); > ASSERT(variable); > // FIXME: We could skip this if we mark all internal variables with a bit, since we > // never make any internal variable escape the current scope it is defined in: >@@ -73,6 +73,16 @@ public: > m_escapedVariables.add(variable, makeString("_", variable->name(), "_", m_count++)); > } > >+ void visit(AST::MakePointerExpression& makePointerExpression) override >+ { >+ escapeVariableUse(makePointerExpression.leftValue()); >+ } >+ >+ void visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) override >+ { >+ escapeVariableUse(makeArrayReferenceExpression.leftValue()); >+ } >+ > HashMap<AST::VariableDeclaration*, String> takeEscapedVariables() { return WTFMove(m_escapedVariables); } > > private: >Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp (working copy) >@@ -95,13 +95,12 @@ struct AnderCallArgumentResult { > }; > > template <typename ExpressionConstructor, typename TypeConstructor> >-static Optional<AnderCallArgumentResult> wrapAnderCallArgument(UniqueRef<AST::Expression>& expression, bool anderFunction, bool threadAnderFunction) >+static Optional<AnderCallArgumentResult> wrapAnderCallArgument(UniqueRef<AST::Expression>& expression, UniqueRef<AST::UnnamedType> baseType, bool anderFunction, bool threadAnderFunction) > { > if (auto addressSpace = expression->typeAnnotation().leftAddressSpace()) { > if (!anderFunction) > return WTF::nullopt; > auto origin = expression->origin(); >- auto baseType = expression->resolvedType().clone(); > auto makeArrayReference = makeUniqueRef<ExpressionConstructor>(Lexer::Token(origin), WTFMove(expression)); > makeArrayReference->setType(makeUniqueRef<TypeConstructor>(WTFMove(origin), *addressSpace, WTFMove(baseType))); > makeArrayReference->setTypeAnnotation(AST::RightValue()); >@@ -109,7 +108,6 @@ static Optional<AnderCallArgumentResult> > } > if (threadAnderFunction) { > auto origin = expression->origin(); >- auto baseType = expression->resolvedType().clone(); > auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), baseType->clone(), String(), WTF::nullopt, WTF::nullopt); > > auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >@@ -151,9 +149,9 @@ static Optional<AnderCallArgumentResult> > if (is<AST::ArrayReferenceType>(unnamedType)) > return {{ WTFMove(expression), WTF::nullopt, WhichAnder::Ander }}; > if (is<AST::ArrayType>(unnamedType)) >- return wrapAnderCallArgument<AST::MakeArrayReferenceExpression, AST::ArrayReferenceType>(expression, anderFunction, threadAnderFunction); >+ return wrapAnderCallArgument<AST::MakeArrayReferenceExpression, AST::ArrayReferenceType>(expression, downcast<AST::ArrayType>(unnamedType).type().clone(), anderFunction, threadAnderFunction); > } >- return wrapAnderCallArgument<AST::MakePointerExpression, AST::PointerType>(expression, anderFunction, threadAnderFunction); >+ return wrapAnderCallArgument<AST::MakePointerExpression, AST::PointerType>(expression, expression->resolvedType().clone(), anderFunction, threadAnderFunction); > } > > static Optional<UniqueRef<AST::Expression>> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::Expression>&& newValue, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, AST::VariableDeclaration* indexVariable) >Index: Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt (working copy) >@@ -792,6 +792,12 @@ int operator++(int value) { > int operator--(int value) { > return value - 1; > } >+uint operator++(uint value) { >+ return value + 1; >+} >+uint operator--(uint value) { >+ return value - 1; >+} > > native ushort Sample(Texture1D<ushort>, sampler, float location); > native ushort Sample(Texture1DArray<ushort>, sampler, float2 location); >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp (working copy) >@@ -628,16 +628,22 @@ void FunctionDefinitionWriter::visit(AST > checkErrorAndVisit(makeArrayReferenceExpression.leftValue()); > // FIXME: This needs to be made to work. It probably should be using the last leftValue too. > // https://bugs.webkit.org/show_bug.cgi?id=198838 >- auto lValue = takeLastValue(); > auto variableName = generateNextVariableName(); >+ > auto mangledTypeName = m_typeNamer.mangledNameForType(makeArrayReferenceExpression.resolvedType()); >- if (is<AST::PointerType>(makeArrayReferenceExpression.resolvedType())) >+ if (is<AST::PointerType>(makeArrayReferenceExpression.leftValue().resolvedType())) { >+ auto ptrValue = takeLastValue(); >+ m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, ";\n")); >+ m_stringBuilder.append(makeString("if (", ptrValue, ") ", variableName, " = { ", ptrValue, ", 1};\n")); >+ m_stringBuilder.append(makeString("else ", variableName, " = { nullptr, 0 };\n")); >+ } else if (is<AST::ArrayType>(makeArrayReferenceExpression.leftValue().resolvedType())) { >+ auto lValue = takeLastLeftValue(); >+ auto& arrayType = downcast<AST::ArrayType>(makeArrayReferenceExpression.leftValue().resolvedType()); >+ m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { ", lValue, "->data(), ", arrayType.numElements(), " };\n")); >+ } else { >+ auto lValue = takeLastLeftValue(); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { ", lValue, ", 1 };\n")); >- else if (is<AST::ArrayType>(makeArrayReferenceExpression.resolvedType())) { >- auto& arrayType = downcast<AST::ArrayType>(makeArrayReferenceExpression.resolvedType()); >- m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &(", lValue, "[0]), ", arrayType.numElements(), " };\n")); >- } else >- m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &", lValue, ", 1 };\n")); >+ } > appendRightValue(makeArrayReferenceExpression, variableName); > } > >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp (working copy) >@@ -174,8 +174,8 @@ String writeNativeFunction(AST::NativeFu > auto& unnamedParameterType = downcast<AST::UnnamedType>(parameterType); > if (is<AST::ArrayType>(unnamedParameterType)) { > auto& arrayParameterType = downcast<AST::ArrayType>(unnamedParameterType); >- stringBuilder.append(makeString("uint ", outputFunctionName, '(', metalParameterName, " v) {\n")); >- stringBuilder.append(makeString(" return ", arrayParameterType.numElements(), "u;\n")); >+ stringBuilder.append(makeString("uint ", outputFunctionName, '(', metalParameterName, ") {\n")); >+ stringBuilder.append(makeString(" return ", arrayParameterType.numElements(), ";\n")); > stringBuilder.append("}\n"); > return stringBuilder.toString(); > } >@@ -257,6 +257,7 @@ String writeNativeFunction(AST::NativeFu > auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " v, ", metalParameter2Name, " n) {\n")); >+ ASSERT(is<AST::ArrayReferenceType>(*nativeFunctionDeclaration.parameters()[0]->type())); > stringBuilder.append(" if (n < v.length) return &(v.pointer[n]);\n"); > stringBuilder.append(" return nullptr;\n"); > stringBuilder.append("}\n"); >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp (working copy) >@@ -309,7 +309,7 @@ UniqueRef<BaseTypeNameNode> TypeNamer::c > return makeUniqueRef<ArrayTypeNameNode>(parent, generateNextTypeName(), arrayType.numElements()); > } > >-size_t TypeNamer::insert(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types) >+BaseTypeNameNode* TypeNamer::insert(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types) > { > Vector<UniqueRef<BaseTypeNameNode>>* vectorToInsertInto { nullptr }; > BaseTypeNameNode* parent { nullptr }; >@@ -317,17 +317,14 @@ size_t TypeNamer::insert(AST::UnnamedTyp > vectorToInsertInto = &types; > parent = nullptr; > } else if (is<AST::PointerType>(unnamedType)) { >- auto& item = types[insert(downcast<AST::PointerType>(unnamedType).elementType(), types)]; >- vectorToInsertInto = &item->children(); >- parent = &item; >+ parent = insert(downcast<AST::PointerType>(unnamedType).elementType(), types); >+ vectorToInsertInto = &parent->children(); > } else if (is<AST::ArrayReferenceType>(unnamedType)) { >- auto& item = types[insert(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types)]; >- vectorToInsertInto = &item->children(); >- parent = &item; >+ parent = insert(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types); >+ vectorToInsertInto = &parent->children(); > } else { >- auto& item = types[insert(downcast<AST::ArrayType>(unnamedType).type(), types)]; >- vectorToInsertInto = &item->children(); >- parent = &item; >+ parent = insert(downcast<AST::ArrayType>(unnamedType).type(), types); >+ vectorToInsertInto = &parent->children(); > } > ASSERT(vectorToInsertInto); > >@@ -339,11 +336,11 @@ size_t TypeNamer::insert(AST::UnnamedTyp > ASSERT_UNUSED(addResult, addResult.isNewEntry); > } > vectorToInsertInto->append(WTFMove(result)); >- return vectorToInsertInto->size() - 1; >+ return &vectorToInsertInto->last().get(); > } > auto addResult = m_unnamedTypeMapping.add(&unnamedType, &*iterator); > ASSERT_UNUSED(addResult, addResult.isNewEntry); >- return iterator - vectorToInsertInto->begin(); >+ return &*iterator; > } > > class MetalTypeDeclarationWriter : public Visitor { >@@ -398,7 +395,7 @@ void TypeNamer::emitUnnamedTypeDefinitio > } else { > auto& arrayType = downcast<ArrayTypeNameNode>(baseTypeNameNode); > ASSERT(baseTypeNameNode.parent()); >- stringBuilder.append(makeString("typedef Array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n")); >+ stringBuilder.append(makeString("typedef array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n")); > } > emittedUnnamedTypes.add(&baseTypeNameNode); > } >Index: Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h >=================================================================== >--- Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h (revision 246850) >+++ Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h (working copy) >@@ -100,7 +100,7 @@ private: > String metalTypeDefinitions(); > > UniqueRef<BaseTypeNameNode> createNameNode(AST::UnnamedType&, BaseTypeNameNode* parent); >- size_t insert(AST::UnnamedType&, Vector<UniqueRef<BaseTypeNameNode>>&); >+ BaseTypeNameNode* insert(AST::UnnamedType&, Vector<UniqueRef<BaseTypeNameNode>>&); > > Program& m_program; > Vector<UniqueRef<BaseTypeNameNode>> m_trie; >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 246850) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,19 @@ >+2019-06-27 Saam Barati <sbarati@apple.com> >+ >+ [WHLSL] Implement arrays and MakeArrayReference >+ https://bugs.webkit.org/show_bug.cgi?id=198414 >+ >+ Reviewed by Myles C. Maxfield. >+ >+ * webgpu/whlsl-huge-array-expected.txt: Added. >+ * webgpu/whlsl-huge-array.html: Added. >+ * webgpu/whlsl-make-array-reference-expected.txt: Added. >+ * webgpu/whlsl-make-array-reference.html: Added. >+ * webgpu/whlsl-simple-arrays-expected.txt: Added. >+ * webgpu/whlsl-simple-arrays.html: Added. >+ * webgpu/whlsl-two-dimensional-array-expected.txt: Added. >+ * webgpu/whlsl-two-dimensional-array.html: Added. >+ > 2019-06-26 Joseph Pecoraro <pecoraro@apple.com> > > Web Inspector: Implement console.countReset >Index: LayoutTests/webgpu/whlsl-huge-array-expected.txt >=================================================================== >--- LayoutTests/webgpu/whlsl-huge-array-expected.txt (nonexistent) >+++ LayoutTests/webgpu/whlsl-huge-array-expected.txt (working copy) >@@ -0,0 +1,5 @@ >+PASS >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >Index: LayoutTests/webgpu/whlsl-huge-array.html >=================================================================== >--- LayoutTests/webgpu/whlsl-huge-array.html (nonexistent) >+++ LayoutTests/webgpu/whlsl-huge-array.html (working copy) >@@ -0,0 +1,115 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../resources/js-test-pre.js"></script> >+<script src="js/webgpu-functions.js"></script> >+</head> >+<body> >+<script> >+const shaderSource = ` >+void fill(thread float[] array, float value) { >+ for (uint i = 0; i < array.length; i++) { >+ array[i] = value; >+ } >+} >+ >+[numthreads(1, 1, 1)] >+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) { >+ float[1000] array; >+ if (array.length != 1000) >+ return; >+ for (uint i = 0; i < array.length; ++i) { >+ if (array[i] != 0) >+ return; >+ } >+ >+ array[0] = 0.1337; >+ if (array[0] != 0.1337) >+ return; >+ >+ thread float[] arrayPtr = @array; >+ if (arrayPtr.length != 1000) >+ return; >+ >+ fill(arrayPtr, 0.1010); >+ for (uint i = 0; i < arrayPtr.length; ++i) { >+ if (arrayPtr[i] != 0.1010) >+ return; >+ if (array[i] != 0.1010) >+ return; >+ } >+ >+ fill(@array, 0.0101); >+ for (uint i = 0; i < array.length; ++i) { >+ if (arrayPtr[i] != 0.0101) >+ return; >+ if (array[i] != 0.0101) >+ return; >+ } >+ >+ buffer[0] = 1; >+} >+`; >+async function start(device) { >+ 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 = Int32Array.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 Int32Array(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(); >+ let resultsInt32Array = new Int32Array(resultsArrayBuffer); >+ if (resultsInt32Array[0] === 1) >+ testPassed(""); >+ else >+ testFailed(""); >+ resultsBuffer.unmap(); >+} >+window.jsTestIsAsync = true; >+getBasicDevice().then(function(device) { >+ start(device).then(function() { >+ finishJSTest(); >+ }, function() { >+ testFailed(""); >+ finishJSTest(); >+ }); >+}, function() { >+ testPassed(""); >+ finishJSTest(); >+}); >+</script> >+<script src="../resources/js-test-post.js"></script> >+</body> >+</html> >Index: LayoutTests/webgpu/whlsl-make-array-reference-expected.txt >=================================================================== >--- LayoutTests/webgpu/whlsl-make-array-reference-expected.txt (nonexistent) >+++ LayoutTests/webgpu/whlsl-make-array-reference-expected.txt (working copy) >@@ -0,0 +1,5 @@ >+PASS >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >Index: LayoutTests/webgpu/whlsl-make-array-reference.html >=================================================================== >--- LayoutTests/webgpu/whlsl-make-array-reference.html (nonexistent) >+++ LayoutTests/webgpu/whlsl-make-array-reference.html (working copy) >@@ -0,0 +1,184 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../resources/js-test-pre.js"></script> >+<script src="js/webgpu-functions.js"></script> >+</head> >+<body> >+<script> >+const shaderSource = ` >+bool test1() { >+ int value = 42; >+ thread int[] array = @value; >+ if (array.length != 1) >+ return false; >+ if (array[0] != 42) >+ return false; >+ if (array[120213] != 0) >+ return false; >+ >+ array[0] = 1337; >+ if (value != 1337) >+ return false; >+ >+ return true; >+} >+ >+bool test2() { >+ int value = 42; >+ thread int* ptr = &value; >+ if (*ptr != 42) >+ return false; >+ >+ thread int[] array = @ptr; >+ if (array.length != 1) >+ return false; >+ if (array[0] != 42) >+ return false; >+ if (array[12374217] != 0) >+ return false; >+ >+ *ptr = 666; >+ if (*ptr != 666) >+ return false; >+ if (value != 666) >+ return false; >+ if (array.length != 1) >+ return false; >+ if (array[0] != 666) >+ return false; >+ >+ array[0] = 4242; >+ if (*ptr != 4242) >+ return false; >+ if (value != 4242) >+ return false; >+ if (array[0] != 4242) >+ return false; >+ if (array.length != 1) >+ return false; >+ >+ return true; >+} >+ >+bool test3() { >+ int[42] x; >+ thread int[42]* arrayPtr = &x; >+ if (arrayPtr->length != 42) >+ return false; >+ >+ x[41] = 666; >+ if ((*arrayPtr)[41] != 666) >+ return false; >+ if ((*arrayPtr)[0] != 0) >+ return false; >+ >+ thread int[] array = @x; >+ if (array.length != 42) >+ return false; >+ >+ array[0] = 1337; >+ if (x[0] != 1337) >+ return false; >+ if ((*arrayPtr)[0] != 1337) >+ return false; >+ >+ return true; >+} >+ >+bool test4() { >+ thread int* ptr = null; >+ >+ thread int[] array = @ptr; >+ if (array.length != 0) >+ return false; >+ >+ if (array[0] != 0) >+ return false; >+ >+ if (array[100000] != 0) >+ return false; >+ >+ return true; >+} >+ >+[numthreads(1, 1, 1)] >+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) { >+ if (!test1()) >+ return; >+ >+ if (!test2()) >+ return; >+ >+ if (!test3()) >+ return; >+ >+ if (!test4()) >+ return; >+ >+ buffer[0] = 1; >+} >+`; >+async function start(device) { >+ 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 = Int32Array.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 Int32Array(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(); >+ let resultsInt32Array = new Int32Array(resultsArrayBuffer); >+ if (resultsInt32Array[0] === 1) >+ testPassed(""); >+ else >+ testFailed(""); >+ resultsBuffer.unmap(); >+} >+window.jsTestIsAsync = true; >+getBasicDevice().then(function(device) { >+ start(device).then(function() { >+ finishJSTest(); >+ }, function() { >+ testFailed(""); >+ finishJSTest(); >+ }); >+}, function() { >+ testPassed(""); >+ finishJSTest(); >+}); >+</script> >+<script src="../resources/js-test-post.js"></script> >+</body> >+</html> >Index: LayoutTests/webgpu/whlsl-simple-arrays-expected.txt >=================================================================== >--- LayoutTests/webgpu/whlsl-simple-arrays-expected.txt (nonexistent) >+++ LayoutTests/webgpu/whlsl-simple-arrays-expected.txt (working copy) >@@ -0,0 +1,5 @@ >+PASS >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >Index: LayoutTests/webgpu/whlsl-simple-arrays.html >=================================================================== >--- LayoutTests/webgpu/whlsl-simple-arrays.html (nonexistent) >+++ LayoutTests/webgpu/whlsl-simple-arrays.html (working copy) >@@ -0,0 +1,123 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../resources/js-test-pre.js"></script> >+<script src="js/webgpu-functions.js"></script> >+</head> >+<body> >+<script> >+const shaderSource = ` >+void fill(thread int[] array, int value) { >+ for (uint i = 0; i < array.length; i++) { >+ array[i] = value; >+ } >+} >+ >+[numthreads(1, 1, 1)] >+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) { >+ int[42] array; >+ if (array.length != 42) >+ return; >+ for (uint i = 0; i < array.length; ++i) { >+ if (array[i] != 0) >+ return; >+ } >+ >+ array[0] = 517; >+ if (array[0] != 517) >+ return; >+ >+ thread int[] arrayPtr = @array; >+ if (arrayPtr.length != 42) >+ return; >+ >+ int[42] array2; >+ array2 = array; >+ if (array2.length != 42) >+ return; >+ if (array2[0] != 517) >+ return; >+ >+ fill(arrayPtr, 1337); >+ for (uint i = 0; i < arrayPtr.length; ++i) { >+ if (arrayPtr[i] != 1337) >+ return; >+ if (array[i] != 1337) >+ return; >+ } >+ >+ if (array2[0] != 517) >+ return; >+ if (array2.length != 42) >+ return; >+ for (uint i = 1; i < array2.length; ++i) { >+ if (array2[i] != 0) >+ return; >+ } >+ >+ buffer[0] = 1; >+} >+`; >+async function start(device) { >+ 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 = Int32Array.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 Int32Array(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(); >+ let resultsInt32Array = new Int32Array(resultsArrayBuffer); >+ if (resultsInt32Array[0] === 1) >+ testPassed(""); >+ else >+ testFailed(""); >+ resultsBuffer.unmap(); >+} >+window.jsTestIsAsync = true; >+getBasicDevice().then(function(device) { >+ start(device).then(function() { >+ finishJSTest(); >+ }, function() { >+ testFailed(""); >+ finishJSTest(); >+ }); >+}, function() { >+ testPassed(""); >+ finishJSTest(); >+}); >+</script> >+<script src="../resources/js-test-post.js"></script> >+</body> >+</html> >Index: LayoutTests/webgpu/whlsl-two-dimensional-array-expected.txt >=================================================================== >--- LayoutTests/webgpu/whlsl-two-dimensional-array-expected.txt (nonexistent) >+++ LayoutTests/webgpu/whlsl-two-dimensional-array-expected.txt (working copy) >@@ -0,0 +1,5 @@ >+PASS >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >Index: LayoutTests/webgpu/whlsl-two-dimensional-array.html >=================================================================== >--- LayoutTests/webgpu/whlsl-two-dimensional-array.html (nonexistent) >+++ LayoutTests/webgpu/whlsl-two-dimensional-array.html (working copy) >@@ -0,0 +1,125 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../resources/js-test-pre.js"></script> >+<script src="js/webgpu-functions.js"></script> >+</head> >+<body> >+<script> >+const shaderSource = ` >+void fill(thread float[10][] array, float[10] value) { >+ for (uint i = 0; i < array.length; i++) { >+ array[i] = value; >+ } >+} >+ >+void fill(thread float[] array, float value) { >+ for (uint i = 0; i < array.length; i++) { >+ array[i] = value; >+ } >+} >+ >+bool contains(thread float[10][] array, float value) { >+ for (uint i = 0; i < array.length; i++) { >+ for (uint j = 0; j < array[j].length; j++) { >+ if (array[i][j] != value) >+ return false; >+ } >+ } >+ return true; >+} >+ >+bool contains(thread float[] array, float value) { >+ for (uint i = 0; i < array.length; i++) { >+ if (array[i] != value) >+ return false; >+ } >+ return true; >+} >+ >+[numthreads(1, 1, 1)] >+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) { >+ float[10][5] array; >+ if (array.length != 5) >+ return; >+ if (!contains(@array, 0)) >+ return; >+ >+ for (uint i = 0; i < array.length; ++i) { >+ float[10] value; >+ fill(@value, float(i)); >+ array[i] = value; >+ } >+ >+ for (uint i = 0; i < array.length; ++i) { >+ float[10] value = array[i]; >+ if (!contains(@value, float(i))) >+ return; >+ } >+ >+ buffer[0] = 1; >+} >+`; >+async function start(device) { >+ 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 = Int32Array.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 Int32Array(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(); >+ let resultsInt32Array = new Int32Array(resultsArrayBuffer); >+ if (resultsInt32Array[0] === 1) >+ testPassed(""); >+ else >+ testFailed(""); >+ resultsBuffer.unmap(); >+} >+window.jsTestIsAsync = true; >+getBasicDevice().then(function(device) { >+ start(device).then(function() { >+ finishJSTest(); >+ }, function() { >+ testFailed(""); >+ finishJSTest(); >+ }); >+}, function() { >+ testPassed(""); >+ finishJSTest(); >+}); >+</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 198414
:
372664
|
372859
| 373006