Changeset 246394 in webkit
- Timestamp:
- Jun 12, 2019, 10:38:28 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 2 deleted
- 17 edited
- 2 copied
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/webgpu/buffer-resource-triangles-expected.html (deleted)
-
LayoutTests/webgpu/buffer-resource-triangles.html (deleted)
-
LayoutTests/webgpu/whlsl-buffer-fragment-expected.html (added)
-
LayoutTests/webgpu/whlsl-buffer-fragment.html (copied) (copied from trunk/LayoutTests/webgpu/whlsl.html ) (2 diffs)
-
LayoutTests/webgpu/whlsl-buffer-vertex-expected.html (added)
-
LayoutTests/webgpu/whlsl-buffer-vertex.html (copied) (copied from trunk/LayoutTests/webgpu/whlsl.html ) (4 diffs)
-
LayoutTests/webgpu/whlsl-dont-crash-parsing-enum.html (modified) (1 diff)
-
LayoutTests/webgpu/whlsl.html (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h (modified) (1 diff)
-
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp (modified) (2 diffs)
-
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp (modified) (4 diffs)
-
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h (modified) (1 diff)
-
Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (modified) (10 diffs)
-
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h (modified) (1 diff)
-
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp (modified) (18 diffs)
-
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp (modified) (2 diffs)
-
Source/WebCore/Modules/webgpu/WebGPUBindGroupDescriptor.cpp (modified) (2 diffs)
-
Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h (modified) (2 diffs)
-
Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm (modified) (3 diffs)
-
Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm (modified) (6 diffs)
-
Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r246393 r246394 1 2019-06-12 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [WHLSL] Implement array references 4 https://bugs.webkit.org/show_bug.cgi?id=198163 5 6 Reviewed by Saam Barati. 7 8 * webgpu/buffer-resource-triangles-expected.html: Deleted. This test doens't make any sense and triggers 9 Metal to read out-of-bounds of a vertex buffer. 10 * webgpu/buffer-resource-triangles.html: Deleted. 11 * webgpu/whlsl-buffer-fragment-expected.html: Added. 12 * webgpu/whlsl-buffer-fragment.html: Added. 13 * webgpu/whlsl-buffer-vertex-expected.html: Added. 14 * webgpu/whlsl-buffer-vertex.html: Added. 15 * webgpu/whlsl-dont-crash-parsing-enum.html: 16 * webgpu/whlsl.html: 17 1 18 2019-06-12 Justin Fan <justin_fan@apple.com> 2 19 -
trunk/LayoutTests/webgpu/whlsl-buffer-fragment.html
r246393 r246394 11 11 } 12 12 13 fragment float4 fragmentShader(float4 position : SV_Position ) : SV_Target 0 {14 return position;13 fragment float4 fragmentShader(float4 position : SV_Position, constant float[] theBuffer : register(b0)) : SV_Target 0 { 14 return float4(theBuffer[0], theBuffer[0], theBuffer[0], 1.0); 15 15 } 16 16 `; … … 70 70 const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync(); 71 71 const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer); 72 vertexBuffer1 Descriptor[0] = 1;73 vertexBuffer1 Descriptor[1] = 1;74 vertexBuffer1 Descriptor[2] = 1;75 vertexBuffer1 Descriptor[3] = 1;72 vertexBuffer1Float32Array[0] = 1; 73 vertexBuffer1Float32Array[1] = 1; 74 vertexBuffer1Float32Array[2] = 1; 75 vertexBuffer1Float32Array[3] = 1; 76 76 vertexBuffer1.unmap(); 77 77 -
trunk/LayoutTests/webgpu/whlsl-buffer-vertex.html
r246393 r246394 7 7 <script> 8 8 const shaderSource = ` 9 vertex float4 vertexShader( float4 position : attribute(0), float i : attribute(1)) : SV_Position {10 return position;9 vertex float4 vertexShader(constant float4[] buffer : register(b0), uint id : SV_VertexID) : SV_Position { 10 return buffer[id]; 11 11 } 12 12 13 13 fragment float4 fragmentShader(float4 position : SV_Position) : SV_Target 0 { 14 return position;14 return float4(1.0, 1.0, 1.0, 1.0); 15 15 } 16 16 `; … … 28 28 const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL 29 29 const depthStencilState = null; 30 31 const attribute0 = {shaderLocation: 0, format: "float4"}; 32 const attribute1 = {shaderLocation: 1, format: "float"}; 33 const input0 = {stride: 16, attributeSet: [attribute0]}; 34 const input1 = {stride: 4, attributeSet: [attribute1]}; 35 const inputs = [input0, input1]; 36 const vertexInput = {vertexBuffers: inputs}; 30 31 const vertexInput = {vertexBuffers: []}; 37 32 38 33 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 44 39 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 45 40 46 const vertexBuffer0Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE}; 47 const vertexBuffer0 = device.createBuffer(vertexBuffer0Descriptor); 48 const vertexBuffer0ArrayBuffer = await vertexBuffer0.mapWriteAsync(); 49 const vertexBuffer0Float32Array = new Float32Array(vertexBuffer0ArrayBuffer); 50 vertexBuffer0Float32Array[0] = -0.5; 51 vertexBuffer0Float32Array[1] = -0.5; 52 vertexBuffer0Float32Array[2] = 1.0; 53 vertexBuffer0Float32Array[3] = 1; 54 vertexBuffer0Float32Array[4] = -0.5; 55 vertexBuffer0Float32Array[5] = 0.5; 56 vertexBuffer0Float32Array[6] = 1.0; 57 vertexBuffer0Float32Array[7] = 1; 58 vertexBuffer0Float32Array[8] = 0.5; 59 vertexBuffer0Float32Array[9] = -0.5; 60 vertexBuffer0Float32Array[10] = 1.0; 61 vertexBuffer0Float32Array[11] = 1; 62 vertexBuffer0Float32Array[12] = 0.5; 63 vertexBuffer0Float32Array[13] = 0.5; 64 vertexBuffer0Float32Array[14] = 1.0; 65 vertexBuffer0Float32Array[15] = 1; 66 vertexBuffer0.unmap(); 67 68 const vertexBuffer1Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE}; 69 const vertexBuffer1 = device.createBuffer(vertexBuffer1Descriptor); 70 const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync(); 71 const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer); 72 vertexBuffer1Descriptor[0] = 1; 73 vertexBuffer1Descriptor[1] = 1; 74 vertexBuffer1Descriptor[2] = 1; 75 vertexBuffer1Descriptor[3] = 1; 76 vertexBuffer1.unmap(); 77 78 const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE}; 41 const resourceBufferDescriptor = {size: 4 * 4 * Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE}; 79 42 const resourceBuffer = device.createBuffer(resourceBufferDescriptor); 80 43 const resourceBufferArrayBuffer = await resourceBuffer.mapWriteAsync(); 81 44 const resourceBufferFloat32Array = new Float32Array(resourceBufferArrayBuffer); 82 resourceBufferFloat32Array[0] = 1; 45 resourceBufferFloat32Array[0] = -0.5; 46 resourceBufferFloat32Array[1] = -0.5; 47 resourceBufferFloat32Array[2] = 1.0; 48 resourceBufferFloat32Array[3] = 1; 49 resourceBufferFloat32Array[4] = -0.5; 50 resourceBufferFloat32Array[5] = 0.5; 51 resourceBufferFloat32Array[6] = 1.0; 52 resourceBufferFloat32Array[7] = 1; 53 resourceBufferFloat32Array[8] = 0.5; 54 resourceBufferFloat32Array[9] = -0.5; 55 resourceBufferFloat32Array[10] = 1.0; 56 resourceBufferFloat32Array[11] = 1; 57 resourceBufferFloat32Array[12] = 0.5; 58 resourceBufferFloat32Array[13] = 0.5; 59 resourceBufferFloat32Array[14] = 1.0; 60 resourceBufferFloat32Array[15] = 1; 83 61 resourceBuffer.unmap(); 84 62 … … 103 81 renderPassEncoder.setPipeline(renderPipeline); 104 82 renderPassEncoder.setBindGroup(0, bindGroup); 105 renderPassEncoder.setVertexBuffers(0, [vertexBuffer0, vertexBuffer1], [0, 0]);106 83 renderPassEncoder.draw(4, 1, 0, 0); 107 84 renderPassEncoder.endPass(); -
trunk/LayoutTests/webgpu/whlsl-dont-crash-parsing-enum.html
r246390 r246394 75 75 const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync(); 76 76 const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer); 77 vertexBuffer1 Descriptor[0] = 1;78 vertexBuffer1 Descriptor[1] = 1;79 vertexBuffer1 Descriptor[2] = 1;80 vertexBuffer1 Descriptor[3] = 1;77 vertexBuffer1Float32Array[0] = 1; 78 vertexBuffer1Float32Array[1] = 1; 79 vertexBuffer1Float32Array[2] = 1; 80 vertexBuffer1Float32Array[3] = 1; 81 81 vertexBuffer1.unmap(); 82 82 -
trunk/LayoutTests/webgpu/whlsl.html
r246390 r246394 70 70 const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync(); 71 71 const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer); 72 vertexBuffer1 Descriptor[0] = 1;73 vertexBuffer1 Descriptor[1] = 1;74 vertexBuffer1 Descriptor[2] = 1;75 vertexBuffer1 Descriptor[3] = 1;72 vertexBuffer1Float32Array[0] = 1; 73 vertexBuffer1Float32Array[1] = 1; 74 vertexBuffer1Float32Array[2] = 1; 75 vertexBuffer1Float32Array[3] = 1; 76 76 vertexBuffer1.unmap(); 77 77 -
trunk/Source/WebCore/ChangeLog
r246391 r246394 1 2019-06-12 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [WHLSL] Implement array references 4 https://bugs.webkit.org/show_bug.cgi?id=198163 5 6 Reviewed by Saam Barati. 7 8 The compiler automatically generates anders for every array reference. Luckily, the infrastructure 9 to generate those anders and emit Metal code to represent them already exists in the compiler. 10 There are two pieces remaining (which this patch implements): 11 12 1. The JavaScript compiler has a behavior where anders that are called with an array reference 13 as an argument don't wrap the argument in a MakePointerExpression. This is because the array 14 reference is already a reference type, so it's silly to operate on a pointer to a reference. 15 This patch implements this by teaching the type checker about which types should be passed 16 to the ander call, and by actually constructing those types in the property resolver. 17 The property resolver does this by placing the logic to construct an ander argument in a 18 single function which also has logic to save the argument in a temporary if the thread ander 19 will be called. The semantics about which functions are called in which situations are not 20 changed; instead, we just simply don't wrap array references with MakePointerExpressions. 21 22 2. Creating a bind group from the WebGPU API has to retain information about buffer lengths for 23 each buffer so the shader can properly perform bounds checks. This can be broken down into a 24 few pieces: 25 - Creating a bind group layout has to assign extra id indexes for each buffer which will be 26 filled in to represent the buffer's length 27 - Creating the bind group itself needs to fill in the buffer length into the Metal argument 28 buffer 29 - The shader compiler needs to emit code at the beginning of entry point to find the buffer 30 lengths and pack them together into the array reference (array references correspond to 31 a Metal struct with two fields: a pointer and a length). 32 33 This patch doesn't actually implement bounds checks themselves; it just hooks up the buffer 34 lengths so https://bugs.webkit.org/show_bug.cgi?id=198600 can implement it. 35 36 The shader compiler's API is modified to allow for this extra buffer length information to be 37 passed in from the WebGPU implementation. 38 39 Unfortunately, I don't think I could split this patch up into two pieces because both are 40 required to test the compiler with buffers. 41 42 Tests: webgpu/whlsl-buffer-fragment.html 43 webgpu/whlsl-buffer-vertex.html 44 45 * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h: 46 (WebCore::WHLSL::AST::PropertyAccessExpression::baseReference): 47 * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp: 48 (WebCore::WHLSL::AST::ResourceSemantic::isAcceptableType const): Arrays can't be resources 49 because the compiler has no way of guaranteeing if the resource is long enough to hold the 50 array at compile time. 51 * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp: 52 (WebCore::WHLSL::Metal::EntryPointScaffolding::EntryPointScaffolding): Generate an extra 53 variable name to represent the buffer length. Only do it for resources which have lengths. 54 (WebCore::WHLSL::Metal::EntryPointScaffolding::resourceHelperTypes): 55 (WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): Perform 56 the appropriate math to turn byte lengths into element counts and store the element count 57 in the array reference. 58 * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h: 59 * Modules/webgpu/WHLSL/WHLSLChecker.cpp: 60 (WebCore::WHLSL::resolveWithOperatorAnderIndexer): Refactor. 61 (WebCore::WHLSL::resolveWithOperatorLength): Ditto. 62 (WebCore::WHLSL::resolveWithReferenceComparator): Ditto. 63 (WebCore::WHLSL::resolveByInstantiation): Ditto. 64 (WebCore::WHLSL::argumentTypeForAndOverload): Given an ander, what should the type of the 65 argument be? 66 (WebCore::WHLSL::Checker::finishVisiting): Call argumentTypeForAndOverload(). Also, if 67 we couldn't find an ander, try automatically generating it, the same way that function 68 calls do. (This is how array references get their anders.) 69 (WebCore::WHLSL::Checker::visit): 70 * Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h: New WHLSL API to provide the length 71 information. 72 * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp: 73 (WebCore::WHLSL::PropertyResolver::visit): SimplifyRightValue() can't fail any more. 74 (WebCore::WHLSL::wrapAnderCallArgument): If the ander argument should be wrapped in a 75 MakePointer or a MakeArrayReference, do that. Also, if the ander is a thread ander, save 76 the argument in a local variable and use that. 77 (WebCore::WHLSL::anderCallArgument): The equivalent of argumentTypeForAndOverload(). 78 (WebCore::WHLSL::setterCall): Call anderCallArgument(). 79 (WebCore::WHLSL::getterCall): Ditto. 80 (WebCore::WHLSL::modify): We used to have special-case code for handling pointer-to-argument 81 values as distinct from just the argument values themselves. However, emitting 82 chains of &* operators is valid and won't even make it through the Metal code generator 83 after https://bugs.webkit.org/show_bug.cgi?id=198600 is fixed. So, in order to simplify 84 wrapAnderCallArgument(), don't special case these values and just create &* chains instead. 85 (WebCore::WHLSL::PropertyResolver::simplifyRightValue): 86 (WebCore::WHLSL::LeftValueSimplifier::finishVisiting): Call anderCallArgument(). 87 * Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp: Update to support the new compiler API. 88 (WebCore::WHLSL::matchMode): 89 (WebCore::WHLSL::matchResources): 90 * Modules/webgpu/WebGPUBindGroupDescriptor.cpp: Ditto. 91 (WebCore::WebGPUBindGroupDescriptor::tryCreateGPUBindGroupDescriptor const): 92 * platform/graphics/gpu/GPUBindGroupLayout.h: Add some internal implementation data inside 93 the bindings object. Use a Variant to differentiate between the various bindings types, and 94 put the extra length field on just those members of the variant that represent buffers. 95 * platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm: Update to support the new compiler API. 96 (WebCore::argumentDescriptor): 97 (WebCore::GPUBindGroupLayout::tryCreate): 98 * platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm: Ditto. 99 (WebCore::setBufferOnEncoder): 100 (WebCore::GPUBindGroup::tryCreate): 101 * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm: Ditto. 102 (WebCore::convertBindingType): 103 (WebCore::convertLayout): 104 1 105 2019-06-12 Carlos Garcia Campos <cgarcia@igalia.com> 2 106 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h
r245680 r246394 100 100 101 101 Expression& base() { return m_base; } 102 UniqueRef<Expression>& baseReference() { return m_base; } 102 103 UniqueRef<Expression> takeBase() { return WTFMove(m_base); } 103 104 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp
r245680 r246394 50 50 return referenceType.addressSpace() == AddressSpace::Constant || referenceType.addressSpace() == AddressSpace::Device; 51 51 } 52 if (is<ArrayType>(unnamedType))53 return true;54 52 if (is<TypeReference>(unnamedType)) { 55 53 auto& typeReference = downcast<TypeReference>(unnamedType); … … 72 70 if (is<ReferenceType>(unnamedType)) 73 71 return downcast<ReferenceType>(unnamedType).addressSpace() == AddressSpace::Constant; 74 return is<ArrayType>(unnamedType);72 return false; 75 73 case Mode::Sampler: 76 74 return matches(unnamedType, intrinsics.samplerType()); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp
r245759 r246394 33 33 #include "WHLSLGatherEntryPointItems.h" 34 34 #include "WHLSLPipelineDescriptor.h" 35 #include "WHLSLReferenceType.h" 35 36 #include "WHLSLResourceSemantic.h" 36 37 #include "WHLSLStageInOutSemantic.h" … … 109 110 NamedBinding namedBinding; 110 111 namedBinding.elementName = m_typeNamer.generateNextStructureElementName(); 111 namedBinding.index = m_layout[i].bindings[j].name; // GPUBindGroupLayout::tryCreate() makes sure these don't collide. 112 namedBinding.index = m_layout[i].bindings[j].internalName; 113 WTF::visit(WTF::makeVisitor([&](UniformBufferBinding& uniformBufferBinding) { 114 LengthInformation lengthInformation { m_typeNamer.generateNextStructureElementName(), m_generateNextVariableName(), uniformBufferBinding.lengthName }; 115 namedBinding.lengthInformation = lengthInformation; 116 }, [&](SamplerBinding&) { 117 }, [&](TextureBinding&) { 118 }, [&](StorageBufferBinding& storageBufferBinding) { 119 LengthInformation lengthInformation { m_typeNamer.generateNextStructureElementName(), m_generateNextVariableName(), storageBufferBinding.lengthName }; 120 namedBinding.lengthInformation = lengthInformation; 121 }), m_layout[i].bindings[j].binding); 112 122 namedBindGroup.namedBindings.uncheckedAppend(WTFMove(namedBinding)); 113 123 } … … 138 148 if (iterator == m_resourceMap.end()) 139 149 continue; 140 auto mangledTypeName = m_typeNamer.mangledNameForType(*m_entryPointItems.inputs[iterator->value].unnamedType); 150 auto& unnamedType = *m_entryPointItems.inputs[iterator->value].unnamedType; 151 ASSERT(is<AST::ReferenceType>(unnamedType)); 152 auto& referenceType = downcast<AST::ReferenceType>(unnamedType); 153 auto mangledTypeName = m_typeNamer.mangledNameForType(referenceType.elementType()); 154 auto addressSpace = toString(referenceType.addressSpace()); 141 155 auto elementName = m_namedBindGroups[i].namedBindings[j].elementName; 142 156 auto index = m_namedBindGroups[i].namedBindings[j].index; 143 stringBuilder.append(makeString(" ", mangledTypeName, ' ', elementName, " [[id(", index, ")]];\n")); 157 stringBuilder.append(makeString(" ", addressSpace, " ", mangledTypeName, "* ", elementName, " [[id(", index, ")]];\n")); 158 if (auto lengthInformation = m_namedBindGroups[i].namedBindings[j].lengthInformation) 159 stringBuilder.append(makeString(" uint2 ", lengthInformation->elementName, " [[id(", lengthInformation->index, ")]];\n")); 144 160 } 145 161 stringBuilder.append("};\n\n"); … … 258 274 if (iterator == m_resourceMap.end()) 259 275 continue; 260 auto& path = m_entryPointItems.inputs[iterator->value].path; 261 auto elementName = m_namedBindGroups[i].namedBindings[j].elementName; 262 stringBuilder.append(makeString(mangledInputPath(path), " = ", variableName, '.', elementName, ";\n")); 276 if (m_namedBindGroups[i].namedBindings[j].lengthInformation) { 277 auto& path = m_entryPointItems.inputs[iterator->value].path; 278 auto elementName = m_namedBindGroups[i].namedBindings[j].elementName; 279 auto lengthElementName = m_namedBindGroups[i].namedBindings[j].lengthInformation->elementName; 280 auto lengthTemporaryName = m_namedBindGroups[i].namedBindings[j].lengthInformation->temporaryName; 281 282 auto& unnamedType = *m_entryPointItems.inputs[iterator->value].unnamedType; 283 ASSERT(is<AST::ReferenceType>(unnamedType)); 284 auto& referenceType = downcast<AST::ReferenceType>(unnamedType); 285 auto mangledTypeName = m_typeNamer.mangledNameForType(referenceType.elementType()); 286 287 stringBuilder.append(makeString("size_t ", lengthTemporaryName, " = ", variableName, '.', lengthElementName, ".x;\n")); 288 stringBuilder.append(makeString(lengthTemporaryName, " = ", lengthTemporaryName, " << 32;\n")); 289 stringBuilder.append(makeString(lengthTemporaryName, " = ", lengthTemporaryName, " | ", variableName, '.', lengthElementName, ".y;\n")); 290 stringBuilder.append(makeString(lengthTemporaryName, " = ", lengthTemporaryName, " / sizeof(", mangledTypeName, ");\n")); 291 stringBuilder.append(makeString("if (", lengthTemporaryName, " > 0xFFFFFFFF) ", lengthTemporaryName, " = 0xFFFFFFFF;\n")); 292 stringBuilder.append(makeString(mangledInputPath(path), " = { ", variableName, '.', elementName, ", static_cast<uint32_t>(", lengthTemporaryName, ") };\n")); 293 } else { 294 auto& path = m_entryPointItems.inputs[iterator->value].path; 295 auto elementName = m_namedBindGroups[i].namedBindings[j].elementName; 296 stringBuilder.append(makeString(mangledInputPath(path), " = ", variableName, '.', elementName, ";\n")); 297 } 263 298 } 264 299 } -
trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h
r243091 r246394 78 78 std::function<String()> m_generateNextVariableName; 79 79 80 struct LengthInformation { 81 String elementName; 82 String temporaryName; 83 unsigned index; 84 }; 80 85 struct NamedBinding { 81 86 String elementName; 82 87 unsigned index; 88 Optional<LengthInformation> lengthInformation; 83 89 }; 84 90 struct NamedBindGroup { -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
r246385 r246394 118 118 }; 119 119 120 static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer( AST::CallExpression& callExpression, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)120 static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(Lexer::Token origin, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics) 121 121 { 122 122 const bool isOperator = true; 123 auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token( callExpression.origin()), firstArgument.addressSpace(), firstArgument.elementType().clone());123 auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(origin), firstArgument.addressSpace(), firstArgument.elementType().clone()); 124 124 AST::VariableDeclarations parameters; 125 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token( callExpression.origin()), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt));126 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token( callExpression.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType())), String(), WTF::nullopt, WTF::nullopt));127 return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token( callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));128 } 129 130 static AST::NativeFunctionDeclaration resolveWithOperatorLength( AST::CallExpression& callExpression, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics)125 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt)); 126 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.uintType())), String(), WTF::nullopt, WTF::nullopt)); 127 return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(origin), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator)); 128 } 129 130 static AST::NativeFunctionDeclaration resolveWithOperatorLength(Lexer::Token origin, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics) 131 131 { 132 132 const bool isOperator = true; 133 auto returnType = AST::TypeReference::wrap(Lexer::Token( callExpression.origin()), intrinsics.uintType());133 auto returnType = AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.uintType()); 134 134 AST::VariableDeclarations parameters; 135 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token( callExpression.origin()), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt));136 return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token( callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));137 } 138 139 static AST::NativeFunctionDeclaration resolveWithReferenceComparator( AST::CallExpression& callExpression, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics)135 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt)); 136 return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(origin), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator)); 137 } 138 139 static AST::NativeFunctionDeclaration resolveWithReferenceComparator(Lexer::Token origin, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics) 140 140 { 141 141 const bool isOperator = true; 142 auto returnType = AST::TypeReference::wrap(Lexer::Token( callExpression.origin()), intrinsics.boolType());142 auto returnType = AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.boolType()); 143 143 auto argumentType = firstArgument.visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> UniqueRef<AST::UnnamedType> { 144 144 return unnamedType->clone(); … … 150 150 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198162 This can probably be generalized, using the "preferred type" infrastructure used by generic literals 151 151 ASSERT_NOT_REACHED(); 152 return AST::TypeReference::wrap(Lexer::Token( callExpression.origin()), intrinsics.intType());152 return AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.intType()); 153 153 })); 154 154 })); 155 155 AST::VariableDeclarations parameters; 156 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token( callExpression.origin()), AST::Qualifiers(), argumentType->clone(), String(), WTF::nullopt, WTF::nullopt));157 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token( callExpression.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(WTFMove(argumentType)), String(), WTF::nullopt, WTF::nullopt));158 return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token( callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));156 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), argumentType->clone(), String(), WTF::nullopt, WTF::nullopt)); 157 parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(WTFMove(argumentType)), String(), WTF::nullopt, WTF::nullopt)); 158 return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(origin), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator)); 159 159 } 160 160 … … 165 165 }; 166 166 167 static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation( AST::CallExpression& callExpression, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics)168 { 169 if ( callExpression.name()== "operator&[]" && types.size() == 2) {167 static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const String& name, Lexer::Token origin, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics) 168 { 169 if (name == "operator&[]" && types.size() == 2) { 170 170 auto* firstArgumentArrayRef = types[0].get().visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::ArrayReferenceType* { 171 171 if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType))) … … 181 181 })); 182 182 if (firstArgumentArrayRef && secondArgumentIsUint) 183 return resolveWithOperatorAnderIndexer( callExpression, *firstArgumentArrayRef, intrinsics);184 } else if ( callExpression.name()== "operator.length" && types.size() == 1) {183 return resolveWithOperatorAnderIndexer(origin, *firstArgumentArrayRef, intrinsics); 184 } else if (name == "operator.length" && types.size() == 1) { 185 185 auto* firstArgumentReference = types[0].get().visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::UnnamedType* { 186 186 if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType))) … … 191 191 })); 192 192 if (firstArgumentReference) 193 return resolveWithOperatorLength( callExpression, *firstArgumentReference, intrinsics);194 } else if ( callExpression.name()== "operator==" && types.size() == 2) {193 return resolveWithOperatorLength(origin, *firstArgumentReference, intrinsics); 194 } else if (name == "operator==" && types.size() == 2) { 195 195 auto acceptability = [](ResolvingType& resolvingType) -> Acceptability { 196 196 return resolvingType.visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> Acceptability { … … 211 211 success = true; 212 212 if (success) 213 return resolveWithReferenceComparator( callExpression, types[0].get(), types[1].get(), intrinsics);213 return resolveWithReferenceComparator(origin, types[0].get(), types[1].get(), intrinsics); 214 214 } 215 215 return WTF::nullopt; … … 970 970 } 971 971 972 static Optional<UniqueRef<AST::UnnamedType>> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace addressSpace) 973 { 974 auto& unifyNode = baseType.unifyNode(); 975 if (is<AST::NamedType>(unifyNode)) { 976 auto& namedType = downcast<AST::NamedType>(unifyNode); 977 return { makeUniqueRef<AST::PointerType>(Lexer::Token(namedType.origin()), addressSpace, AST::TypeReference::wrap(Lexer::Token(namedType.origin()), namedType)) }; 978 } 979 980 ASSERT(is<AST::UnnamedType>(unifyNode)); 981 auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); 982 983 if (is<AST::ArrayReferenceType>(unnamedType)) 984 return unnamedType.clone(); 985 986 if (is<AST::ArrayType>(unnamedType)) 987 return { makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(unnamedType.origin()), addressSpace, downcast<AST::ArrayType>(unnamedType).type().clone()) }; 988 989 if (is<AST::PointerType>(unnamedType)) 990 return WTF::nullopt; 991 992 return { makeUniqueRef<AST::PointerType>(Lexer::Token(unnamedType.origin()), addressSpace, unnamedType.clone()) }; 993 } 994 972 995 void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpression, ResolvingType* additionalArgumentType) 973 996 { … … 993 1016 auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace(); 994 1017 if (leftAddressSpace) { 995 ResolvingType argumentType = { makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), *leftAddressSpace, baseUnnamedType->get().clone()) }; 996 Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType }; 997 if (additionalArgumentType) 998 anderArgumentTypes.append(*additionalArgumentType); 999 if ((anderFunction = resolveFunctionOverload(propertyAccessExpression.possibleAnderOverloads(), anderArgumentTypes))) 1000 anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer 1018 if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, *leftAddressSpace)) { 1019 ResolvingType argumentType = { WTFMove(*argumentTypeForAndOverload) }; 1020 Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType }; 1021 if (additionalArgumentType) 1022 anderArgumentTypes.append(*additionalArgumentType); 1023 if ((anderFunction = resolveFunctionOverload(propertyAccessExpression.possibleAnderOverloads(), anderArgumentTypes))) 1024 anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer 1025 else if (auto newFunction = resolveByInstantiation(propertyAccessExpression.anderFunctionName(), propertyAccessExpression.origin(), anderArgumentTypes, m_intrinsics)) { 1026 m_program.append(WTFMove(*newFunction)); 1027 anderFunction = &m_program.nativeFunctionDeclarations().last(); 1028 anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer 1029 } 1030 } 1001 1031 } 1002 1032 1003 1033 AST::FunctionDeclaration* threadAnderFunction = nullptr; 1004 1034 AST::UnnamedType* threadAnderReturnType = nullptr; 1005 {1035 if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, AST::AddressSpace::Thread)) { 1006 1036 ResolvingType argumentType = { makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, baseUnnamedType->get().clone()) }; 1007 1037 Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { argumentType }; … … 1010 1040 if ((threadAnderFunction = resolveFunctionOverload(propertyAccessExpression.possibleAnderOverloads(), threadAnderArgumentTypes))) 1011 1041 threadAnderReturnType = &downcast<AST::PointerType>(threadAnderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer 1042 else if (auto newFunction = resolveByInstantiation(propertyAccessExpression.anderFunctionName(), propertyAccessExpression.origin(), threadAnderArgumentTypes, m_intrinsics)) { 1043 m_program.append(WTFMove(*newFunction)); 1044 threadAnderFunction = &m_program.nativeFunctionDeclarations().last(); 1045 threadAnderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer 1046 } 1012 1047 } 1013 1048 … … 1435 1470 auto* function = resolveFunctionOverload(*callExpression.overloads(), types, callExpression.castReturnType()); 1436 1471 if (!function) { 1437 if (auto newFunction = resolveByInstantiation(callExpression , types, m_intrinsics)) {1472 if (auto newFunction = resolveByInstantiation(callExpression.name(), callExpression.origin(), types, m_intrinsics)) { 1438 1473 m_program.append(WTFMove(*newFunction)); 1439 1474 function = &m_program.nativeFunctionDeclarations().last(); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h
r245759 r246394 115 115 }; 116 116 117 enum class BindingType : uint8_t { 118 UniformBuffer, 119 Sampler, 120 Texture, 121 StorageBuffer, 122 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198168 Add the dynamic types 117 struct UniformBufferBinding { 118 unsigned lengthName; 123 119 }; 124 120 121 struct SamplerBinding { 122 }; 123 124 struct TextureBinding { 125 }; 126 127 struct StorageBufferBinding { 128 unsigned lengthName; 129 }; 130 131 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198168 Add the dynamic types 132 125 133 struct Binding { 134 using BindingDetails = Variant<UniformBufferBinding, SamplerBinding, TextureBinding, StorageBufferBinding>; 126 135 OptionSet<ShaderStage> visibility; 127 BindingType bindingType; 128 unsigned name; 136 BindingDetails binding; 137 unsigned internalName; 138 unsigned externalName; 129 139 }; 130 140 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp
r246385 r246394 36 36 #include "WHLSLFunctionDeclaration.h" 37 37 #include "WHLSLFunctionDefinition.h" 38 #include "WHLSLMakeArrayReferenceExpression.h" 38 39 #include "WHLSLMakePointerExpression.h" 39 40 #include "WHLSLPointerType.h" … … 56 57 void visit(AST::ReadModifyWriteExpression&) override; 57 58 58 boolsimplifyRightValue(AST::PropertyAccessExpression&);59 void simplifyRightValue(AST::PropertyAccessExpression&); 59 60 bool simplifyAbstractLeftValue(AST::AssignmentExpression&, AST::DotExpression&, UniqueRef<AST::Expression>&& right); 60 61 void simplifyLeftValue(AST::Expression&); … … 66 67 { 67 68 // Unless we're inside an AssignmentExpression or a ReadModifyWriteExpression, we're a right value. 68 if (!simplifyRightValue(dotExpression)) 69 setError(); 69 simplifyRightValue(dotExpression); 70 70 } 71 71 … … 74 74 checkErrorAndVisit(indexExpression.indexExpression()); 75 75 // Unless we're inside an AssignmentExpression or a ReadModifyWriteExpression, we're a right value. 76 if (!simplifyRightValue(indexExpression)) 77 setError(); 76 simplifyRightValue(indexExpression); 78 77 } 79 78 … … 85 84 } 86 85 87 static Optional<UniqueRef<AST::Expression>> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::Expression>&& newValue, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory, AST::VariableDeclaration* indexVariable) 86 enum class WhichAnder { 87 ThreadAnder, 88 Ander 89 }; 90 91 struct AnderCallArgumentResult { 92 UniqueRef<AST::Expression> expression; 93 Optional<UniqueRef<AST::VariableDeclaration>> variableDeclaration; 94 WhichAnder whichAnder; 95 }; 96 97 template <typename ExpressionConstructor, typename TypeConstructor> 98 static Optional<AnderCallArgumentResult> wrapAnderCallArgument(UniqueRef<AST::Expression>& expression, bool anderFunction, bool threadAnderFunction) 99 { 100 if (auto addressSpace = expression->typeAnnotation().leftAddressSpace()) { 101 if (!anderFunction) 102 return WTF::nullopt; 103 auto origin = expression->origin(); 104 auto baseType = expression->resolvedType().clone(); 105 auto makeArrayReference = makeUniqueRef<ExpressionConstructor>(Lexer::Token(origin), WTFMove(expression)); 106 makeArrayReference->setType(makeUniqueRef<TypeConstructor>(WTFMove(origin), *addressSpace, WTFMove(baseType))); 107 makeArrayReference->setTypeAnnotation(AST::RightValue()); 108 return {{ WTFMove(makeArrayReference), WTF::nullopt, WhichAnder::Ander }}; 109 } 110 if (threadAnderFunction) { 111 auto origin = expression->origin(); 112 auto baseType = expression->resolvedType().clone(); 113 auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), baseType->clone(), String(), WTF::nullopt, WTF::nullopt); 114 115 auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 116 variableReference1->setType(baseType->clone()); 117 variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 118 119 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), WTFMove(expression)); 120 assignmentExpression->setType(baseType->clone()); 121 assignmentExpression->setTypeAnnotation(AST::RightValue()); 122 123 auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 124 variableReference2->setType(baseType->clone()); 125 variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 126 127 auto expression = makeUniqueRef<ExpressionConstructor>(Lexer::Token(origin), WTFMove(variableReference2)); 128 auto resultType = makeUniqueRef<TypeConstructor>(Lexer::Token(origin), AST::AddressSpace::Thread, WTFMove(baseType)); 129 expression->setType(resultType->clone()); 130 expression->setTypeAnnotation(AST::RightValue()); 131 132 Vector<UniqueRef<AST::Expression>> expressions; 133 expressions.append(WTFMove(assignmentExpression)); 134 expressions.append(WTFMove(expression)); 135 auto commaExpression = makeUniqueRef<AST::CommaExpression>(WTFMove(origin), WTFMove(expressions)); 136 commaExpression->setType(WTFMove(resultType)); 137 commaExpression->setTypeAnnotation(AST::RightValue()); 138 return {{ WTFMove(commaExpression), { WTFMove(variableDeclaration) }, WhichAnder::ThreadAnder}}; 139 } 140 return WTF::nullopt; 141 } 142 143 static Optional<AnderCallArgumentResult> anderCallArgument(UniqueRef<AST::Expression>& expression, bool anderFunction, bool threadAnderFunction) 144 { 145 auto& unifyNode = expression->resolvedType().unifyNode(); 146 if (is<AST::UnnamedType>(unifyNode)) { 147 auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); 148 ASSERT(!is<AST::PointerType>(unnamedType)); 149 if (is<AST::ArrayReferenceType>(unnamedType)) 150 return {{ WTFMove(expression), WTF::nullopt, WhichAnder::Ander }}; 151 if (is<AST::ArrayType>(unnamedType)) 152 return wrapAnderCallArgument<AST::MakeArrayReferenceExpression, AST::ArrayReferenceType>(expression, anderFunction, threadAnderFunction); 153 } 154 return wrapAnderCallArgument<AST::MakePointerExpression, AST::PointerType>(expression, anderFunction, threadAnderFunction); 155 } 156 157 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) 88 158 { 89 159 auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::Expression>>& arguments) { … … 99 169 if (relevantAnder) { 100 170 // *operator&.foo(&v) = newValue 171 auto leftValue = leftValueFactory(); 172 auto argument = anderCallArgument(leftValue, true, true); 173 ASSERT(argument); 174 ASSERT(!argument->variableDeclaration); 175 ASSERT(argument->whichAnder == WhichAnder::Ander); 101 176 Vector<UniqueRef<AST::Expression>> arguments; 102 arguments.append( pointerToLeftValueFactory());177 arguments.append(WTFMove(argument->expression)); 103 178 maybeAddIndexArgument(arguments); 104 179 … … 139 214 } 140 215 141 static Optional<UniqueRef<AST::Expression>> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory,AST::VariableDeclaration* indexVariable)216 static Optional<UniqueRef<AST::Expression>> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, AST::VariableDeclaration* indexVariable) 142 217 { 143 218 auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::Expression>>& arguments) { … … 153 228 if (relevantAnder) { 154 229 // *operator&.foo(&v) 230 auto leftValue = leftValueFactory(); 231 auto argument = anderCallArgument(leftValue, true, true); 232 ASSERT(argument); 233 ASSERT(!argument->variableDeclaration); 234 ASSERT(argument->whichAnder == WhichAnder::Ander); 155 235 Vector<UniqueRef<AST::Expression>> arguments; 156 arguments.append( pointerToLeftValueFactory());236 arguments.append(WTFMove(argument->expression)); 157 237 maybeAddIndexArgument(arguments); 158 238 … … 171 251 // operator.foo(v) 172 252 ASSERT(propertyAccessExpression.getterFunction()); 173 253 174 254 Vector<UniqueRef<AST::Expression>> arguments; 175 255 arguments.append(leftValueFactory()); … … 305 385 return variableReference; 306 386 } 307 387 308 388 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); 309 389 ASSERT(pointerVariable->type()); … … 317 397 return dereferenceExpression; 318 398 }; 319 auto pointerToPreviousLeftValue = [&]() -> UniqueRef<AST::Expression> {320 if (previous) {321 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*previous));322 ASSERT(previous->type());323 variableReference->setType(previous->type()->clone());324 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?325 326 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference));327 ASSERT(previous->type());328 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, previous->type()->clone()));329 makePointerExpression->setTypeAnnotation(AST::RightValue());330 return makePointerExpression;331 }332 333 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable));334 ASSERT(pointerVariable->type());335 variableReference->setType(pointerVariable->type()->clone());336 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?337 return variableReference;338 };339 399 auto appendIndexAssignment = [&](AST::PropertyAccessExpression& propertyAccessExpression, Optional<UniqueRef<AST::VariableDeclaration>>& indexVariable) { 340 400 if (!indexVariable) … … 362 422 363 423 AST::FunctionDeclaration* relevantAnder = i == chain.size() - 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction(); 364 auto callExpression = getterCall(propertyAccessExpression, relevantAnder, previousLeftValue, pointerToPreviousLeftValue,indexVariable ? &*indexVariable : nullptr);424 auto callExpression = getterCall(propertyAccessExpression, relevantAnder, previousLeftValue, indexVariable ? &*indexVariable : nullptr); 365 425 366 426 if (!callExpression) … … 377 437 378 438 expressions.append(WTFMove(assignmentExpression)); 379 439 380 440 previous = &variableDeclaration; 381 441 } 382 442 appendIndexAssignment(chain[0], indexVariables[0]); 383 443 AST::FunctionDeclaration* relevantAnder = chain.size() == 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction(); 384 auto lastGetterCallExpression = getterCall(chain[0], relevantAnder, previousLeftValue, pointerToPreviousLeftValue,indexVariables[0] ? &*(indexVariables[0]) : nullptr);444 auto lastGetterCallExpression = getterCall(chain[0], relevantAnder, previousLeftValue, indexVariables[0] ? &*(indexVariables[0]) : nullptr); 385 445 386 446 // Step 3: … … 405 465 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 406 466 return variableReference; 407 }, [&]() -> UniqueRef<AST::Expression> {408 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));409 ASSERT(variableDeclaration.type());410 variableReference->setType(variableDeclaration.type()->clone());411 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?412 413 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference));414 ASSERT(variableDeclaration.type());415 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, variableDeclaration.type()->clone()));416 makePointerExpression->setTypeAnnotation(AST::RightValue());417 return makePointerExpression;418 467 }, indexVariable ? &*indexVariable : nullptr); 419 468 … … 443 492 dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(*pointerVariable->type()).addressSpace() }); 444 493 return dereferenceExpression; 445 }, [&]() -> UniqueRef<AST::Expression> {446 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable));447 ASSERT(pointerVariable->type());448 variableReference->setType(pointerVariable->type()->clone());449 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?450 return variableReference;451 494 }, indexVariables[indexVariables.size() - 1] ? &*(indexVariables[indexVariables.size() - 1]) : nullptr); 452 495 … … 672 715 } 673 716 674 bool PropertyResolver::simplifyRightValue(AST::PropertyAccessExpression& propertyAccessExpression) 717 static Optional<AnderCallArgumentResult> anderCallArgument(AST::PropertyAccessExpression& propertyAccessExpression) 718 { 719 return anderCallArgument(propertyAccessExpression.baseReference(), propertyAccessExpression.anderFunction(), propertyAccessExpression.threadAnderFunction()); 720 } 721 722 void PropertyResolver::simplifyRightValue(AST::PropertyAccessExpression& propertyAccessExpression) 675 723 { 676 724 Lexer::Token origin = propertyAccessExpression.origin(); … … 678 726 checkErrorAndVisit(propertyAccessExpression.base()); 679 727 680 auto& base = propertyAccessExpression.base(); 681 if (auto leftAddressSpace = base.typeAnnotation().leftAddressSpace()) { 682 if (auto* anderFunction = propertyAccessExpression.anderFunction()) { 683 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), propertyAccessExpression.takeBase()); 684 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), *leftAddressSpace, base.resolvedType().clone())); 685 makePointerExpression->setTypeAnnotation(AST::RightValue()); 686 687 Vector<UniqueRef<AST::Expression>> arguments; 688 arguments.append(WTFMove(makePointerExpression)); 689 if (is<AST::IndexExpression>(propertyAccessExpression)) 690 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 691 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); 692 callExpression->setType(anderFunction->type().clone()); 693 callExpression->setTypeAnnotation(AST::RightValue()); 694 callExpression->setFunction(*anderFunction); 695 696 auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(callExpression)); 697 dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); 698 dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() }); 699 return true; 700 } 701 } 702 703 if (propertyAccessExpression.getterFunction()) { 704 auto& getterFunction = *propertyAccessExpression.getterFunction(); 728 if (auto argument = anderCallArgument(propertyAccessExpression)) { 729 auto* anderFunction = argument->whichAnder == WhichAnder::ThreadAnder ? propertyAccessExpression.threadAnderFunction() : propertyAccessExpression.anderFunction(); 730 ASSERT(anderFunction); 731 auto origin = propertyAccessExpression.origin(); 705 732 Vector<UniqueRef<AST::Expression>> arguments; 706 arguments.append( propertyAccessExpression.takeBase());733 arguments.append(WTFMove(argument->expression)); 707 734 if (is<AST::IndexExpression>(propertyAccessExpression)) 708 735 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 709 auto* callExpression = AST::replaceWith<AST::CallExpression>(propertyAccessExpression, WTFMove(origin), String(getterFunction.name()), WTFMove(arguments)); 710 callExpression->setFunction(getterFunction); 711 callExpression->setType(getterFunction.type().clone()); 736 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); 737 callExpression->setType(anderFunction->type().clone()); 712 738 callExpression->setTypeAnnotation(AST::RightValue()); 713 return true; 714 } 715 716 // We have an ander, but no left value to call it on. Let's save the value into a temporary variable to create a left value. 717 // This is effectively inlining the functions the spec says are generated. 718 ASSERT(propertyAccessExpression.threadAnderFunction()); 719 auto* threadAnderFunction = propertyAccessExpression.threadAnderFunction(); 720 721 auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), base.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt); 722 723 auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 724 variableReference1->setType(base.resolvedType().clone()); 725 variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 726 727 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), propertyAccessExpression.takeBase()); 728 assignmentExpression->setType(base.resolvedType().clone()); 729 assignmentExpression->setTypeAnnotation(AST::RightValue()); 730 731 auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 732 variableReference2->setType(base.resolvedType().clone()); 733 variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 734 735 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), WTFMove(variableReference2)); 736 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), AST::AddressSpace::Thread, base.resolvedType().clone())); 737 makePointerExpression->setTypeAnnotation(AST::RightValue()); 738 739 callExpression->setFunction(*anderFunction); 740 741 auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(callExpression)); 742 dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); 743 dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() }); 744 745 if (auto& variableDeclaration = argument->variableDeclaration) 746 m_variableDeclarations.append(WTFMove(*variableDeclaration)); 747 748 return; 749 } 750 751 ASSERT(propertyAccessExpression.getterFunction()); 752 auto& getterFunction = *propertyAccessExpression.getterFunction(); 739 753 Vector<UniqueRef<AST::Expression>> arguments; 740 arguments.append( WTFMove(makePointerExpression));754 arguments.append(propertyAccessExpression.takeBase()); 741 755 if (is<AST::IndexExpression>(propertyAccessExpression)) 742 756 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 743 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(threadAnderFunction->name()), WTFMove(arguments)); 744 callExpression->setType(threadAnderFunction->type().clone()); 757 auto* callExpression = AST::replaceWith<AST::CallExpression>(propertyAccessExpression, WTFMove(origin), String(getterFunction.name()), WTFMove(arguments)); 758 callExpression->setFunction(getterFunction); 759 callExpression->setType(getterFunction.type().clone()); 745 760 callExpression->setTypeAnnotation(AST::RightValue()); 746 callExpression->setFunction(*threadAnderFunction);747 748 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(WTFMove(origin), WTFMove(callExpression));749 dereferenceExpression->setType(downcast<AST::PointerType>(threadAnderFunction->type()).elementType().clone());750 dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });751 752 Vector<UniqueRef<AST::Expression>> expressions;753 expressions.append(WTFMove(assignmentExpression));754 expressions.append(WTFMove(dereferenceExpression));755 auto* commaExpression = AST::replaceWith<AST::CommaExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(expressions));756 commaExpression->setType(downcast<AST::PointerType>(threadAnderFunction->type()).elementType().clone());757 commaExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });758 759 m_variableDeclarations.append(WTFMove(variableDeclaration));760 return true;761 762 761 } 763 762 … … 778 777 Lexer::Token origin = propertyAccessExpression.origin(); 779 778 auto* anderFunction = propertyAccessExpression.anderFunction(); 780 auto& base = propertyAccessExpression.base(); 781 auto leftAddressSpace = *propertyAccessExpression.base().typeAnnotation().leftAddressSpace();782 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), propertyAccessExpression.takeBase());783 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), leftAddressSpace, base.resolvedType().clone()));784 makePointerExpression->setTypeAnnotation(AST::RightValue());779 780 auto argument = anderCallArgument(propertyAccessExpression); 781 ASSERT(argument); 782 ASSERT(!argument->variableDeclaration); 783 ASSERT(argument->whichAnder == WhichAnder::Ander); 785 784 786 785 Vector<UniqueRef<AST::Expression>> arguments; 787 arguments.append(WTFMove( makePointerExpression));786 arguments.append(WTFMove(argument->expression)); 788 787 if (is<AST::IndexExpression>(propertyAccessExpression)) 789 788 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp
r245759 r246394 56 56 }; 57 57 58 static bool matchMode(BindingType bindingType, AST::ResourceSemantic::Mode mode) 59 { 60 switch (bindingType) { 61 case BindingType::UniformBuffer: 58 static bool matchMode(Binding::BindingDetails bindingType, AST::ResourceSemantic::Mode mode) 59 { 60 return WTF::visit(WTF::makeVisitor([&](UniformBufferBinding) -> bool { 62 61 return mode == AST::ResourceSemantic::Mode::Buffer; 63 case BindingType::Sampler:62 }, [&](SamplerBinding) -> bool { 64 63 return mode == AST::ResourceSemantic::Mode::Sampler; 65 case BindingType::Texture:64 }, [&](TextureBinding) -> bool { 66 65 return mode == AST::ResourceSemantic::Mode::Texture; 67 default: 68 ASSERT(bindingType == BindingType::StorageBuffer); 66 }, [&](StorageBufferBinding) -> bool { 69 67 return mode == AST::ResourceSemantic::Mode::UnorderedAccessView; 70 } 68 }), bindingType); 71 69 } 72 70 … … 88 86 continue; 89 87 auto& resourceSemantic = WTF::get<AST::ResourceSemantic>(semantic); 90 if (!matchMode(binding.binding Type, resourceSemantic.mode()))88 if (!matchMode(binding.binding, resourceSemantic.mode())) 91 89 continue; 92 if (binding. name != resourceSemantic.index())90 if (binding.externalName != resourceSemantic.index()) 93 91 continue; 94 92 if (space != resourceSemantic.space()) -
trunk/Source/WebCore/Modules/webgpu/WebGPUBindGroupDescriptor.cpp
r243636 r246394 112 112 return WTF::nullopt; 113 113 114 if (!validateBufferBindingType(buffer, layoutBinding , functionName))114 if (!validateBufferBindingType(buffer, layoutBinding.externalBinding, functionName)) 115 115 return WTF::nullopt; 116 116 … … 120 120 auto bindingResource = WTF::visit(bindingResourceVisitor, binding.resource); 121 121 if (!bindingResource) { 122 LOG(WebGPU, "%s: Invalid resource for binding %u!", functionName, layoutBinding. binding);122 LOG(WebGPU, "%s: Invalid resource for binding %u!", functionName, layoutBinding.externalBinding.binding); 123 123 return WTF::nullopt; 124 124 } -
trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h
r243658 r246394 34 34 #include <wtf/RefPtr.h> 35 35 #include <wtf/RetainPtr.h> 36 #include <wtf/Variant.h> 36 37 37 38 #if USE(METAL) … … 48 49 static RefPtr<GPUBindGroupLayout> tryCreate(const GPUDevice&, const GPUBindGroupLayoutDescriptor&); 49 50 50 using BindingsMapType = HashMap<uint64_t, GPUBindGroupLayoutBinding, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>; 51 struct UniformBuffer { 52 unsigned internalLengthName; 53 }; 54 55 struct DynamicUniformBuffer { 56 unsigned internalLengthName; 57 }; 58 59 struct Sampler { 60 }; 61 62 struct SampledTexture { 63 }; 64 65 struct StorageBuffer { 66 unsigned internalLengthName; 67 }; 68 69 struct DynamicStorageBuffer { 70 unsigned internalLengthName; 71 }; 72 73 using InternalBindingDetails = Variant<UniformBuffer, DynamicUniformBuffer, Sampler, SampledTexture, StorageBuffer, DynamicStorageBuffer>; 74 75 struct Binding { 76 GPUBindGroupLayoutBinding externalBinding; 77 unsigned internalName; 78 InternalBindingDetails internalBindingDetails; 79 }; 80 81 using BindingsMapType = HashMap<uint64_t, Binding, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>; 51 82 const BindingsMapType& bindingsMap() const { return m_bindingsMap; } 52 83 #if USE(METAL) -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm
r243636 r246394 78 78 }; 79 79 80 static RetainPtr<MTLArgumentDescriptor> argumentDescriptor(MTLDataType dataType, NSUInteger index) 81 { 82 RetainPtr<MTLArgumentDescriptor> mtlArgument; 83 BEGIN_BLOCK_OBJC_EXCEPTIONS; 84 mtlArgument = adoptNS([MTLArgumentDescriptor new]); 85 END_BLOCK_OBJC_EXCEPTIONS; 86 87 [mtlArgument setDataType:dataType]; 88 [mtlArgument setIndex:index]; 89 return mtlArgument; 90 } 91 80 92 RefPtr<GPUBindGroupLayout> GPUBindGroupLayout::tryCreate(const GPUDevice& device, const GPUBindGroupLayoutDescriptor& descriptor) 81 93 { … … 88 100 BindingsMapType bindingsMap; 89 101 102 unsigned internalName = 0; 103 unsigned internalLengthBase = descriptor.bindings.size(); 90 104 for (const auto& binding : descriptor.bindings) { 91 if (!bindingsMap.add(binding.binding, binding)) { 105 Optional<unsigned> extraIndex; 106 auto internalDetails = ([&]() -> GPUBindGroupLayout::InternalBindingDetails { 107 switch (binding.type) { 108 case GPUBindingType::UniformBuffer: 109 extraIndex = internalLengthBase++; 110 return GPUBindGroupLayout::UniformBuffer { *extraIndex }; 111 case GPUBindingType::DynamicUniformBuffer: 112 extraIndex = internalLengthBase++; 113 return GPUBindGroupLayout::DynamicUniformBuffer { *extraIndex }; 114 case GPUBindingType::Sampler: 115 return GPUBindGroupLayout::Sampler { }; 116 case GPUBindingType::SampledTexture: 117 return GPUBindGroupLayout::SampledTexture { }; 118 case GPUBindingType::StorageBuffer: 119 extraIndex = internalLengthBase++; 120 return GPUBindGroupLayout::StorageBuffer { *extraIndex }; 121 default: 122 ASSERT(binding.type == GPUBindingType::DynamicStorageBuffer); 123 extraIndex = internalLengthBase++; 124 return GPUBindGroupLayout::DynamicStorageBuffer { *extraIndex }; 125 } 126 })(); 127 Binding bindingDetails = { binding, internalName++, WTFMove(internalDetails) }; 128 if (!bindingsMap.add(binding.binding, bindingDetails)) { 92 129 LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Duplicate binding %u found in GPUBindGroupLayoutDescriptor!", binding.binding); 93 130 return nullptr; 94 131 } 95 132 96 RetainPtr<MTLArgumentDescriptor> mtlArgument ;133 RetainPtr<MTLArgumentDescriptor> mtlArgument = argumentDescriptor(MTLDataTypeForBindingType(binding.type), bindingDetails.internalName); 97 134 98 BEGIN_BLOCK_OBJC_EXCEPTIONS;99 mtlArgument = adoptNS([MTLArgumentDescriptor new]);100 END_BLOCK_OBJC_EXCEPTIONS;101 135 if (!mtlArgument) { 102 136 LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLArgumentDescriptor for binding %u!", binding.binding); … … 104 138 } 105 139 106 [mtlArgument setDataType:MTLDataTypeForBindingType(binding.type)]; 107 [mtlArgument setIndex:binding.binding]; 108 109 if (binding.visibility & GPUShaderStageBit::Flags::Vertex) 110 appendArgumentToArray(vertexArgsArray, mtlArgument); 111 if (binding.visibility & GPUShaderStageBit::Flags::Fragment) 112 appendArgumentToArray(fragmentArgsArray, mtlArgument); 113 if (binding.visibility & GPUShaderStageBit::Flags::Compute) 114 appendArgumentToArray(computeArgsArray, mtlArgument); 140 auto addIndices = [&](ArgumentArray& array) -> bool { 141 appendArgumentToArray(array, mtlArgument); 142 if (extraIndex) { 143 RetainPtr<MTLArgumentDescriptor> mtlArgument = argumentDescriptor(MTLDataTypeUInt2, *extraIndex); 144 if (!mtlArgument) { 145 LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLArgumentDescriptor for binding %u!", binding.binding); 146 return false; 147 } 148 appendArgumentToArray(array, mtlArgument); 149 } 150 return true; 151 }; 152 if ((binding.visibility & GPUShaderStageBit::Flags::Vertex) && !addIndices(vertexArgsArray)) 153 return nullptr; 154 if ((binding.visibility & GPUShaderStageBit::Flags::Fragment) && !addIndices(fragmentArgsArray)) 155 return nullptr; 156 if ((binding.visibility & GPUShaderStageBit::Flags::Compute) && !addIndices(computeArgsArray)) 157 return nullptr; 115 158 } 116 159 117 160 RetainPtr<MTLArgumentEncoder> vertex, fragment, compute; 118 161 119 if (vertexArgsArray) { 120 if (!(vertex = tryCreateMtlArgumentEncoder(device, vertexArgsArray))) 121 return nullptr; 122 } 123 if (fragmentArgsArray) { 124 if (!(fragment = tryCreateMtlArgumentEncoder(device, fragmentArgsArray))) 125 return nullptr; 126 } 127 if (computeArgsArray) { 128 if (!(compute = tryCreateMtlArgumentEncoder(device, computeArgsArray))) 129 return nullptr; 130 } 162 if (vertexArgsArray && !(vertex = tryCreateMtlArgumentEncoder(device, vertexArgsArray))) 163 return nullptr; 164 if (fragmentArgsArray && !(fragment = tryCreateMtlArgumentEncoder(device, fragmentArgsArray))) 165 return nullptr; 166 if (computeArgsArray && !(compute = tryCreateMtlArgumentEncoder(device, computeArgsArray))) 167 return nullptr; 131 168 132 169 return adoptRef(new GPUBindGroupLayout(WTFMove(bindingsMap), WTFMove(vertex), WTFMove(fragment), WTFMove(compute))); -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm
r244235 r246394 73 73 } 74 74 75 static void setBufferOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBufferBinding& bufferBinding, unsigned index)75 static void setBufferOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBufferBinding& bufferBinding, unsigned name, unsigned lengthName) 76 76 { 77 77 ASSERT(argumentEncoder && bufferBinding.buffer->platformBuffer()); … … 79 79 BEGIN_BLOCK_OBJC_EXCEPTIONS; 80 80 // Bounds check when converting GPUBufferBinding ensures that NSUInteger cast of uint64_t offset is safe. 81 [argumentEncoder setBuffer:bufferBinding.buffer->platformBuffer() offset:static_cast<NSUInteger>(bufferBinding.offset) atIndex:index]; 81 [argumentEncoder setBuffer:bufferBinding.buffer->platformBuffer() offset:static_cast<NSUInteger>(bufferBinding.offset) atIndex:name]; 82 void* lengthPointer = [argumentEncoder constantDataAtIndex:lengthName]; 83 memcpy(lengthPointer, &bufferBinding.size, sizeof(uint64_t)); 82 84 END_BLOCK_OBJC_EXCEPTIONS; 83 85 } … … 172 174 } 173 175 auto layoutBinding = layoutIterator->value; 174 if (layoutBinding. visibility == GPUShaderStageBit::Flags::None)176 if (layoutBinding.externalBinding.visibility == GPUShaderStageBit::Flags::None) 175 177 continue; 176 178 177 bool isForVertex = layoutBinding. visibility & GPUShaderStageBit::Flags::Vertex;178 bool isForFragment = layoutBinding. visibility & GPUShaderStageBit::Flags::Fragment;179 bool isForCompute = layoutBinding. visibility & GPUShaderStageBit::Flags::Compute;179 bool isForVertex = layoutBinding.externalBinding.visibility & GPUShaderStageBit::Flags::Vertex; 180 bool isForFragment = layoutBinding.externalBinding.visibility & GPUShaderStageBit::Flags::Fragment; 181 bool isForCompute = layoutBinding.externalBinding.visibility & GPUShaderStageBit::Flags::Compute; 180 182 181 183 if (isForVertex && !vertexEncoder) { … … 192 194 } 193 195 194 switch (layoutBinding.type) { 195 // FIXME: Support more resource types. 196 // FIXME: We could avoid this ugly switch-on-type using virtual functions if GPUBindingResource is refactored as a base class rather than a Variant. 197 case GPUBindingType::UniformBuffer: 198 case GPUBindingType::StorageBuffer: { 196 auto handleBuffer = [&](unsigned internalLengthName) -> bool { 199 197 auto bufferResource = tryGetResourceAsBufferBinding(resourceBinding.resource, functionName); 200 198 if (!bufferResource) 201 return nullptr;199 return false; 202 200 if (isForVertex) 203 setBufferOnEncoder(vertexEncoder, *bufferResource, index);201 setBufferOnEncoder(vertexEncoder, *bufferResource, layoutBinding.internalName, internalLengthName); 204 202 if (isForFragment) 205 setBufferOnEncoder(fragmentEncoder, *bufferResource, index);203 setBufferOnEncoder(fragmentEncoder, *bufferResource, layoutBinding.internalName, internalLengthName); 206 204 if (isForCompute) 207 setBufferOnEncoder(computeEncoder, *bufferResource, index);205 setBufferOnEncoder(computeEncoder, *bufferResource, layoutBinding.internalName, internalLengthName); 208 206 boundBuffers.append(bufferResource->buffer.copyRef()); 209 break; 210 } 211 case GPUBindingType::Sampler: { 207 return true; 208 }; 209 210 auto success = WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer& uniformBuffer) -> bool { 211 return handleBuffer(uniformBuffer.internalLengthName); 212 }, [&](GPUBindGroupLayout::DynamicUniformBuffer& dynamicUniformBuffer) -> bool { 213 return handleBuffer(dynamicUniformBuffer.internalLengthName); 214 }, [&](GPUBindGroupLayout::Sampler&) -> bool { 212 215 auto samplerState = tryGetResourceAsMtlSampler(resourceBinding.resource, functionName); 213 216 if (!samplerState) 214 return nullptr;217 return false; 215 218 if (isForVertex) 216 219 setSamplerOnEncoder(vertexEncoder, samplerState, index); … … 219 222 if (isForCompute) 220 223 setSamplerOnEncoder(computeEncoder, samplerState, index); 221 break; 222 } 223 case GPUBindingType::SampledTexture: { 224 return true; 225 }, [&](GPUBindGroupLayout::SampledTexture&) -> bool { 224 226 auto textureResource = tryGetResourceAsTexture(resourceBinding.resource, functionName); 225 227 if (!textureResource) 226 return nullptr;228 return false; 227 229 if (isForVertex) 228 230 setTextureOnEncoder(vertexEncoder, textureResource->platformTexture(), index); … … 232 234 setTextureOnEncoder(computeEncoder, textureResource->platformTexture(), index); 233 235 boundTextures.append(textureResource.releaseNonNull()); 234 break; 235 } 236 default: 237 LOG(WebGPU, "%s: Resource type not yet implemented.", functionName); 238 return nullptr; 239 } 236 return true; 237 }, [&](GPUBindGroupLayout::StorageBuffer& storageBuffer) -> bool { 238 return handleBuffer(storageBuffer.internalLengthName); 239 }, [&](GPUBindGroupLayout::DynamicStorageBuffer& dynamicStorageBuffer) -> bool { 240 return handleBuffer(dynamicStorageBuffer.internalLengthName); 241 }), layoutBinding.internalBindingDetails); 242 if (!success) 243 return nullptr; 240 244 } 241 245 -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm
r245905 r246394 111 111 } 112 112 113 static Optional<WHLSL::BindingType> convertBindingType(GPUBindingType type) 114 { 115 switch (type) { 116 case GPUBindingType::UniformBuffer: 117 return WHLSL::BindingType::UniformBuffer; 118 case GPUBindingType::Sampler: 119 return WHLSL::BindingType::Sampler; 120 case GPUBindingType::SampledTexture: 121 return WHLSL::BindingType::Texture; 122 case GPUBindingType::StorageBuffer: 123 return WHLSL::BindingType::StorageBuffer; 124 default: 113 static Optional<WHLSL::Binding::BindingDetails> convertBindingType(GPUBindGroupLayout::InternalBindingDetails internalBindingDetails) 114 { 115 return WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer uniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> { 116 return { WHLSL::UniformBufferBinding { uniformBuffer.internalLengthName } }; 117 }, [&](GPUBindGroupLayout::DynamicUniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> { 125 118 return WTF::nullopt; 126 } 119 }, [&](GPUBindGroupLayout::Sampler) -> Optional<WHLSL::Binding::BindingDetails> { 120 return { WHLSL::SamplerBinding { } }; 121 }, [&](GPUBindGroupLayout::SampledTexture) -> Optional<WHLSL::Binding::BindingDetails> { 122 return { WHLSL::TextureBinding { } }; 123 }, [&](GPUBindGroupLayout::StorageBuffer storageBuffer) -> Optional<WHLSL::Binding::BindingDetails> { 124 return { WHLSL::StorageBufferBinding { storageBuffer.internalLengthName } }; 125 }, [&](GPUBindGroupLayout::DynamicStorageBuffer) -> Optional<WHLSL::Binding::BindingDetails> { 126 return WTF::nullopt; 127 }), internalBindingDetails); 127 128 } 128 129 … … 378 379 bindGroup.name = static_cast<unsigned>(i); 379 380 for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) { 380 const auto& gpuBindGroupLayoutBinding= keyValuePair.value;381 const auto& bindingDetails = keyValuePair.value; 381 382 WHLSL::Binding binding; 382 binding.visibility = convertShaderStageFlags( gpuBindGroupLayoutBinding.visibility);383 if (auto bindingType = convertBindingType( gpuBindGroupLayoutBinding.type))384 binding.binding Type= *bindingType;383 binding.visibility = convertShaderStageFlags(bindingDetails.externalBinding.visibility); 384 if (auto bindingType = convertBindingType(bindingDetails.internalBindingDetails)) 385 binding.binding = *bindingType; 385 386 else 386 387 return WTF::nullopt; 387 if ( gpuBindGroupLayoutBinding.binding > std::numeric_limits<unsigned>::max())388 if (bindingDetails.externalBinding.binding > std::numeric_limits<unsigned>::max()) 388 389 return WTF::nullopt; 389 binding.name = static_cast<unsigned>(gpuBindGroupLayoutBinding.binding); 390 binding.externalName = bindingDetails.externalBinding.binding; 391 binding.internalName = bindingDetails.internalName; 390 392 bindGroup.bindings.append(WTFMove(binding)); 391 393 }
Note:
See TracChangeset
for help on using the changeset viewer.