1 // Copyright 2017 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "dawn_native/utils/WGPUHelpers.h" 16 17 #include "common/Assert.h" 18 #include "common/Constants.h" 19 #include "dawn_native/BindGroup.h" 20 #include "dawn_native/BindGroupLayout.h" 21 #include "dawn_native/Buffer.h" 22 #include "dawn_native/Device.h" 23 #include "dawn_native/PipelineLayout.h" 24 #include "dawn_native/Queue.h" 25 #include "dawn_native/Sampler.h" 26 #include "dawn_native/ShaderModule.h" 27 28 #include <cstring> 29 #include <iomanip> 30 #include <limits> 31 #include <mutex> 32 #include <sstream> 33 34 namespace dawn_native { namespace utils { 35 CreateShaderModule(DeviceBase * device,const char * source)36 ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(DeviceBase* device, 37 const char* source) { 38 ShaderModuleWGSLDescriptor wgslDesc; 39 wgslDesc.source = source; 40 ShaderModuleDescriptor descriptor; 41 descriptor.nextInChain = &wgslDesc; 42 return device->CreateShaderModule(&descriptor); 43 } 44 CreateBufferFromData(DeviceBase * device,wgpu::BufferUsage usage,const void * data,uint64_t size)45 ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device, 46 wgpu::BufferUsage usage, 47 const void* data, 48 uint64_t size) { 49 BufferDescriptor descriptor; 50 descriptor.size = size; 51 descriptor.usage = usage; 52 descriptor.mappedAtCreation = true; 53 Ref<BufferBase> buffer; 54 DAWN_TRY_ASSIGN(buffer, device->CreateBuffer(&descriptor)); 55 memcpy(buffer->GetMappedRange(0, size), data, size); 56 buffer->Unmap(); 57 return buffer; 58 } 59 MakeBasicPipelineLayout(DeviceBase * device,const Ref<BindGroupLayoutBase> & bindGroupLayout)60 ResultOrError<Ref<PipelineLayoutBase>> MakeBasicPipelineLayout( 61 DeviceBase* device, 62 const Ref<BindGroupLayoutBase>& bindGroupLayout) { 63 PipelineLayoutDescriptor descriptor; 64 descriptor.bindGroupLayoutCount = 1; 65 BindGroupLayoutBase* bgl = bindGroupLayout.Get(); 66 descriptor.bindGroupLayouts = &bgl; 67 return device->CreatePipelineLayout(&descriptor); 68 } 69 MakeBindGroupLayout(DeviceBase * device,std::initializer_list<BindingLayoutEntryInitializationHelper> entriesInitializer,bool allowInternalBinding)70 ResultOrError<Ref<BindGroupLayoutBase>> MakeBindGroupLayout( 71 DeviceBase* device, 72 std::initializer_list<BindingLayoutEntryInitializationHelper> entriesInitializer, 73 bool allowInternalBinding) { 74 std::vector<BindGroupLayoutEntry> entries; 75 for (const BindingLayoutEntryInitializationHelper& entry : entriesInitializer) { 76 entries.push_back(entry); 77 } 78 79 BindGroupLayoutDescriptor descriptor; 80 descriptor.entryCount = static_cast<uint32_t>(entries.size()); 81 descriptor.entries = entries.data(); 82 return device->CreateBindGroupLayout(&descriptor, allowInternalBinding); 83 } 84 BindingLayoutEntryInitializationHelper(uint32_t entryBinding,wgpu::ShaderStage entryVisibility,wgpu::BufferBindingType bufferType,bool bufferHasDynamicOffset,uint64_t bufferMinBindingSize)85 BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper( 86 uint32_t entryBinding, 87 wgpu::ShaderStage entryVisibility, 88 wgpu::BufferBindingType bufferType, 89 bool bufferHasDynamicOffset, 90 uint64_t bufferMinBindingSize) { 91 binding = entryBinding; 92 visibility = entryVisibility; 93 buffer.type = bufferType; 94 buffer.hasDynamicOffset = bufferHasDynamicOffset; 95 buffer.minBindingSize = bufferMinBindingSize; 96 } 97 BindingLayoutEntryInitializationHelper(uint32_t entryBinding,wgpu::ShaderStage entryVisibility,wgpu::SamplerBindingType samplerType)98 BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper( 99 uint32_t entryBinding, 100 wgpu::ShaderStage entryVisibility, 101 wgpu::SamplerBindingType samplerType) { 102 binding = entryBinding; 103 visibility = entryVisibility; 104 sampler.type = samplerType; 105 } 106 BindingLayoutEntryInitializationHelper(uint32_t entryBinding,wgpu::ShaderStage entryVisibility,wgpu::TextureSampleType textureSampleType,wgpu::TextureViewDimension textureViewDimension,bool textureMultisampled)107 BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper( 108 uint32_t entryBinding, 109 wgpu::ShaderStage entryVisibility, 110 wgpu::TextureSampleType textureSampleType, 111 wgpu::TextureViewDimension textureViewDimension, 112 bool textureMultisampled) { 113 binding = entryBinding; 114 visibility = entryVisibility; 115 texture.sampleType = textureSampleType; 116 texture.viewDimension = textureViewDimension; 117 texture.multisampled = textureMultisampled; 118 } 119 BindingLayoutEntryInitializationHelper(uint32_t entryBinding,wgpu::ShaderStage entryVisibility,wgpu::StorageTextureAccess storageTextureAccess,wgpu::TextureFormat format,wgpu::TextureViewDimension textureViewDimension)120 BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper( 121 uint32_t entryBinding, 122 wgpu::ShaderStage entryVisibility, 123 wgpu::StorageTextureAccess storageTextureAccess, 124 wgpu::TextureFormat format, 125 wgpu::TextureViewDimension textureViewDimension) { 126 binding = entryBinding; 127 visibility = entryVisibility; 128 storageTexture.access = storageTextureAccess; 129 storageTexture.format = format; 130 storageTexture.viewDimension = textureViewDimension; 131 } 132 BindingLayoutEntryInitializationHelper(const BindGroupLayoutEntry & entry)133 BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper( 134 const BindGroupLayoutEntry& entry) 135 : BindGroupLayoutEntry(entry) { 136 } 137 BindingInitializationHelper(uint32_t binding,const Ref<SamplerBase> & sampler)138 BindingInitializationHelper::BindingInitializationHelper(uint32_t binding, 139 const Ref<SamplerBase>& sampler) 140 : binding(binding), sampler(sampler) { 141 } 142 BindingInitializationHelper(uint32_t binding,const Ref<TextureViewBase> & textureView)143 BindingInitializationHelper::BindingInitializationHelper( 144 uint32_t binding, 145 const Ref<TextureViewBase>& textureView) 146 : binding(binding), textureView(textureView) { 147 } 148 BindingInitializationHelper(uint32_t binding,const Ref<BufferBase> & buffer,uint64_t offset,uint64_t size)149 BindingInitializationHelper::BindingInitializationHelper(uint32_t binding, 150 const Ref<BufferBase>& buffer, 151 uint64_t offset, 152 uint64_t size) 153 : binding(binding), buffer(buffer), offset(offset), size(size) { 154 } 155 156 BindingInitializationHelper::~BindingInitializationHelper() = default; 157 GetAsBinding() const158 BindGroupEntry BindingInitializationHelper::GetAsBinding() const { 159 BindGroupEntry result; 160 161 result.binding = binding; 162 result.sampler = sampler.Get(); 163 result.textureView = textureView.Get(); 164 result.buffer = buffer.Get(); 165 result.offset = offset; 166 result.size = size; 167 168 return result; 169 } 170 MakeBindGroup(DeviceBase * device,const Ref<BindGroupLayoutBase> & layout,std::initializer_list<BindingInitializationHelper> entriesInitializer)171 ResultOrError<Ref<BindGroupBase>> MakeBindGroup( 172 DeviceBase* device, 173 const Ref<BindGroupLayoutBase>& layout, 174 std::initializer_list<BindingInitializationHelper> entriesInitializer) { 175 std::vector<BindGroupEntry> entries; 176 for (const BindingInitializationHelper& helper : entriesInitializer) { 177 entries.push_back(helper.GetAsBinding()); 178 } 179 180 BindGroupDescriptor descriptor; 181 descriptor.layout = layout.Get(); 182 descriptor.entryCount = entries.size(); 183 descriptor.entries = entries.data(); 184 185 return device->CreateBindGroup(&descriptor); 186 } 187 GetLabelForTrace(const char * label)188 const char* GetLabelForTrace(const char* label) { 189 return (label == nullptr || strlen(label) == 0) ? "None" : label; 190 } 191 192 }} // namespace dawn_native::utils 193