Changeset 241996 in webkit
- Timestamp:
- Feb 23, 2019 3:24:27 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 2 deleted
- 24 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r241989 r241996 1 2019-02-23 Justin Fan <justin_fan@apple.com> 2 3 [WebGPU] Buffer updates part 1: async mapping functions, unmap, and destroy 4 https://bugs.webkit.org/show_bug.cgi?id=194665 5 6 Reviewed by Dean Jackson. 7 8 Rewrite buffers.html -> map-write-buffers.html to test new functionality. Rewrite other affected 9 tests to use mapWriteAsync. 10 11 * webgpu/buffer-resource-triangles.html: 12 * webgpu/buffers-expected.txt: Renamed to map-write-buffers-expected.txt. 13 * webgpu/buffers.html: Renamed to map-write-buffers.html. 14 * webgpu/depth-enabled-triangle-strip.html: 15 * webgpu/map-write-buffers-expected.txt: Renamed from buffers-expected.txt. 16 * webgpu/map-write-buffers.html: Renamed from buffers.html. 17 * webgpu/vertex-buffer-triangle-strip.html: 18 19 * platform/mac/TestExpectations: Skip all webgpu tests on macOS 10.12 bots. 20 1 21 2019-02-23 chris fleizach <cfleizach@apple.com> 2 22 -
trunk/LayoutTests/platform/mac/TestExpectations
r241219 r241996 1786 1786 webkit.org/b/190976 imported/w3c/web-platform-tests/media-source/mediasource-changetype-play.html [ Pass Failure ] 1787 1787 1788 webkit.org/b/192956 [ Sierra ] webgpu/buffers.html [ Skip ] 1789 webkit.org/b/192956 [ Sierra ] webgpu/command-buffers.html [ Skip ] 1790 webkit.org/b/192956 [ Sierra ] webgpu/pipeline-layouts.html [ Skip ] 1791 webkit.org/b/192956 [ Sierra ] webgpu/queue-creation.html [ Skip ] 1792 webkit.org/b/192956 [ Sierra ] webgpu/render-command-encoding.html [ Skip ] 1793 webkit.org/b/192956 [ Sierra ] webgpu/render-passes.html [ Skip ] 1794 webkit.org/b/192956 [ Sierra ] webgpu/render-pipelines.html [ Skip ] 1795 webkit.org/b/192956 [ Sierra ] webgpu/shader-modules.html [ Skip ] 1796 webkit.org/b/192956 [ Sierra ] webgpu/textures-textureviews.html [ Skip ] 1797 webkit.org/b/192956 [ Sierra ] webgpu/webgpu-basics.html [ Skip ] 1798 webkit.org/b/192956 [ Sierra ] webgpu/webgpu-enabled.html [ Skip ] 1799 webkit.org/b/192956 [ Sierra ] webgpu/simple-triangle-strip.html [ Skip ] 1800 webkit.org/b/192956 [ Sierra ] webgpu/vertex-buffer-triangle-strip.html [ Skip ] 1788 webkit.org/b/192956 [ Sierra ] webgpu [ Skip ] 1801 1789 1802 1790 webkit.org/b/189680 platform/mac/media/audio-session-category-video-paused.html [ Pass Timeout ] -
trunk/LayoutTests/webgpu/buffer-resource-triangles.html
r241328 r241996 80 80 const vertexSize = 4 * 4; 81 81 const verticesBufferSize = vertexSize * 3; 82 83 // FIXME: Keep up to date with buffer upload decisions. 84 function createVerticesBuffer(device) { 85 const buffer = device.createBuffer({ size:verticesBufferSize, usage: GPUBufferUsage.VERTEX });86 87 const vertices =[88 0, 1, 0, 1,89 -1, -1, 0, 1,90 1, -1, 0, 191 ];92 93 const mappedArray = new Float32Array(buffer.mapping);94 mappedArray.set(vertices); 95 82 function createAndUploadVerticesBuffer(device, promises) { 83 const buffer = device.createBuffer({ size:verticesBufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }); 84 85 const promise = buffer.mapWriteAsync().then(mapping => { 86 const mappedArray = new Float32Array(mapping); 87 mappedArray.set([ 88 0, 1, 0, 1, 89 -1, -1, 0, 1, 90 1, -1, 0, 1 91 ]); 92 buffer.unmap(); 93 }); 94 95 promises.push(promise); 96 96 return buffer; 97 97 } 98 98 99 function createFloat4Buffer(device, a, b) { 100 const buffer = device.createBuffer({ size: vertexSize, usage: GPUBufferUsage.UNIFORM }); 101 102 const arrayBuffer = buffer.mapping; 103 const floatArray = new Float32Array(arrayBuffer); 104 105 floatArray[0] = a; 106 floatArray[1] = b; 107 floatArray[2] = 0; 108 floatArray[3] = 1; 109 99 function createFloat4Buffer(device, a, b, promises) { 100 const buffer = device.createBuffer({ size: vertexSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE }); 101 102 const promise = buffer.mapWriteAsync().then(mapping => { 103 const mappedArray = new Float32Array(mapping); 104 mappedArray.set([a, b, 0, 1]); 105 buffer.unmap(); 106 }); 107 108 promises.push(promise); 110 109 return buffer; 111 110 } … … 127 126 128 127 // Create vertex data WebGPUBuffers. 129 const verticesBuffer = createVerticesBuffer(device); 130 131 const upperLeft = createFloat4Buffer(device, -1, 1); 132 const upperMiddle = createFloat4Buffer(device, 0, 1); 133 const upperRight = createFloat4Buffer(device, 1, 1); 134 const lowerLeft = createFloat4Buffer(device, -1, -1); 135 const lowerRight = createFloat4Buffer(device, 1, -1); 128 let bufferPromises = []; 129 130 const verticesBuffer = createAndUploadVerticesBuffer(device, bufferPromises); 131 132 const upperLeft = createFloat4Buffer(device, -1, 1, bufferPromises); 133 const upperMiddle = createFloat4Buffer(device, 0, 1, bufferPromises); 134 const upperRight = createFloat4Buffer(device, 1, 1, bufferPromises); 135 const lowerLeft = createFloat4Buffer(device, -1, -1, bufferPromises); 136 const lowerRight = createFloat4Buffer(device, 1, -1, bufferPromises); 136 137 137 138 // Color data buffer. 138 const green = createFloat4Buffer(device, 0, 1 );139 const green = createFloat4Buffer(device, 0, 1, bufferPromises); 139 140 140 141 // Create vertex input state. … … 196 197 }); 197 198 198 const commandBuffer = device.createCommandBuffer(); 199 const passEncoder = beginBasicRenderPass(context, commandBuffer); 200 passEncoder.setPipeline(pipeline); 201 202 // Vertex data for upper triangles. 203 passEncoder.setBindGroup(0, leftTriangleBG); 204 passEncoder.setBindGroup(1, rightTriangleBG); 205 // Lower triangle. 206 passEncoder.setVertexBuffers(0, [verticesBuffer], [0]); 207 passEncoder.draw(9, 1, 0, 0); 208 209 const endCommandBuffer = passEncoder.endPass(); 210 const queue = device.getQueue(); 211 queue.submit([endCommandBuffer]); 212 context.present(); 199 Promise.all(bufferPromises).then(() => { 200 const commandBuffer = device.createCommandBuffer(); 201 const passEncoder = beginBasicRenderPass(context, commandBuffer); 202 passEncoder.setPipeline(pipeline); 203 204 // Vertex data for upper triangles. 205 passEncoder.setBindGroup(0, leftTriangleBG); 206 passEncoder.setBindGroup(1, rightTriangleBG); 207 // Lower triangle. 208 passEncoder.setVertexBuffers(0, [verticesBuffer], [0]); 209 passEncoder.draw(9, 1, 0, 0); 210 211 const endCommandBuffer = passEncoder.endPass(); 212 const queue = device.getQueue(); 213 queue.submit([endCommandBuffer]); 214 context.present(); 215 }); 213 216 } 214 217 -
trunk/LayoutTests/webgpu/depth-enabled-triangle-strip.html
r241328 r241996 45 45 ` 46 46 47 function createVertexBuffer(device) {47 async function createVertexBuffer(device) { 48 48 const bufferSize = 4 * 4 * 4; 49 const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage. MAP_WRITE });49 const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }); 50 50 51 51 let floatArray = new Float32Array(buffer.mapping); 52 53 const vertices = [ 54 // float4 xyzw 55 -1, 1, 0, 1, 56 -1, -1, 0, 1, 57 1, 1, 0, 1, 58 1, -1, 0, 1 59 ]; 60 61 floatArray.set(vertices); 52 await buffer.mapWriteAsync().then(mapping => { 53 let mappedArray = new Float32Array(mapping); 54 mappedArray.set([ 55 // float4 xyzw 56 -1, 1, 0, 1, 57 -1, -1, 0, 1, 58 1, 1, 0, 1, 59 1, -1, 0, 1 60 ]); 61 buffer.unmap(); 62 }); 62 63 63 64 return buffer; … … 87 88 // FIXME: Replace with non-MSL shaders. 88 89 const shaderModule = device.createShaderModule({ code: shaderCode }); 89 const vertexBuffer = createVertexBuffer(device);90 const vertexBuffer = await createVertexBuffer(device); 90 91 const inputStateDescriptor = createInputStateDescriptor(); 91 92 const depthStateDescriptor = createBasicDepthStateDescriptor(); -
trunk/LayoutTests/webgpu/vertex-buffer-triangle-strip.html
r241328 r241996 39 39 ` 40 40 41 function createVertexBuffer(device) {41 async function createVertexBuffer(device) { 42 42 const bufferSize = 4 * 5 * 4; 43 const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage. MAP_WRITE });43 const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }); 44 44 45 let floatArray = new Float32Array(buffer.mapping); 46 47 const vertices = [ 48 // float4 xyzw, float g 49 -1, 1, 0, 1, 1, 50 -1, -1, 0, 1, 1, 51 1, 1, 0, 1, 1, 52 1, -1, 0, 1, 1 53 ]; 54 55 for (let i = 0; i < vertices.length; ++i) { 56 floatArray[i] = vertices[i]; 57 } 45 await buffer.mapWriteAsync().then(mapping => { 46 let mappedArray = new Float32Array(mapping); 47 mappedArray.set([ 48 // float4 xyzw, float g 49 -1, 1, 0, 1, 1, 50 -1, -1, 0, 1, 1, 51 1, 1, 0, 1, 1, 52 1, -1, 0, 1, 1 53 ]); 54 buffer.unmap(); 55 }); 58 56 59 57 return buffer; … … 88 86 // FIXME: Replace with non-MSL shaders. 89 87 const shaderModule = device.createShaderModule({ code: shaderCode }); 90 const vertexBuffer = createVertexBuffer(device);88 const vertexBuffer = await createVertexBuffer(device); 91 89 const inputStateDescriptor = createInputStateDescriptor(); 92 90 const pipeline = createBasicPipeline(shaderModule, device, null, inputStateDescriptor); -
trunk/Source/WebCore/ChangeLog
r241990 r241996 1 2019-02-23 Justin Fan <justin_fan@apple.com> 2 3 [WebGPU] Buffer updates part 1: async mapping functions, unmap, and destroy 4 https://bugs.webkit.org/show_bug.cgi?id=194665 5 6 Reviewed by Dean Jackson. 7 8 Test: map-write-buffers.html. Other tests updated to match new API. 9 10 * Modules/webgpu/WebGPUBindGroupDescriptor.cpp: Added. 11 (WebCore::validateBufferBindingType): Ensure buffer binding usages match the binding type. 12 (WebCore::WebGPUBindGroupDescriptor::asGPUBindGroupDescriptor const): Logic moved out from WebGPUDevice.cpp. 13 * Modules/webgpu/WebGPUBindGroupDescriptor.h: 14 * Modules/webgpu/WebGPUBuffer.cpp: Added GPUBuffer functionality. 15 (WebCore::WebGPUBuffer::create): 16 (WebCore::WebGPUBuffer::WebGPUBuffer): 17 (WebCore::WebGPUBuffer::mapReadAsync): 18 (WebCore::WebGPUBuffer::mapWriteAsync): 19 (WebCore::WebGPUBuffer::unmap): 20 (WebCore::WebGPUBuffer::destroy): 21 (WebCore::WebGPUBuffer::rejectOrRegisterPromiseCallback): Register a mapping request on the GPUBuffer, if valid. 22 * Modules/webgpu/WebGPUBuffer.h: 23 (WebCore::WebGPUBuffer::buffer const): 24 (WebCore::WebGPUBuffer::mapping const): Deleted. 25 * Modules/webgpu/WebGPUBuffer.idl: Update to latest API and enable every function except setSubData. 26 * Modules/webgpu/WebGPUCommandBuffer.cpp: 27 (WebCore::WebGPUCommandBuffer::beginRenderPass): Renamed descriptor conversion method. 28 * Modules/webgpu/WebGPUDevice.cpp: 29 (WebCore::WebGPUDevice::createBuffer const): Update to non-nullable return type. 30 (WebCore::WebGPUDevice::createBindGroup const): Move descriptor validation logic to descriptor implementation. 31 * Modules/webgpu/WebGPUDevice.h: 32 * Modules/webgpu/WebGPURenderPassDescriptor.cpp: 33 (WebCore::WebGPURenderPassDescriptor::asGPURenderPassDescriptor const): Renamed from validateAndConvertToGPUVersion. 34 * Modules/webgpu/WebGPURenderPassEncoder.cpp: 35 (WebCore::WebGPURenderPassEncoder::setVertexBuffers): Add validation for submitted buffers. 36 * platform/graphics/gpu/GPUBuffer.cpp: Added. 37 (WebCore::GPUBuffer::PendingMappingCallback::PendingMappingCallback): New struct for retaining a reference to mapping callbacks. 38 * platform/graphics/gpu/GPUBuffer.h: Add functionality to retain callbacks and usage bits. 39 (WebCore::GPUBuffer::isVertex const): 40 (WebCore::GPUBuffer::isUniform const): 41 (WebCore::GPUBuffer::isStorage const): 42 (WebCore::GPUBuffer::isReadOnly const): 43 (WebCore::GPUBuffer::PendingMapPromise::create): 44 (WebCore::GPUBuffer::isMappable const): 45 (WebCore::GPUBuffer::isMapWriteable const): 46 (WebCore::GPUBuffer::isMapReadable const): 47 (WebCore::GPUBuffer::mapping const): Deleted. 48 * platform/graphics/gpu/GPUBufferUsage.h: enum class cannot be logical ORed together. 49 * platform/graphics/gpu/GPUDevice.cpp: 50 (WebCore::GPUDevice::tryCreateBuffer const): Renamed from createBuffer. 51 (WebCore::GPUDevice::createBuffer const): Deleted. 52 * platform/graphics/gpu/GPUDevice.h: 53 * platform/graphics/gpu/cocoa/GPUBufferMetal.mm: 54 (WebCore::GPUBuffer::tryCreateSharedBuffer): Attempt to create a MTLBuffer with shared memory. 55 (WebCore::GPUBuffer::tryCreate): No longer use Gigacage-allocated memory for MTLBuffer. 56 (WebCore::GPUBuffer::GPUBuffer): 57 (WebCore::GPUBuffer::~GPUBuffer): 58 (WebCore::GPUBuffer::registerMappingCallback): Register the provided callback to be executed when the staging buffer can be safely exposed. 59 (WebCore::GPUBuffer::stagingBufferForRead): Prepare the arrayBuffer for reading and run the mapping callback. 60 (WebCore::GPUBuffer::stagingBufferForWrite): Ditto, but for writing. 61 (WebCore::GPUBuffer::unmap): If needed, copy the staging ArrayBuffer to the MTLBuffer. Unregister any mapping callback. 62 (WebCore::GPUBuffer::destroy): Stub implementation for now. Frees the MTLBuffer as soon as possible. 63 (WebCore::GPUBuffer::create): Deleted. 64 * platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm: 65 (WebCore::GPUProgrammablePassEncoder::setResourceAsBufferOnEncoder): Ensure only read-only GPUBuffers are used as read-only on the GPU. 66 67 Add symbols for new files: 68 * Sources.txt: 69 * WebCore.xcodeproj/project.pbxproj: 70 1 71 2019-02-23 Keith Miller <keith_miller@apple.com> 2 72 -
trunk/Source/WebCore/Modules/webgpu/WebGPUBindGroupDescriptor.h
r239837 r241996 30 30 #include "WebGPUBindGroupBinding.h" 31 31 #include "WebGPUBindGroupLayout.h" 32 #include <wtf/Optional.h> 32 33 #include <wtf/RefPtr.h> 33 34 #include <wtf/Vector.h> … … 35 36 namespace WebCore { 36 37 38 struct GPUBindGroupDescriptor; 39 37 40 struct WebGPUBindGroupDescriptor { 41 Optional<GPUBindGroupDescriptor> asGPUBindGroupDescriptor() const; 42 38 43 RefPtr<WebGPUBindGroupLayout> layout; 39 44 Vector<WebGPUBindGroupBinding> bindings; -
trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp
r239535 r241996 29 29 #if ENABLE(WEBGPU) 30 30 31 #include "Logging.h" 32 31 33 namespace WebCore { 32 34 33 Ref<WebGPUBuffer> WebGPUBuffer::create(Ref <GPUBuffer>&& buffer)35 Ref<WebGPUBuffer> WebGPUBuffer::create(RefPtr<GPUBuffer>&& buffer) 34 36 { 35 37 return adoptRef(*new WebGPUBuffer(WTFMove(buffer))); 36 38 } 37 39 38 WebGPUBuffer::WebGPUBuffer(Ref <GPUBuffer>&& buffer)40 WebGPUBuffer::WebGPUBuffer(RefPtr<GPUBuffer>&& buffer) 39 41 : m_buffer(WTFMove(buffer)) 40 42 { 43 } 44 45 void WebGPUBuffer::mapReadAsync(BufferMappingPromise&& promise) 46 { 47 rejectOrRegisterPromiseCallback(WTFMove(promise), true); 48 } 49 50 void WebGPUBuffer::mapWriteAsync(BufferMappingPromise&& promise) 51 { 52 rejectOrRegisterPromiseCallback(WTFMove(promise), false); 53 } 54 55 void WebGPUBuffer::unmap() 56 { 57 if (m_buffer) 58 m_buffer->unmap(); 59 } 60 61 void WebGPUBuffer::destroy() 62 { 63 if (!m_buffer) 64 LOG(WebGPU, "GPUBuffer::destroy(): Invalid operation!"); 65 else { 66 m_buffer->destroy(); 67 // FIXME: Ensure that GPUBuffer is kept alive by resource bindings if still being used by GPU. 68 m_buffer = nullptr; 69 } 70 } 71 72 void WebGPUBuffer::rejectOrRegisterPromiseCallback(BufferMappingPromise&& promise, bool isRead) 73 { 74 if (!m_buffer) { 75 LOG(WebGPU, "GPUBuffer::map%sAsync(): Invalid operation!", isRead ? "Read" : "Write"); 76 promise.reject(); 77 return; 78 } 79 80 m_buffer->registerMappingCallback([promise = WTFMove(promise)] (JSC::ArrayBuffer* arrayBuffer) mutable { 81 if (!arrayBuffer) { 82 promise.reject(); 83 return; 84 } 85 86 promise.resolve(arrayBuffer); 87 }, isRead); 41 88 } 42 89 -
trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.h
r239535 r241996 29 29 30 30 #include "GPUBuffer.h" 31 31 #include "GPUBufferUsage.h" 32 #include "JSDOMPromiseDeferred.h" 32 33 #include <wtf/RefCounted.h> 33 34 #include <wtf/RefPtr.h> 34 35 36 namespace JSC { 37 class ArrayBuffer; 38 } 39 35 40 namespace WebCore { 41 42 struct GPUBufferDescriptor; 36 43 37 44 class WebGPUBuffer : public RefCounted<WebGPUBuffer> { 38 45 public: 39 static Ref<WebGPUBuffer> create(Ref <GPUBuffer>&&);46 static Ref<WebGPUBuffer> create(RefPtr<GPUBuffer>&&); 40 47 41 const GPUBuffer& buffer() const { return m_buffer.get(); }48 RefPtr<const GPUBuffer> buffer() const { return m_buffer; } 42 49 43 JSC::ArrayBuffer* mapping() const { return m_buffer->mapping(); } 44 void unmap() { /* FIXME: Unimplemented stub. */ } 45 void destroy() { /* FIXME: Unimplemented stub. */ } 50 using BufferMappingPromise = DOMPromiseDeferred<IDLInterface<JSC::ArrayBuffer*>>; 51 void mapReadAsync(BufferMappingPromise&&); 52 void mapWriteAsync(BufferMappingPromise&&); 53 void unmap(); 54 void destroy(); 46 55 47 56 private: 48 explicit WebGPUBuffer(Ref <GPUBuffer>&&);57 explicit WebGPUBuffer(RefPtr<GPUBuffer>&&); 49 58 50 Ref<GPUBuffer> m_buffer; 59 void rejectOrRegisterPromiseCallback(BufferMappingPromise&&, bool); 60 61 RefPtr<GPUBuffer> m_buffer; 51 62 }; 52 63 -
trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.idl
r239094 r241996 29 29 ImplementationLacksVTable 30 30 ] interface WebGPUBuffer { 31 readonly attribute ArrayBuffer? mapping; 31 //void setSubData(u32 offset, ArrayBuffer data); 32 33 Promise<ArrayBuffer> mapReadAsync(); 34 Promise<ArrayBuffer> mapWriteAsync(); 32 35 void unmap(); 33 36 -
trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.cpp
r241310 r241996 48 48 RefPtr<WebGPURenderPassEncoder> WebGPUCommandBuffer::beginRenderPass(WebGPURenderPassDescriptor&& descriptor) 49 49 { 50 auto gpuDescriptor = descriptor. validateAndConvertToGPUVersion();50 auto gpuDescriptor = descriptor.asGPURenderPassDescriptor(); 51 51 if (!gpuDescriptor) 52 52 return nullptr; -
trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp
r241328 r241996 56 56 #include "WebGPUShaderModuleDescriptor.h" 57 57 #include "WebGPUTexture.h" 58 #include <wtf/Variant.h>59 58 60 59 namespace WebCore { … … 74 73 } 75 74 76 Ref Ptr<WebGPUBuffer> WebGPUDevice::createBuffer(GPUBufferDescriptor&& descriptor) const75 Ref<WebGPUBuffer> WebGPUDevice::createBuffer(GPUBufferDescriptor&& descriptor) const 77 76 { 78 if (auto buffer = m_device->createBuffer(WTFMove(descriptor))) 79 return WebGPUBuffer::create(buffer.releaseNonNull()); 80 return nullptr; 77 auto buffer = m_device->tryCreateBuffer(WTFMove(descriptor)); 78 return WebGPUBuffer::create(WTFMove(buffer)); 81 79 } 82 80 … … 105 103 Ref<WebGPUBindGroup> WebGPUDevice::createBindGroup(WebGPUBindGroupDescriptor&& descriptor) const 106 104 { 107 if (!descriptor.layout || !descriptor.layout->bindGroupLayout()) {108 LOG(WebGPU, "WebGPUDevice::createBindGroup(): Invalid WebGPUBindGroupLayout!");105 auto gpuDescriptor = descriptor.asGPUBindGroupDescriptor(); 106 if (!gpuDescriptor) 109 107 return WebGPUBindGroup::create(nullptr); 110 }111 108 112 if (descriptor.bindings.size() != descriptor.layout->bindGroupLayout()->bindingsMap().size()) { 113 LOG(WebGPU, "WebGPUDevice::createBindGroup(): Mismatched number of WebGPUBindGroupLayoutBindings and WebGPUBindGroupBindings!"); 114 return WebGPUBindGroup::create(nullptr); 115 } 116 117 auto bindingResourceVisitor = WTF::makeVisitor([] (RefPtr<WebGPUTextureView> view) -> Optional<GPUBindingResource> { 118 if (view) 119 return static_cast<GPUBindingResource>(view->texture()); 120 return WTF::nullopt; 121 }, [] (const WebGPUBufferBinding& binding) -> Optional<GPUBindingResource> { 122 if (binding.buffer) 123 return static_cast<GPUBindingResource>(GPUBufferBinding { binding.buffer->buffer(), binding.offset, binding.size }); 124 return WTF::nullopt; 125 }); 126 127 Vector<GPUBindGroupBinding> bindGroupBindings; 128 bindGroupBindings.reserveCapacity(descriptor.bindings.size()); 129 130 for (const auto& binding : descriptor.bindings) { 131 if (!descriptor.layout->bindGroupLayout()->bindingsMap().contains(binding.binding)) { 132 LOG(WebGPU, "WebGPUDevice::createBindGroup(): WebGPUBindGroupBinding %lu not found in WebGPUBindGroupLayout!", binding.binding); 133 return WebGPUBindGroup::create(nullptr); 134 } 135 136 auto bindingResource = WTF::visit(bindingResourceVisitor, binding.resource); 137 if (bindingResource) 138 bindGroupBindings.uncheckedAppend(GPUBindGroupBinding { binding.binding, WTFMove(bindingResource.value()) }); 139 else { 140 LOG(WebGPU, "WebGPUDevice::createBindGroup(): Invalid WebGPUBindingResource for binding %lu in WebGPUBindGroupBindings!", binding.binding); 141 return WebGPUBindGroup::create(nullptr); 142 } 143 } 144 auto bindGroup = GPUBindGroup::create(GPUBindGroupDescriptor { descriptor.layout->bindGroupLayout().releaseNonNull(), WTFMove(bindGroupBindings) }); 109 auto bindGroup = GPUBindGroup::create(WTFMove(*gpuDescriptor)); 145 110 return WebGPUBindGroup::create(WTFMove(bindGroup)); 146 111 } -
trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.h
r241328 r241996 63 63 const GPUDevice& device() const { return m_device.get(); } 64 64 65 Ref Ptr<WebGPUBuffer> createBuffer(GPUBufferDescriptor&&) const;65 Ref<WebGPUBuffer> createBuffer(GPUBufferDescriptor&&) const; 66 66 Ref<WebGPUTexture> createTexture(GPUTextureDescriptor&&) const; 67 67 -
trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassDescriptor.cpp
r241310 r241996 46 46 } 47 47 48 Optional<GPURenderPassDescriptor> WebGPURenderPassDescriptor:: validateAndConvertToGPUVersion() const48 Optional<GPURenderPassDescriptor> WebGPURenderPassDescriptor::asGPURenderPassDescriptor() const 49 49 { 50 50 // FIXME: Improve error checking as WebGPURenderPassDescriptor is added to spec. -
trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassDescriptor.h
r241310 r241996 47 47 48 48 struct WebGPURenderPassDescriptor { 49 Optional<GPURenderPassDescriptor> validateAndConvertToGPUVersion() const;49 Optional<GPURenderPassDescriptor> asGPURenderPassDescriptor() const; 50 50 51 51 Vector<WebGPURenderPassColorAttachmentDescriptor> colorAttachments; -
trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp
r240898 r241996 50 50 void WebGPURenderPassEncoder::setVertexBuffers(unsigned long startSlot, Vector<RefPtr<WebGPUBuffer>>&& buffers, Vector<unsigned long long>&& offsets) 51 51 { 52 #if !LOG_DISABLED 53 const char* const functionName = "GPURenderPassEncoder::setVertexBuffers()"; 54 #endif 52 55 if (buffers.isEmpty() || buffers.size() != offsets.size()) { 53 LOG(WebGPU, " WebGPURenderPassEncoder::setVertexBuffers: Invalid number of buffers or offsets!");56 LOG(WebGPU, "%s: Invalid number of buffers or offsets!", functionName); 54 57 return; 55 58 } 56 59 57 60 if (startSlot + buffers.size() > maxVertexBuffers) { 58 LOG(WebGPU, " WebGPURenderPassEncoder::setVertexBuffers: Invalid startSlot %lu for %lu buffers!", startSlot, buffers.size());61 LOG(WebGPU, "%s: Invalid startSlot %lu for %lu buffers!", functionName, startSlot, buffers.size()); 59 62 return; 60 63 } 61 64 62 auto gpuBuffers = buffers.map([] (const auto& buffer) -> Ref<const GPUBuffer> { 63 return buffer->buffer(); 64 }); 65 Vector<Ref<const GPUBuffer>> gpuBuffers; 66 gpuBuffers.reserveCapacity(buffers.size()); 67 68 for (const auto& buffer : buffers) { 69 if (!buffer || !buffer->buffer()) { 70 LOG(WebGPU, "%s: Invalid or destroyed buffer in list!", functionName); 71 return; 72 } 73 74 if (!buffer->buffer()->isVertex()) { 75 LOG(WebGPU, "%s: Buffer was not created with VERTEX usage!", functionName); 76 return; 77 } 78 79 gpuBuffers.uncheckedAppend(buffer->buffer().releaseNonNull()); 80 } 65 81 66 82 m_passEncoder->setVertexBuffers(startSlot, WTFMove(gpuBuffers), WTFMove(offsets)); -
trunk/Source/WebCore/Sources.txt
r241328 r241996 349 349 Modules/webgpu/WebGPU.cpp 350 350 Modules/webgpu/WebGPUBindGroup.cpp 351 Modules/webgpu/WebGPUBindGroupDescriptor.cpp 351 352 Modules/webgpu/WebGPUAdapter.cpp 352 353 Modules/webgpu/WebGPUBindGroupLayout.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r241841 r241996 4256 4256 D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */; }; 4257 4257 D07DEABA0A36554A00CA30F8 /* InsertListCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */; }; 4258 D084033C221CBF6900007205 /* GPUBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D084033A221CBF5400007205 /* GPUBuffer.cpp */; }; 4258 4259 D0843A4B20FEBE3D00FE860E /* GraphicsContext3DManager.h in Headers */ = {isa = PBXBuildFile; fileRef = D0843A4A20FEBE3D00FE860E /* GraphicsContext3DManager.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4259 4260 D086FE9809D53AAB005BC74D /* UnlinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D086FE9609D53AAB005BC74D /* UnlinkCommand.h */; }; … … 14076 14077 D083D98421C48050008E8EFF /* GPUBindGroupLayoutDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUBindGroupLayoutDescriptor.h; sourceTree = "<group>"; }; 14077 14078 D083D98621C4813E008E8EFF /* WebGPUBindGroupLayoutDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebGPUBindGroupLayoutDescriptor.h; path = Modules/streams/WebGPUBindGroupLayoutDescriptor.h; sourceTree = SOURCE_ROOT; }; 14079 D084033A221CBF5400007205 /* GPUBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUBuffer.cpp; sourceTree = "<group>"; }; 14080 D084033D221E186400007205 /* WebGPUBindGroupDescriptor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebGPUBindGroupDescriptor.cpp; sourceTree = "<group>"; }; 14078 14081 D0843A4A20FEBE3D00FE860E /* GraphicsContext3DManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContext3DManager.h; sourceTree = "<group>"; }; 14079 14082 D0843A4C20FEC16500FE860E /* GraphicsContext3DManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3DManager.cpp; sourceTree = "<group>"; }; … … 18482 18485 D0B8BB0121C46E78000C7681 /* GPUBindGroupLayoutBinding.h */, 18483 18486 D083D98421C48050008E8EFF /* GPUBindGroupLayoutDescriptor.h */, 18487 D084033A221CBF5400007205 /* GPUBuffer.cpp */, 18484 18488 D0D8649221B760F2003C983C /* GPUBuffer.h */, 18485 18489 D0BE104A21E6872F00E42A89 /* GPUBufferBinding.h */, … … 26108 26112 D0BE104F21E69F8300E42A89 /* WebGPUBindGroupBinding.h */, 26109 26113 D0BE105021E69F8300E42A89 /* WebGPUBindGroupBinding.idl */, 26114 D084033D221E186400007205 /* WebGPUBindGroupDescriptor.cpp */, 26110 26115 D0BE105221E6AA0D00E42A89 /* WebGPUBindGroupDescriptor.h */, 26111 26116 D0BE105321E6AA0D00E42A89 /* WebGPUBindGroupDescriptor.idl */, … … 32946 32951 515BE1911D54F5FB00DD7C68 /* GamepadProvider.cpp in Sources */, 32947 32952 837964CF1F8DB69D00218EA0 /* GeolocationPositionIOS.mm in Sources */, 32953 D084033C221CBF6900007205 /* GPUBuffer.cpp in Sources */, 32948 32954 6E21C6C01126338500A7BE02 /* GraphicsContext3D.cpp in Sources */, 32949 32955 7C3E510B18DF8F3500C112F7 /* HTMLConverter.mm in Sources */, -
trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.cpp
r241995 r241996 24 24 */ 25 25 26 #pragma once 26 #include "config.h" 27 #include "GPUBuffer.h" 27 28 28 29 #if ENABLE(WEBGPU) 29 30 30 #include "WebGPUBindGroupBinding.h"31 #include "WebGPUBindGroupLayout.h"32 #include <wtf/RefPtr.h>33 #include <wtf/Vector.h>34 35 31 namespace WebCore { 36 32 37 struct WebGPUBindGroupDescriptor { 38 RefPtr<WebGPUBindGroupLayout> layout;39 Vector<WebGPUBindGroupBinding> bindings; 40 } ;33 GPUBuffer::PendingMappingCallback::PendingMappingCallback(MappingCallback&& pending) 34 : callback(WTFMove(pending)) 35 { 36 } 41 37 42 38 } // namespace WebCore -
trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h
r239094 r241996 28 28 #if ENABLE(WEBGPU) 29 29 30 #include "DeferrableTask.h" 31 #include "GPUBufferUsage.h" 32 #include <wtf/Function.h> 30 33 #include <wtf/Ref.h> 31 34 #include <wtf/RefCounted.h> … … 51 54 ~GPUBuffer(); 52 55 53 static RefPtr<GPUBuffer> create(const GPUDevice&, GPUBufferDescriptor&&);56 static RefPtr<GPUBuffer> tryCreate(const GPUDevice&, GPUBufferDescriptor&&); 54 57 55 58 PlatformBuffer *platformBuffer() const { return m_platformBuffer.get(); } 59 bool isVertex() const { return m_isVertex; } 60 bool isUniform() const { return m_isUniform; } 61 bool isStorage() const { return m_isStorage; } 62 bool isReadOnly() const { return m_isReadOnly; } 56 63 57 JSC::ArrayBuffer* mapping() const { return m_mapping.get(); } 64 using MappingCallback = WTF::Function<void(JSC::ArrayBuffer*)>; 65 void registerMappingCallback(MappingCallback&&, bool); 66 void unmap(); 67 void destroy(); 58 68 59 69 private: 60 explicit GPUBuffer(PlatformBufferSmartPtr&&, RefPtr<JSC::ArrayBuffer>&&); 70 struct PendingMappingCallback : public RefCounted<PendingMappingCallback> { 71 static Ref<PendingMappingCallback> create(MappingCallback&& callback) 72 { 73 return adoptRef(*new PendingMappingCallback(WTFMove(callback))); 74 } 75 76 MappingCallback callback; 77 78 private: 79 PendingMappingCallback(MappingCallback&&); 80 }; 81 82 GPUBuffer(PlatformBufferSmartPtr&&, const GPUBufferDescriptor&); 83 84 static RefPtr<GPUBuffer> tryCreateSharedBuffer(const GPUDevice&, const GPUBufferDescriptor&); 85 JSC::ArrayBuffer* stagingBufferForRead(); 86 JSC::ArrayBuffer* stagingBufferForWrite(); 87 88 bool isMappable() const { return m_isMapWrite || m_isMapRead; } 89 bool isMapWriteable() const { return m_isMapWrite && !m_pendingCallback; } 90 bool isMapReadable() const { return m_isMapRead && !m_pendingCallback; } 61 91 62 92 PlatformBufferSmartPtr m_platformBuffer; 63 RefPtr<JSC::ArrayBuffer> m_mapping; 93 94 RefPtr<JSC::ArrayBuffer> m_stagingBuffer; 95 RefPtr<PendingMappingCallback> m_pendingCallback; 96 DeferrableTask<Timer> m_mappingCallbackTask; 97 98 unsigned long m_byteLength; 99 unsigned m_numScheduledCommandBuffers = 0; 100 bool m_isMapWrite; 101 bool m_isMapRead; 102 bool m_isDestroyed = false; 103 bool m_isVertex; 104 bool m_isUniform; 105 bool m_isStorage; 106 bool m_isReadOnly; 64 107 }; 65 108 -
trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h
r241328 r241996 36 36 class GPUBufferUsage : public RefCounted<GPUBufferUsage> { 37 37 public: 38 enum classFlags : GPUBufferUsageFlags {38 enum Flags : GPUBufferUsageFlags { 39 39 None = 0, 40 40 MapRead = 1, -
trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp
r241181 r241996 45 45 namespace WebCore { 46 46 47 RefPtr<GPUBuffer> GPUDevice:: createBuffer(GPUBufferDescriptor&& descriptor) const47 RefPtr<GPUBuffer> GPUDevice::tryCreateBuffer(GPUBufferDescriptor&& descriptor) const 48 48 { 49 return GPUBuffer:: create(*this, WTFMove(descriptor));49 return GPUBuffer::tryCreate(*this, WTFMove(descriptor)); 50 50 } 51 51 -
trunk/Source/WebCore/platform/graphics/gpu/GPUDevice.h
r241181 r241996 61 61 static RefPtr<GPUDevice> create(Optional<GPURequestAdapterOptions>&&); 62 62 63 RefPtr<GPUBuffer> createBuffer(GPUBufferDescriptor&&) const;63 RefPtr<GPUBuffer> tryCreateBuffer(GPUBufferDescriptor&&) const; 64 64 RefPtr<GPUTexture> tryCreateTexture(GPUTextureDescriptor&&) const; 65 65 -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm
r239535 r241996 32 32 #import "GPUDevice.h" 33 33 #import "Logging.h" 34 35 #import <Foundation/NSRange.h>36 34 #import <JavaScriptCore/ArrayBuffer.h> 37 35 #import <Metal/Metal.h> 38 #import <wtf/Gigacage.h> 39 #import <wtf/PageBlock.h> 36 #import <wtf/BlockObjCExceptions.h> 40 37 41 38 namespace WebCore { 42 39 43 RefPtr<GPUBuffer> GPUBuffer::create(const GPUDevice& device, GPUBufferDescriptor&& descriptor) 40 RefPtr<GPUBuffer> GPUBuffer::tryCreateSharedBuffer(const GPUDevice& device, const GPUBufferDescriptor& descriptor) 41 { 42 ASSERT(device.platformDevice()); 43 44 RetainPtr<MTLBuffer> mtlBuffer; 45 46 BEGIN_BLOCK_OBJC_EXCEPTIONS; 47 48 mtlBuffer = adoptNS([device.platformDevice() newBufferWithLength:descriptor.size options: MTLResourceCPUCacheModeDefaultCache]); 49 50 END_BLOCK_OBJC_EXCEPTIONS; 51 52 if (!mtlBuffer) { 53 LOG(WebGPU, "GPUBuffer::create(): Unable to create MTLBuffer!"); 54 return nullptr; 55 } 56 57 return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), descriptor)); 58 } 59 60 static const auto readOnlyMask = GPUBufferUsage::Index | GPUBufferUsage::Vertex | GPUBufferUsage::Uniform | GPUBufferUsage::TransferSrc; 61 62 RefPtr<GPUBuffer> GPUBuffer::tryCreate(const GPUDevice& device, GPUBufferDescriptor&& descriptor) 44 63 { 45 64 if (!device.platformDevice()) { … … 48 67 } 49 68 50 size_t pageSize = WTF::pageSize(); 51 size_t pageAlignedSize = roundUpToMultipleOf(pageSize, descriptor.size); 52 void* pageAlignedCopy = Gigacage::tryAlignedMalloc(Gigacage::Primitive, pageSize, pageAlignedSize); 53 if (!pageAlignedCopy) { 54 LOG(WebGPU, "GPUBuffer::create(): Unable to allocate memory!"); 69 if ((descriptor.usage & GPUBufferUsage::MapWrite) && (descriptor.usage & GPUBufferUsage::MapRead)) { 70 LOG(WebGPU, "GPUBuffer::create(): Buffer cannot have both MAP_READ and MAP_WRITE usage!"); 55 71 return nullptr; 56 72 } 57 73 58 auto arrayBuffer = ArrayBuffer::createFromBytes(pageAlignedCopy, descriptor.size, [] (void* ptr) { 59 Gigacage::alignedFree(Gigacage::Primitive, ptr); 60 }); 61 arrayBuffer->ref(); 62 ArrayBuffer* arrayBufferContents = arrayBuffer.ptr(); 63 // FIXME: Default this MTLResourceOptions. 64 PlatformBufferSmartPtr mtlBuffer = adoptNS([device.platformDevice() 65 newBufferWithBytesNoCopy:arrayBuffer->data() 66 length:pageAlignedSize 67 options:MTLResourceCPUCacheModeDefaultCache 68 deallocator:^(void*, NSUInteger) { 69 arrayBufferContents->deref(); 70 }]); 71 72 if (!mtlBuffer) { 73 LOG(WebGPU, "GPUBuffer::create(): Unable to create MTLBuffer!"); 74 arrayBuffer->deref(); 74 if ((descriptor.usage & readOnlyMask) && (descriptor.usage & GPUBufferUsage::Storage)) { 75 LOG(WebGPU, "GPUBuffer::create(): Buffer cannot have both STORAGE and a read-only usage!"); 75 76 return nullptr; 76 77 } 77 78 78 return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(arrayBuffer))); 79 // Mappable buffers need (default) shared storage allocation. 80 if (descriptor.usage & (GPUBufferUsage::MapWrite | GPUBufferUsage::MapRead)) 81 return tryCreateSharedBuffer(device, descriptor); 82 83 LOG(WebGPU, "GPUBuffer::create(): Support for non-mapped buffers not implemented!"); 84 return nullptr; 79 85 } 80 86 81 GPUBuffer::GPUBuffer(PlatformBufferSmartPtr&& platformBuffer, RefPtr<ArrayBuffer>&& arrayBuffer) 82 : m_platformBuffer(WTFMove(platformBuffer)) 83 , m_mapping(WTFMove(arrayBuffer)) 87 GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, const GPUBufferDescriptor& descriptor) 88 : m_platformBuffer(WTFMove(buffer)) 89 , m_byteLength(descriptor.size) 90 , m_isMapWrite(descriptor.usage & GPUBufferUsage::MapWrite) 91 , m_isMapRead(descriptor.usage & GPUBufferUsage::MapRead) 92 , m_isVertex(descriptor.usage & GPUBufferUsage::Vertex) 93 , m_isUniform(descriptor.usage & GPUBufferUsage::Uniform) 94 , m_isStorage(descriptor.usage & GPUBufferUsage::Storage) 95 , m_isReadOnly(descriptor.usage & readOnlyMask) 84 96 { 85 97 } … … 87 99 GPUBuffer::~GPUBuffer() 88 100 { 89 if (m_mapping) { 90 m_mapping->deref(); 91 m_mapping = nullptr; 101 unmap(); 102 } 103 104 void GPUBuffer::registerMappingCallback(MappingCallback&& callback, bool isRead) 105 { 106 // Reject if request is invalid. 107 if (isRead && !isMapReadable()) { 108 LOG(WebGPU, "GPUBuffer::mapReadAsync(): Invalid operation!"); 109 callback(nullptr); 110 return; 92 111 } 112 if (!isRead && !isMapWriteable()) { 113 LOG(WebGPU, "GPUBuffer::mapWriteAsync(): Invalid operation!"); 114 callback(nullptr); 115 return; 116 } 117 118 ASSERT(!m_pendingCallback && !m_mappingCallbackTask.hasPendingTask()); 119 120 // An existing callback means this buffer is in the mapped state. 121 m_pendingCallback = PendingMappingCallback::create(WTFMove(callback)); 122 123 // If GPU is not using this buffer, run the callback ASAP. 124 if (!m_numScheduledCommandBuffers) { 125 m_mappingCallbackTask.scheduleTask([this, protectedThis = makeRef(*this)] () mutable { 126 ASSERT(m_pendingCallback); 127 128 m_pendingCallback->callback(m_isMapRead ? stagingBufferForRead() : stagingBufferForWrite()); 129 }); 130 } 131 } 132 133 JSC::ArrayBuffer* GPUBuffer::stagingBufferForRead() 134 { 135 if (!m_stagingBuffer) 136 m_stagingBuffer = ArrayBuffer::create(m_platformBuffer.get().contents, m_byteLength); 137 else 138 memcpy(m_stagingBuffer->data(), m_platformBuffer.get().contents, m_byteLength); 139 140 return m_stagingBuffer.get(); 141 } 142 143 JSC::ArrayBuffer* GPUBuffer::stagingBufferForWrite() 144 { 145 m_stagingBuffer = ArrayBuffer::create(1, m_byteLength); 146 return m_stagingBuffer.get(); 147 } 148 149 void GPUBuffer::unmap() 150 { 151 if (!isMappable()) { 152 LOG(WebGPU, "GPUBuffer::unmap(): Buffer is not mappable!"); 153 return; 154 } 155 156 if (m_stagingBuffer && m_isMapWrite) { 157 memcpy(m_platformBuffer.get().contents, m_stagingBuffer->data(), m_byteLength); 158 m_stagingBuffer = nullptr; 159 } 160 161 if (m_pendingCallback) { 162 m_mappingCallbackTask.cancelTask(); 163 m_pendingCallback->callback(nullptr); 164 m_pendingCallback = nullptr; 165 } 166 } 167 168 void GPUBuffer::destroy() 169 { 170 if (isMappable()) 171 unmap(); 172 173 m_isDestroyed = true; 174 175 // FIXME: If GPU is still using the MTLBuffer, it will be released after all relevant commands have executed. 176 if (!m_numScheduledCommandBuffers) 177 m_platformBuffer = nullptr; 93 178 } 94 179 -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm
r240180 r241996 62 62 63 63 auto& bufferBinding = WTF::get<GPUBufferBinding>(resource); 64 auto buffer = bufferBinding.buffer->platformBuffer();64 auto mtlBuffer = bufferBinding.buffer->platformBuffer(); 65 65 66 if (! buffer) {66 if (!mtlBuffer) { 67 67 LOG(WebGPU, "%s: Invalid MTLBuffer in GPUBufferBinding!", functionName); 68 68 return; … … 71 71 BEGIN_BLOCK_OBJC_EXCEPTIONS; 72 72 73 [argumentEncoder setBuffer: buffer offset:bufferBinding.offset atIndex:index];74 useResource( buffer, MTLResourceUsageRead);73 [argumentEncoder setBuffer:mtlBuffer offset:bufferBinding.offset atIndex:index]; 74 useResource(mtlBuffer, bufferBinding.buffer->isReadOnly() ? MTLResourceUsageRead : MTLResourceUsageRead | MTLResourceUsageWrite); 75 75 76 76 END_BLOCK_OBJC_EXCEPTIONS;
Note: See TracChangeset
for help on using the changeset viewer.