|
Lines 30-39
a/Source/WebGPU/WebGPU/BindGroupLayout.mm_sec1
|
| 30 |
|
30 |
|
| 31 |
namespace WebGPU { |
31 |
namespace WebGPU { |
| 32 |
|
32 |
|
|
|
33 |
static bool isPresent(const WGPUBufferBindingLayout& buffer) |
| 34 |
{ |
| 35 |
return buffer.type != WGPUBufferBindingType_Undefined; |
| 36 |
} |
| 37 |
|
| 38 |
static MTLArgumentDescriptor *createArgumentDescriptor(const WGPUBufferBindingLayout& buffer) |
| 39 |
{ |
| 40 |
if (buffer.nextInChain) |
| 41 |
return nil; |
| 42 |
|
| 43 |
auto descriptor = [MTLArgumentDescriptor new]; |
| 44 |
descriptor.dataType = MTLDataTypePointer; |
| 45 |
// FIXME: Handle hasDynamicOffset. |
| 46 |
// FIXME: Handle minBindingSize. |
| 47 |
switch (buffer.type) { |
| 48 |
case WGPUBufferBindingType_Uniform: |
| 49 |
case WGPUBufferBindingType_ReadOnlyStorage: |
| 50 |
descriptor.access = MTLArgumentAccessReadOnly; |
| 51 |
break; |
| 52 |
case WGPUBufferBindingType_Storage: |
| 53 |
descriptor.access = MTLArgumentAccessReadWrite; |
| 54 |
break; |
| 55 |
default: |
| 56 |
return nil; |
| 57 |
} |
| 58 |
return descriptor; |
| 59 |
} |
| 60 |
|
| 61 |
static bool isPresent(const WGPUSamplerBindingLayout& sampler) |
| 62 |
{ |
| 63 |
return sampler.type != WGPUSamplerBindingType_Undefined; |
| 64 |
} |
| 65 |
|
| 66 |
static MTLArgumentDescriptor *createArgumentDescriptor(const WGPUSamplerBindingLayout& sampler) |
| 67 |
{ |
| 68 |
if (sampler.nextInChain) |
| 69 |
return nil; |
| 70 |
|
| 71 |
UNUSED_PARAM(sampler); |
| 72 |
auto descriptor = [MTLArgumentDescriptor new]; |
| 73 |
descriptor.dataType = MTLDataTypeSampler; |
| 74 |
// FIXME: Implement this. |
| 75 |
return descriptor; |
| 76 |
} |
| 77 |
|
| 78 |
static bool isPresent(const WGPUTextureBindingLayout& texture) |
| 79 |
{ |
| 80 |
return texture.sampleType != WGPUTextureSampleType_Undefined |
| 81 |
&& texture.viewDimension != WGPUTextureViewDimension_Undefined; |
| 82 |
} |
| 83 |
|
| 84 |
static MTLArgumentDescriptor *createArgumentDescriptor(const WGPUTextureBindingLayout& texture) |
| 85 |
{ |
| 86 |
if (texture.nextInChain) |
| 87 |
return nil; |
| 88 |
|
| 89 |
UNUSED_PARAM(texture); |
| 90 |
auto descriptor = [MTLArgumentDescriptor new]; |
| 91 |
descriptor.dataType = MTLDataTypeTexture; |
| 92 |
// FIXME: Implement this. |
| 93 |
return descriptor; |
| 94 |
} |
| 95 |
|
| 96 |
static bool isPresent(const WGPUStorageTextureBindingLayout& storageTexture) |
| 97 |
{ |
| 98 |
return storageTexture.access != WGPUStorageTextureAccess_Undefined |
| 99 |
&& storageTexture.format != WGPUTextureFormat_Undefined |
| 100 |
&& storageTexture.viewDimension != WGPUTextureViewDimension_Undefined; |
| 101 |
} |
| 102 |
|
| 103 |
static MTLArgumentDescriptor *createArgumentDescriptor(const WGPUStorageTextureBindingLayout& storageTexture) |
| 104 |
{ |
| 105 |
if (storageTexture.nextInChain) |
| 106 |
return nil; |
| 107 |
|
| 108 |
UNUSED_PARAM(storageTexture); |
| 109 |
auto descriptor = [MTLArgumentDescriptor new]; |
| 110 |
descriptor.dataType = MTLDataTypeTexture; |
| 111 |
// FIXME: Implement this. |
| 112 |
return descriptor; |
| 113 |
} |
| 114 |
|
| 33 |
RefPtr<BindGroupLayout> Device::createBindGroupLayout(const WGPUBindGroupLayoutDescriptor* descriptor) |
115 |
RefPtr<BindGroupLayout> Device::createBindGroupLayout(const WGPUBindGroupLayoutDescriptor* descriptor) |
| 34 |
{ |
116 |
{ |
| 35 |
UNUSED_PARAM(descriptor); |
117 |
if (descriptor->nextInChain) |
| 36 |
return BindGroupLayout::create(nil, nil, nil); |
118 |
return nullptr; |
|
|
119 |
|
| 120 |
NSMutableArray<MTLArgumentDescriptor *> *vertexArguments = [NSMutableArray arrayWithCapacity:descriptor->entryCount]; |
| 121 |
NSMutableArray<MTLArgumentDescriptor *> *fragmentArguments = [NSMutableArray arrayWithCapacity:descriptor->entryCount]; |
| 122 |
NSMutableArray<MTLArgumentDescriptor *> *computeArguments = [NSMutableArray arrayWithCapacity:descriptor->entryCount]; |
| 123 |
if (!vertexArguments || !fragmentArguments || !computeArguments) |
| 124 |
return nullptr; |
| 125 |
|
| 126 |
for (uint32_t i = 0; i < descriptor->entryCount; ++i) { |
| 127 |
const WGPUBindGroupLayoutEntry& entry = descriptor->entries[i]; |
| 128 |
if (entry.nextInChain) |
| 129 |
return nullptr; |
| 130 |
|
| 131 |
// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry |
| 132 |
// "Only one [of buffer, sampler, texture, storageTexture, or externalTexture] may be defined for any given GPUBindGroupLayoutEntry." |
| 133 |
|
| 134 |
ASSERT(i == vertexArguments.count); |
| 135 |
ASSERT(vertexArguments.count == fragmentArguments.count); |
| 136 |
ASSERT(fragmentArguments.count == computeArguments.count); |
| 137 |
|
| 138 |
const WGPUBufferBindingLayout& buffer = entry.buffer; |
| 139 |
const WGPUSamplerBindingLayout& sampler = entry.sampler; |
| 140 |
const WGPUTextureBindingLayout& texture = entry.texture; |
| 141 |
const WGPUStorageTextureBindingLayout& storageTexture = entry.storageTexture; |
| 142 |
|
| 143 |
MTLArgumentDescriptor *descriptor = nil; |
| 144 |
|
| 145 |
if (isPresent(buffer)) { |
| 146 |
if (i != vertexArguments.count) |
| 147 |
return nullptr; |
| 148 |
|
| 149 |
descriptor = createArgumentDescriptor(buffer); |
| 150 |
if (!descriptor) |
| 151 |
return nullptr; |
| 152 |
} |
| 153 |
|
| 154 |
if (isPresent(sampler)) { |
| 155 |
if (i != vertexArguments.count) |
| 156 |
return nullptr; |
| 157 |
|
| 158 |
descriptor = createArgumentDescriptor(sampler); |
| 159 |
if (!descriptor) |
| 160 |
return nullptr; |
| 161 |
} |
| 162 |
|
| 163 |
if (isPresent(texture)) { |
| 164 |
if (i != vertexArguments.count) |
| 165 |
return nullptr; |
| 166 |
|
| 167 |
descriptor = createArgumentDescriptor(texture); |
| 168 |
if (!descriptor) |
| 169 |
return nullptr; |
| 170 |
} |
| 171 |
|
| 172 |
if (isPresent(storageTexture)) { |
| 173 |
if (i != vertexArguments.count) |
| 174 |
return nullptr; |
| 175 |
|
| 176 |
descriptor = createArgumentDescriptor(storageTexture); |
| 177 |
if (!descriptor) |
| 178 |
return nullptr; |
| 179 |
} |
| 180 |
|
| 181 |
// FIXME: This needs coordination with the shader compiler. |
| 182 |
descriptor.index = i; |
| 183 |
|
| 184 |
MTLArgumentDescriptor *vertexDescriptor = descriptor; |
| 185 |
MTLArgumentDescriptor *fragmentDescriptor = [descriptor copy]; |
| 186 |
MTLArgumentDescriptor *computeDescriptor = [descriptor copy]; |
| 187 |
if (!fragmentDescriptor || !computeDescriptor) |
| 188 |
return nullptr; |
| 189 |
|
| 190 |
if (!(entry.visibility & WGPUShaderStage_Vertex)) |
| 191 |
vertexDescriptor.access = MTLArgumentAccessReadOnly; |
| 192 |
if (!(entry.visibility & WGPUShaderStage_Fragment)) |
| 193 |
fragmentDescriptor.access = MTLArgumentAccessReadOnly; |
| 194 |
if (!(entry.visibility & WGPUShaderStage_Compute)) |
| 195 |
computeDescriptor.access = MTLArgumentAccessReadOnly; |
| 196 |
|
| 197 |
[vertexArguments addObject:vertexDescriptor]; |
| 198 |
[fragmentArguments addObject:fragmentDescriptor]; |
| 199 |
[computeArguments addObject:computeDescriptor]; |
| 200 |
} |
| 201 |
|
| 202 |
id <MTLArgumentEncoder> vertexArgumentEncoder = [m_device newArgumentEncoderWithArguments:vertexArguments]; |
| 203 |
id <MTLArgumentEncoder> fragmentArgumentEncoder = [m_device newArgumentEncoderWithArguments:fragmentArguments]; |
| 204 |
id <MTLArgumentEncoder> computeArgumentEncoder = [m_device newArgumentEncoderWithArguments:computeArguments]; |
| 205 |
if (!vertexArgumentEncoder || !fragmentArgumentEncoder || !computeArgumentEncoder) |
| 206 |
return nullptr; |
| 207 |
|
| 208 |
auto label = [NSString stringWithCString:descriptor->label encoding:NSUTF8StringEncoding]; |
| 209 |
vertexArgumentEncoder.label = label; |
| 210 |
fragmentArgumentEncoder.label = label; |
| 211 |
computeArgumentEncoder.label = label; |
| 212 |
|
| 213 |
return BindGroupLayout::create(vertexArgumentEncoder, fragmentArgumentEncoder, computeArgumentEncoder); |
| 37 |
} |
214 |
} |
| 38 |
|
215 |
|
| 39 |
BindGroupLayout::BindGroupLayout(id <MTLArgumentEncoder> vertexArgumentEncoder, id <MTLArgumentEncoder> fragmentArgumentEncoder, id <MTLArgumentEncoder> computeArgumentEncoder) |
216 |
BindGroupLayout::BindGroupLayout(id <MTLArgumentEncoder> vertexArgumentEncoder, id <MTLArgumentEncoder> fragmentArgumentEncoder, id <MTLArgumentEncoder> computeArgumentEncoder) |
|
Lines 41-56
BindGroupLayout::BindGroupLayout(id <MTLArgumentEncoder> vertexArgumentEncoder,
a/Source/WebGPU/WebGPU/BindGroupLayout.mm_sec2
|
| 41 |
, m_fragmentArgumentEncoder(fragmentArgumentEncoder) |
218 |
, m_fragmentArgumentEncoder(fragmentArgumentEncoder) |
| 42 |
, m_computeArgumentEncoder(computeArgumentEncoder) |
219 |
, m_computeArgumentEncoder(computeArgumentEncoder) |
| 43 |
{ |
220 |
{ |
| 44 |
UNUSED_VARIABLE(m_vertexArgumentEncoder); |
|
|
| 45 |
UNUSED_VARIABLE(m_fragmentArgumentEncoder); |
| 46 |
UNUSED_VARIABLE(m_computeArgumentEncoder); |
| 47 |
} |
221 |
} |
| 48 |
|
222 |
|
| 49 |
BindGroupLayout::~BindGroupLayout() = default; |
223 |
BindGroupLayout::~BindGroupLayout() = default; |
| 50 |
|
224 |
|
| 51 |
void BindGroupLayout::setLabel(const char* label) |
225 |
void BindGroupLayout::setLabel(const char* label) |
| 52 |
{ |
226 |
{ |
| 53 |
UNUSED_PARAM(label); |
227 |
auto labelString = [NSString stringWithCString:label encoding:NSUTF8StringEncoding]; |
|
|
228 |
m_vertexArgumentEncoder.label = labelString; |
| 229 |
m_fragmentArgumentEncoder.label = labelString; |
| 230 |
m_computeArgumentEncoder.label = labelString; |
| 231 |
} |
| 232 |
|
| 233 |
NSUInteger BindGroupLayout::encodedLength() const |
| 234 |
{ |
| 235 |
auto result = m_vertexArgumentEncoder.encodedLength; |
| 236 |
ASSERT(result == m_fragmentArgumentEncoder.encodedLength); |
| 237 |
ASSERT(result == m_computeArgumentEncoder.encodedLength); |
| 238 |
return result; |
| 54 |
} |
239 |
} |
| 55 |
|
240 |
|
| 56 |
} |
241 |
} |