blob: 3e510c574f3ef863b1a1012f5ef6399134b9c17c [file] [log] [blame]
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +00001/*
2 * Copyright (C) 2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebGPUBindGroupDescriptor.h"
28
29#if ENABLE(WEBGPU)
30
31#include "GPUBindGroupDescriptor.h"
32#include "GPUBuffer.h"
33#include "Logging.h"
34#include <wtf/Variant.h>
35
36namespace WebCore {
37
38static bool validateBufferBindingType(const GPUBuffer* buffer, const GPUBindGroupLayoutBinding& binding, const char* const functionName)
39{
40#if LOG_DISABLED
41 UNUSED_PARAM(functionName);
42#endif
43
44 switch (binding.type) {
justin_fan@apple.comfd8b80a2019-03-14 22:26:52 +000045 case GPUBindingType::UniformBuffer:
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000046 if (!buffer->isUniform()) {
justin_fan@apple.comaa5e7bf2019-03-29 02:19:37 +000047 LOG(WebGPU, "%s: GPUBuffer resource for binding %u does not have UNIFORM usage!", functionName, binding.binding);
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000048 return false;
49 }
50 return true;
justin_fan@apple.comfd8b80a2019-03-14 22:26:52 +000051 case GPUBindingType::StorageBuffer:
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000052 if (!buffer->isStorage()) {
justin_fan@apple.comaa5e7bf2019-03-29 02:19:37 +000053 LOG(WebGPU, "%s: GPUBuffer resource for binding %u does not have STORAGE usage!", functionName, binding.binding);
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000054 return false;
55 }
56 return true;
57 default:
justin_fan@apple.comaa5e7bf2019-03-29 02:19:37 +000058 LOG(WebGPU, "%s: Layout binding %u is not a buffer-type resource!", functionName, binding.binding);
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000059 return false;
60 }
61}
62
justin_fan@apple.com0d966272019-03-13 01:33:11 +000063Optional<GPUBindGroupDescriptor> WebGPUBindGroupDescriptor::tryCreateGPUBindGroupDescriptor() const
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000064{
65 const char* const functionName = "GPUDevice::createBindGroup()";
66
67 if (!layout || !layout->bindGroupLayout()) {
68 LOG(WebGPU, "%s: Invalid GPUBindGroupLayout!", functionName);
69 return WTF::nullopt;
70 }
71
72 if (bindings.size() != layout->bindGroupLayout()->bindingsMap().size()) {
73 LOG(WebGPU, "%s: Mismatched number of GPUBindGroupLayoutBindings and GPUBindGroupBindings!", functionName);
74 return WTF::nullopt;
75 }
76
77 auto layoutMap = layout->bindGroupLayout()->bindingsMap();
78
79 Vector<GPUBindGroupBinding> bindGroupBindings;
80 bindGroupBindings.reserveCapacity(bindings.size());
81
82 for (const auto& binding : bindings) {
83 auto iterator = layoutMap.find(binding.binding);
84 if (iterator == layoutMap.end()) {
justin_fan@apple.comaa5e7bf2019-03-29 02:19:37 +000085 LOG(WebGPU, "%s: GPUBindGroupLayoutBinding %u not found in GPUBindGroupLayout!", functionName, binding.binding);
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000086 return WTF::nullopt;
87 }
88
justin_fan@apple.com7a34ac32019-02-27 21:10:24 +000089 const auto layoutBinding = iterator->value;
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +000090
justin_fan@apple.comcc25e322019-03-07 23:03:53 +000091 auto bindingResourceVisitor = WTF::makeVisitor([](const RefPtr<WebGPUSampler>& sampler) -> Optional<GPUBindingResource> {
92 if (!sampler)
93 return WTF::nullopt;
94 auto gpuSampler = sampler->sampler();
95 if (!gpuSampler)
96 return WTF::nullopt;
97
98 return static_cast<GPUBindingResource>(makeRef(*gpuSampler));
99 }, [](const RefPtr<WebGPUTextureView>& view) -> Optional<GPUBindingResource> {
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000100 if (!view)
101 return WTF::nullopt;
justin_fan@apple.com73c5df7a2019-03-06 23:57:58 +0000102 auto texture = view->texture();
103 if (!texture)
104 return WTF::nullopt;
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000105
justin_fan@apple.com128cdf82019-03-27 20:47:55 +0000106 return static_cast<GPUBindingResource>(makeRef(*texture));
justin_fan@apple.com7a34ac32019-02-27 21:10:24 +0000107 }, [&layoutBinding, functionName] (WebGPUBufferBinding bufferBinding) -> Optional<GPUBindingResource> {
justin_fan@apple.com73c5df7a2019-03-06 23:57:58 +0000108 if (!bufferBinding.buffer)
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000109 return WTF::nullopt;
justin_fan@apple.com73c5df7a2019-03-06 23:57:58 +0000110 auto buffer = bufferBinding.buffer->buffer();
111 if (!buffer)
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000112 return WTF::nullopt;
113
mmaxfield@apple.com2a946692019-06-13 05:38:28 +0000114 if (!validateBufferBindingType(buffer, layoutBinding.externalBinding, functionName))
justin_fan@apple.com73c5df7a2019-03-06 23:57:58 +0000115 return WTF::nullopt;
116
justin_fan@apple.com128cdf82019-03-27 20:47:55 +0000117 return static_cast<GPUBindingResource>(GPUBufferBinding { makeRef(*buffer), bufferBinding.offset, bufferBinding.size });
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000118 });
119
120 auto bindingResource = WTF::visit(bindingResourceVisitor, binding.resource);
justin_fan@apple.com73c5df7a2019-03-06 23:57:58 +0000121 if (!bindingResource) {
mmaxfield@apple.com2a946692019-06-13 05:38:28 +0000122 LOG(WebGPU, "%s: Invalid resource for binding %u!", functionName, layoutBinding.externalBinding.binding);
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000123 return WTF::nullopt;
justin_fan@apple.com73c5df7a2019-03-06 23:57:58 +0000124 }
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000125
126 bindGroupBindings.uncheckedAppend(GPUBindGroupBinding { binding.binding, WTFMove(bindingResource.value()) });
127 }
128
justin_fan@apple.com128cdf82019-03-27 20:47:55 +0000129 return GPUBindGroupDescriptor { makeRef(*layout->bindGroupLayout()), WTFMove(bindGroupBindings) };
justin_fan@apple.com99d6d4b2019-02-23 23:24:27 +0000130}
131
132} // namespace WebCore
133
134#endif // ENABLE(WEBGPU)