// Copyright 2017 The Dawn Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef UTILS_DAWNHELPERS_H_ #define UTILS_DAWNHELPERS_H_ #include #include #include #include #include "common/Constants.h" #include "utils/TextureFormatUtils.h" namespace utils { enum Expectation { Success, Failure }; wgpu::ShaderModule CreateShaderModuleFromASM(const wgpu::Device& device, const char* source); wgpu::ShaderModule CreateShaderModule(const wgpu::Device& device, const char* source); wgpu::Buffer CreateBufferFromData(const wgpu::Device& device, const void* data, uint64_t size, wgpu::BufferUsage usage); template wgpu::Buffer CreateBufferFromData(const wgpu::Device& device, wgpu::BufferUsage usage, std::initializer_list data) { return CreateBufferFromData(device, data.begin(), uint32_t(sizeof(T) * data.size()), usage); } wgpu::ImageCopyBuffer CreateImageCopyBuffer(wgpu::Buffer buffer, uint64_t offset, uint32_t bytesPerRow, uint32_t rowsPerImage = wgpu::kCopyStrideUndefined); wgpu::ImageCopyTexture CreateImageCopyTexture( wgpu::Texture texture, uint32_t level, wgpu::Origin3D origin, wgpu::TextureAspect aspect = wgpu::TextureAspect::All); wgpu::TextureDataLayout CreateTextureDataLayout( uint64_t offset, uint32_t bytesPerRow, uint32_t rowsPerImage = wgpu::kCopyStrideUndefined); struct ComboRenderPassDescriptor : public wgpu::RenderPassDescriptor { public: ComboRenderPassDescriptor(std::initializer_list colorAttachmentInfo, wgpu::TextureView depthStencil = wgpu::TextureView()); ComboRenderPassDescriptor(const ComboRenderPassDescriptor& otherRenderPass); const ComboRenderPassDescriptor& operator=( const ComboRenderPassDescriptor& otherRenderPass); std::array cColorAttachments; wgpu::RenderPassDepthStencilAttachmentDescriptor cDepthStencilAttachmentInfo = {}; }; struct BasicRenderPass { public: BasicRenderPass(); BasicRenderPass(uint32_t width, uint32_t height, wgpu::Texture color, wgpu::TextureFormat texture = kDefaultColorFormat); static constexpr wgpu::TextureFormat kDefaultColorFormat = wgpu::TextureFormat::RGBA8Unorm; uint32_t width; uint32_t height; wgpu::Texture color; wgpu::TextureFormat colorFormat; utils::ComboRenderPassDescriptor renderPassInfo; }; BasicRenderPass CreateBasicRenderPass(const wgpu::Device& device, uint32_t width, uint32_t height); wgpu::PipelineLayout MakeBasicPipelineLayout(const wgpu::Device& device, const wgpu::BindGroupLayout* bindGroupLayout); wgpu::PipelineLayout MakePipelineLayout(const wgpu::Device& device, std::vector bgls); extern wgpu::ExternalTextureBindingLayout kExternalTextureBindingLayout; // Helpers to make creating bind group layouts look nicer: // // utils::MakeBindGroupLayout(device, { // {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}, // {1, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}, // {3, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float} // }); struct BindingLayoutEntryInitializationHelper : wgpu::BindGroupLayoutEntry { BindingLayoutEntryInitializationHelper(uint32_t entryBinding, wgpu::ShaderStage entryVisibility, wgpu::BufferBindingType bufferType, bool bufferHasDynamicOffset = false, uint64_t bufferMinBindingSize = 0); BindingLayoutEntryInitializationHelper(uint32_t entryBinding, wgpu::ShaderStage entryVisibility, wgpu::SamplerBindingType samplerType); BindingLayoutEntryInitializationHelper( uint32_t entryBinding, wgpu::ShaderStage entryVisibility, wgpu::TextureSampleType textureSampleType, wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D, bool textureMultisampled = false); BindingLayoutEntryInitializationHelper( uint32_t entryBinding, wgpu::ShaderStage entryVisibility, wgpu::StorageTextureAccess storageTextureAccess, wgpu::TextureFormat format, wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D); BindingLayoutEntryInitializationHelper(uint32_t entryBinding, wgpu::ShaderStage entryVisibility, wgpu::ExternalTextureBindingLayout* bindingLayout); BindingLayoutEntryInitializationHelper(const wgpu::BindGroupLayoutEntry& entry); }; wgpu::BindGroupLayout MakeBindGroupLayout( const wgpu::Device& device, std::initializer_list entriesInitializer); // Helpers to make creating bind groups look nicer: // // utils::MakeBindGroup(device, layout, { // {0, mySampler}, // {1, myBuffer, offset, size}, // {3, myTextureView} // }); // Structure with one constructor per-type of bindings, so that the initializer_list accepts // bindings with the right type and no extra information. struct BindingInitializationHelper { BindingInitializationHelper(uint32_t binding, const wgpu::Sampler& sampler); BindingInitializationHelper(uint32_t binding, const wgpu::TextureView& textureView); BindingInitializationHelper(uint32_t binding, const wgpu::ExternalTexture& externalTexture); BindingInitializationHelper(uint32_t binding, const wgpu::Buffer& buffer, uint64_t offset = 0, uint64_t size = wgpu::kWholeSize); wgpu::BindGroupEntry GetAsBinding() const; uint32_t binding; wgpu::Sampler sampler; wgpu::TextureView textureView; wgpu::Buffer buffer; wgpu::ExternalTextureBindingEntry externalTextureBindingEntry; uint64_t offset = 0; uint64_t size = 0; }; wgpu::BindGroup MakeBindGroup( const wgpu::Device& device, const wgpu::BindGroupLayout& layout, std::initializer_list entriesInitializer); } // namespace utils #endif // UTILS_DAWNHELPERS_H_