/**
 * This file is part of the "Learn WebGPU for C++" book.
 *   https://github.com/eliemichel/LearnWebGPU
 *
 * MIT License
 * Copyright (c) 2022 Elie Michel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Exactly one of your source files must #define WEBGPU_CPP_IMPLEMENTATION
 * before including this header.
 *
 * NB: This file has been generated by the webgpu-cpp generator
 *   (see https://github.com/eliemichel/webgpu-cpp )
 */

#pragma once

#include <webgpu/webgpu.h>

#include <iostream>
#include <vector>
#include <functional>
#include <cassert>
#include <memory>

/**
 * A namespace providing a more C++ idiomatic API to WebGPU.
 */
namespace wgpu {

struct DefaultFlag {};
constexpr DefaultFlag Default;

#define HANDLE(Type) \
class Type { \
public: \
	typedef Type S; /* S == Self */ \
	typedef WGPU ## Type W; /* W == WGPU Type */ \
	Type(const W& w) : m_raw(w) {} \
	operator W&() { return m_raw; } \
	operator const W&() const { return m_raw; } \
	operator bool() const { return m_raw != nullptr; } \
	friend auto operator<<(std::ostream &stream, const S& self) -> std::ostream & { \
		return stream << "<wgpu::" << #Type << " " << self.m_raw << ">"; \
	} \
private: \
	W m_raw; \
public:

#define DESCRIPTOR(Type) \
struct Type : public WGPU ## Type { \
public: \
	typedef Type S; /* S == Self */ \
	typedef WGPU ## Type W; /* W == WGPU Type */ \
	Type() : W() { nextInChain = nullptr; } \
	Type(const W &other) : W(other) { nextInChain = nullptr; } \
	Type(const DefaultFlag &) : W() { setDefault(); } \
	Type& operator=(const DefaultFlag &) { setDefault(); return *this; } \
	friend auto operator<<(std::ostream &stream, const S&) -> std::ostream & { \
		return stream << "<wgpu::" << #Type << ">"; \
	} \
public:

#define STRUCT(Type) \
struct Type : public WGPU ## Type { \
public: \
	typedef Type S; /* S == Self */ \
	typedef WGPU ## Type W; /* W == WGPU Type */ \
	Type() : W() {} \
	Type(const W &other) : W(other) {} \
	Type(const DefaultFlag &) : W() { setDefault(); } \
	Type& operator=(const DefaultFlag &) { setDefault(); return *this; } \
	friend auto operator<<(std::ostream &stream, const S&) -> std::ostream & { \
		return stream << "<wgpu::" << #Type << ">"; \
	} \
public:

#define ENUM(Type) \
class Type { \
public: \
	typedef Type S; /* S == Self */ \
	typedef WGPU ## Type W; /* W == WGPU Type */ \
	Type(const W& w) : m_raw(w) {} \
	operator W() const { return m_raw; } \
private: \
	W m_raw; \
public:

#define ENUM_ENTRY(Name, Value) \
	static constexpr W Name = (W)Value;

#define END };



// Enumerations
ENUM(AdapterType)
	ENUM_ENTRY(DiscreteGPU, 0x00000000)
	ENUM_ENTRY(IntegratedGPU, 0x00000001)
	ENUM_ENTRY(CPU, 0x00000002)
	ENUM_ENTRY(Unknown, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(AddressMode)
	ENUM_ENTRY(Repeat, 0x00000000)
	ENUM_ENTRY(MirrorRepeat, 0x00000001)
	ENUM_ENTRY(ClampToEdge, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(AlphaMode)
	ENUM_ENTRY(Premultiplied, 0x00000000)
	ENUM_ENTRY(Unpremultiplied, 0x00000001)
	ENUM_ENTRY(Opaque, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BackendType)
	ENUM_ENTRY(Null, 0x00000000)
	ENUM_ENTRY(WebGPU, 0x00000001)
	ENUM_ENTRY(D3D11, 0x00000002)
	ENUM_ENTRY(D3D12, 0x00000003)
	ENUM_ENTRY(Metal, 0x00000004)
	ENUM_ENTRY(Vulkan, 0x00000005)
	ENUM_ENTRY(OpenGL, 0x00000006)
	ENUM_ENTRY(OpenGLES, 0x00000007)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BlendFactor)
	ENUM_ENTRY(Zero, 0x00000000)
	ENUM_ENTRY(One, 0x00000001)
	ENUM_ENTRY(Src, 0x00000002)
	ENUM_ENTRY(OneMinusSrc, 0x00000003)
	ENUM_ENTRY(SrcAlpha, 0x00000004)
	ENUM_ENTRY(OneMinusSrcAlpha, 0x00000005)
	ENUM_ENTRY(Dst, 0x00000006)
	ENUM_ENTRY(OneMinusDst, 0x00000007)
	ENUM_ENTRY(DstAlpha, 0x00000008)
	ENUM_ENTRY(OneMinusDstAlpha, 0x00000009)
	ENUM_ENTRY(SrcAlphaSaturated, 0x0000000A)
	ENUM_ENTRY(Constant, 0x0000000B)
	ENUM_ENTRY(OneMinusConstant, 0x0000000C)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BlendOperation)
	ENUM_ENTRY(Add, 0x00000000)
	ENUM_ENTRY(Subtract, 0x00000001)
	ENUM_ENTRY(ReverseSubtract, 0x00000002)
	ENUM_ENTRY(Min, 0x00000003)
	ENUM_ENTRY(Max, 0x00000004)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BufferBindingType)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Uniform, 0x00000001)
	ENUM_ENTRY(Storage, 0x00000002)
	ENUM_ENTRY(ReadOnlyStorage, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BufferMapAsyncStatus)
	ENUM_ENTRY(Success, 0x00000000)
	ENUM_ENTRY(Error, 0x00000001)
	ENUM_ENTRY(Unknown, 0x00000002)
	ENUM_ENTRY(DeviceLost, 0x00000003)
	ENUM_ENTRY(DestroyedBeforeCallback, 0x00000004)
	ENUM_ENTRY(UnmappedBeforeCallback, 0x00000005)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BufferMapState)
	ENUM_ENTRY(Unmapped, 0x00000000)
	ENUM_ENTRY(Pending, 0x00000001)
	ENUM_ENTRY(Mapped, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(CompareFunction)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Never, 0x00000001)
	ENUM_ENTRY(Less, 0x00000002)
	ENUM_ENTRY(LessEqual, 0x00000003)
	ENUM_ENTRY(Greater, 0x00000004)
	ENUM_ENTRY(GreaterEqual, 0x00000005)
	ENUM_ENTRY(Equal, 0x00000006)
	ENUM_ENTRY(NotEqual, 0x00000007)
	ENUM_ENTRY(Always, 0x00000008)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(CompilationInfoRequestStatus)
	ENUM_ENTRY(Success, 0x00000000)
	ENUM_ENTRY(Error, 0x00000001)
	ENUM_ENTRY(DeviceLost, 0x00000002)
	ENUM_ENTRY(Unknown, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(CompilationMessageType)
	ENUM_ENTRY(Error, 0x00000000)
	ENUM_ENTRY(Warning, 0x00000001)
	ENUM_ENTRY(Info, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(ComputePassTimestampLocation)
	ENUM_ENTRY(Beginning, 0x00000000)
	ENUM_ENTRY(End, 0x00000001)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(CreatePipelineAsyncStatus)
	ENUM_ENTRY(Success, 0x00000000)
	ENUM_ENTRY(ValidationError, 0x00000001)
	ENUM_ENTRY(InternalError, 0x00000002)
	ENUM_ENTRY(DeviceLost, 0x00000003)
	ENUM_ENTRY(DeviceDestroyed, 0x00000004)
	ENUM_ENTRY(Unknown, 0x00000005)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(CullMode)
	ENUM_ENTRY(None, 0x00000000)
	ENUM_ENTRY(Front, 0x00000001)
	ENUM_ENTRY(Back, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(DeviceLostReason)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Destroyed, 0x00000001)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(ErrorFilter)
	ENUM_ENTRY(Validation, 0x00000000)
	ENUM_ENTRY(OutOfMemory, 0x00000001)
	ENUM_ENTRY(Internal, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(ErrorType)
	ENUM_ENTRY(NoError, 0x00000000)
	ENUM_ENTRY(Validation, 0x00000001)
	ENUM_ENTRY(OutOfMemory, 0x00000002)
	ENUM_ENTRY(Internal, 0x00000003)
	ENUM_ENTRY(Unknown, 0x00000004)
	ENUM_ENTRY(DeviceLost, 0x00000005)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(ExternalTextureRotation)
	ENUM_ENTRY(Rotate0Degrees, 0x00000000)
	ENUM_ENTRY(Rotate90Degrees, 0x00000001)
	ENUM_ENTRY(Rotate180Degrees, 0x00000002)
	ENUM_ENTRY(Rotate270Degrees, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(FeatureName)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(DepthClipControl, 0x00000001)
	ENUM_ENTRY(Depth32FloatStencil8, 0x00000002)
	ENUM_ENTRY(TimestampQuery, 0x00000003)
	ENUM_ENTRY(PipelineStatisticsQuery, 0x00000004)
	ENUM_ENTRY(TextureCompressionBC, 0x00000005)
	ENUM_ENTRY(TextureCompressionETC2, 0x00000006)
	ENUM_ENTRY(TextureCompressionASTC, 0x00000007)
	ENUM_ENTRY(IndirectFirstInstance, 0x00000008)
	ENUM_ENTRY(ShaderF16, 0x00000009)
	ENUM_ENTRY(RG11B10UfloatRenderable, 0x0000000A)
	ENUM_ENTRY(BGRA8UnormStorage, 0x0000000B)
	ENUM_ENTRY(DawnShaderFloat16, 0x000003E9)
	ENUM_ENTRY(DawnInternalUsages, 0x000003EA)
	ENUM_ENTRY(DawnMultiPlanarFormats, 0x000003EB)
	ENUM_ENTRY(DawnNative, 0x000003EC)
	ENUM_ENTRY(ChromiumExperimentalDp4a, 0x000003ED)
	ENUM_ENTRY(TimestampQueryInsidePasses, 0x000003EE)
	ENUM_ENTRY(ImplicitDeviceSynchronization, 0x000003EF)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(FilterMode)
	ENUM_ENTRY(Nearest, 0x00000000)
	ENUM_ENTRY(Linear, 0x00000001)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(FrontFace)
	ENUM_ENTRY(CCW, 0x00000000)
	ENUM_ENTRY(CW, 0x00000001)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(IndexFormat)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Uint16, 0x00000001)
	ENUM_ENTRY(Uint32, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(LoadOp)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Clear, 0x00000001)
	ENUM_ENTRY(Load, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(LoggingType)
	ENUM_ENTRY(Verbose, 0x00000000)
	ENUM_ENTRY(Info, 0x00000001)
	ENUM_ENTRY(Warning, 0x00000002)
	ENUM_ENTRY(Error, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(PipelineStatisticName)
	ENUM_ENTRY(VertexShaderInvocations, 0x00000000)
	ENUM_ENTRY(ClipperInvocations, 0x00000001)
	ENUM_ENTRY(ClipperPrimitivesOut, 0x00000002)
	ENUM_ENTRY(FragmentShaderInvocations, 0x00000003)
	ENUM_ENTRY(ComputeShaderInvocations, 0x00000004)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(PowerPreference)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(LowPower, 0x00000001)
	ENUM_ENTRY(HighPerformance, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(PresentMode)
	ENUM_ENTRY(Immediate, 0x00000000)
	ENUM_ENTRY(Mailbox, 0x00000001)
	ENUM_ENTRY(Fifo, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(PrimitiveTopology)
	ENUM_ENTRY(PointList, 0x00000000)
	ENUM_ENTRY(LineList, 0x00000001)
	ENUM_ENTRY(LineStrip, 0x00000002)
	ENUM_ENTRY(TriangleList, 0x00000003)
	ENUM_ENTRY(TriangleStrip, 0x00000004)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(QueryType)
	ENUM_ENTRY(Occlusion, 0x00000000)
	ENUM_ENTRY(PipelineStatistics, 0x00000001)
	ENUM_ENTRY(Timestamp, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(QueueWorkDoneStatus)
	ENUM_ENTRY(Success, 0x00000000)
	ENUM_ENTRY(Error, 0x00000001)
	ENUM_ENTRY(Unknown, 0x00000002)
	ENUM_ENTRY(DeviceLost, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(RenderPassTimestampLocation)
	ENUM_ENTRY(Beginning, 0x00000000)
	ENUM_ENTRY(End, 0x00000001)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(RequestAdapterStatus)
	ENUM_ENTRY(Success, 0x00000000)
	ENUM_ENTRY(Unavailable, 0x00000001)
	ENUM_ENTRY(Error, 0x00000002)
	ENUM_ENTRY(Unknown, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(RequestDeviceStatus)
	ENUM_ENTRY(Success, 0x00000000)
	ENUM_ENTRY(Error, 0x00000001)
	ENUM_ENTRY(Unknown, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(SType)
	ENUM_ENTRY(Invalid, 0x00000000)
	ENUM_ENTRY(SurfaceDescriptorFromMetalLayer, 0x00000001)
	ENUM_ENTRY(SurfaceDescriptorFromWindowsHWND, 0x00000002)
	ENUM_ENTRY(SurfaceDescriptorFromXlibWindow, 0x00000003)
	ENUM_ENTRY(SurfaceDescriptorFromCanvasHTMLSelector, 0x00000004)
	ENUM_ENTRY(ShaderModuleSPIRVDescriptor, 0x00000005)
	ENUM_ENTRY(ShaderModuleWGSLDescriptor, 0x00000006)
	ENUM_ENTRY(PrimitiveDepthClipControl, 0x00000007)
	ENUM_ENTRY(SurfaceDescriptorFromWaylandSurface, 0x00000008)
	ENUM_ENTRY(SurfaceDescriptorFromAndroidNativeWindow, 0x00000009)
	ENUM_ENTRY(SurfaceDescriptorFromWindowsCoreWindow, 0x0000000B)
	ENUM_ENTRY(ExternalTextureBindingEntry, 0x0000000C)
	ENUM_ENTRY(ExternalTextureBindingLayout, 0x0000000D)
	ENUM_ENTRY(SurfaceDescriptorFromWindowsSwapChainPanel, 0x0000000E)
	ENUM_ENTRY(RenderPassDescriptorMaxDrawCount, 0x0000000F)
	ENUM_ENTRY(DawnTextureInternalUsageDescriptor, 0x000003E8)
	ENUM_ENTRY(DawnTogglesDeviceDescriptor, 0x000003EA)
	ENUM_ENTRY(DawnEncoderInternalUsageDescriptor, 0x000003EB)
	ENUM_ENTRY(DawnInstanceDescriptor, 0x000003EC)
	ENUM_ENTRY(DawnCacheDeviceDescriptor, 0x000003ED)
	ENUM_ENTRY(DawnAdapterPropertiesPowerPreference, 0x000003EE)
	ENUM_ENTRY(DawnBufferDescriptorErrorInfoFromWireClient, 0x000003EF)
	ENUM_ENTRY(DawnTogglesDescriptor, 0x000003F0)
	ENUM_ENTRY(DawnShaderModuleSPIRVOptionsDescriptor, 0x000003F1)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(SamplerBindingType)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Filtering, 0x00000001)
	ENUM_ENTRY(NonFiltering, 0x00000002)
	ENUM_ENTRY(Comparison, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(StencilOperation)
	ENUM_ENTRY(Keep, 0x00000000)
	ENUM_ENTRY(Zero, 0x00000001)
	ENUM_ENTRY(Replace, 0x00000002)
	ENUM_ENTRY(Invert, 0x00000003)
	ENUM_ENTRY(IncrementClamp, 0x00000004)
	ENUM_ENTRY(DecrementClamp, 0x00000005)
	ENUM_ENTRY(IncrementWrap, 0x00000006)
	ENUM_ENTRY(DecrementWrap, 0x00000007)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(StorageTextureAccess)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(WriteOnly, 0x00000001)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(StoreOp)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Store, 0x00000001)
	ENUM_ENTRY(Discard, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureAspect)
	ENUM_ENTRY(All, 0x00000000)
	ENUM_ENTRY(StencilOnly, 0x00000001)
	ENUM_ENTRY(DepthOnly, 0x00000002)
	ENUM_ENTRY(Plane0Only, 0x00000003)
	ENUM_ENTRY(Plane1Only, 0x00000004)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureComponentType)
	ENUM_ENTRY(Float, 0x00000000)
	ENUM_ENTRY(Sint, 0x00000001)
	ENUM_ENTRY(Uint, 0x00000002)
	ENUM_ENTRY(DepthComparison, 0x00000003)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureDimension)
	ENUM_ENTRY(_1D, 0x00000000)
	ENUM_ENTRY(_2D, 0x00000001)
	ENUM_ENTRY(_3D, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureFormat)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(R8Unorm, 0x00000001)
	ENUM_ENTRY(R8Snorm, 0x00000002)
	ENUM_ENTRY(R8Uint, 0x00000003)
	ENUM_ENTRY(R8Sint, 0x00000004)
	ENUM_ENTRY(R16Uint, 0x00000005)
	ENUM_ENTRY(R16Sint, 0x00000006)
	ENUM_ENTRY(R16Float, 0x00000007)
	ENUM_ENTRY(RG8Unorm, 0x00000008)
	ENUM_ENTRY(RG8Snorm, 0x00000009)
	ENUM_ENTRY(RG8Uint, 0x0000000A)
	ENUM_ENTRY(RG8Sint, 0x0000000B)
	ENUM_ENTRY(R32Float, 0x0000000C)
	ENUM_ENTRY(R32Uint, 0x0000000D)
	ENUM_ENTRY(R32Sint, 0x0000000E)
	ENUM_ENTRY(RG16Uint, 0x0000000F)
	ENUM_ENTRY(RG16Sint, 0x00000010)
	ENUM_ENTRY(RG16Float, 0x00000011)
	ENUM_ENTRY(RGBA8Unorm, 0x00000012)
	ENUM_ENTRY(RGBA8UnormSrgb, 0x00000013)
	ENUM_ENTRY(RGBA8Snorm, 0x00000014)
	ENUM_ENTRY(RGBA8Uint, 0x00000015)
	ENUM_ENTRY(RGBA8Sint, 0x00000016)
	ENUM_ENTRY(BGRA8Unorm, 0x00000017)
	ENUM_ENTRY(BGRA8UnormSrgb, 0x00000018)
	ENUM_ENTRY(RGB10A2Unorm, 0x00000019)
	ENUM_ENTRY(RG11B10Ufloat, 0x0000001A)
	ENUM_ENTRY(RGB9E5Ufloat, 0x0000001B)
	ENUM_ENTRY(RG32Float, 0x0000001C)
	ENUM_ENTRY(RG32Uint, 0x0000001D)
	ENUM_ENTRY(RG32Sint, 0x0000001E)
	ENUM_ENTRY(RGBA16Uint, 0x0000001F)
	ENUM_ENTRY(RGBA16Sint, 0x00000020)
	ENUM_ENTRY(RGBA16Float, 0x00000021)
	ENUM_ENTRY(RGBA32Float, 0x00000022)
	ENUM_ENTRY(RGBA32Uint, 0x00000023)
	ENUM_ENTRY(RGBA32Sint, 0x00000024)
	ENUM_ENTRY(Stencil8, 0x00000025)
	ENUM_ENTRY(Depth16Unorm, 0x00000026)
	ENUM_ENTRY(Depth24Plus, 0x00000027)
	ENUM_ENTRY(Depth24PlusStencil8, 0x00000028)
	ENUM_ENTRY(Depth32Float, 0x00000029)
	ENUM_ENTRY(Depth32FloatStencil8, 0x0000002A)
	ENUM_ENTRY(BC1RGBAUnorm, 0x0000002B)
	ENUM_ENTRY(BC1RGBAUnormSrgb, 0x0000002C)
	ENUM_ENTRY(BC2RGBAUnorm, 0x0000002D)
	ENUM_ENTRY(BC2RGBAUnormSrgb, 0x0000002E)
	ENUM_ENTRY(BC3RGBAUnorm, 0x0000002F)
	ENUM_ENTRY(BC3RGBAUnormSrgb, 0x00000030)
	ENUM_ENTRY(BC4RUnorm, 0x00000031)
	ENUM_ENTRY(BC4RSnorm, 0x00000032)
	ENUM_ENTRY(BC5RGUnorm, 0x00000033)
	ENUM_ENTRY(BC5RGSnorm, 0x00000034)
	ENUM_ENTRY(BC6HRGBUfloat, 0x00000035)
	ENUM_ENTRY(BC6HRGBFloat, 0x00000036)
	ENUM_ENTRY(BC7RGBAUnorm, 0x00000037)
	ENUM_ENTRY(BC7RGBAUnormSrgb, 0x00000038)
	ENUM_ENTRY(ETC2RGB8Unorm, 0x00000039)
	ENUM_ENTRY(ETC2RGB8UnormSrgb, 0x0000003A)
	ENUM_ENTRY(ETC2RGB8A1Unorm, 0x0000003B)
	ENUM_ENTRY(ETC2RGB8A1UnormSrgb, 0x0000003C)
	ENUM_ENTRY(ETC2RGBA8Unorm, 0x0000003D)
	ENUM_ENTRY(ETC2RGBA8UnormSrgb, 0x0000003E)
	ENUM_ENTRY(EACR11Unorm, 0x0000003F)
	ENUM_ENTRY(EACR11Snorm, 0x00000040)
	ENUM_ENTRY(EACRG11Unorm, 0x00000041)
	ENUM_ENTRY(EACRG11Snorm, 0x00000042)
	ENUM_ENTRY(ASTC4x4Unorm, 0x00000043)
	ENUM_ENTRY(ASTC4x4UnormSrgb, 0x00000044)
	ENUM_ENTRY(ASTC5x4Unorm, 0x00000045)
	ENUM_ENTRY(ASTC5x4UnormSrgb, 0x00000046)
	ENUM_ENTRY(ASTC5x5Unorm, 0x00000047)
	ENUM_ENTRY(ASTC5x5UnormSrgb, 0x00000048)
	ENUM_ENTRY(ASTC6x5Unorm, 0x00000049)
	ENUM_ENTRY(ASTC6x5UnormSrgb, 0x0000004A)
	ENUM_ENTRY(ASTC6x6Unorm, 0x0000004B)
	ENUM_ENTRY(ASTC6x6UnormSrgb, 0x0000004C)
	ENUM_ENTRY(ASTC8x5Unorm, 0x0000004D)
	ENUM_ENTRY(ASTC8x5UnormSrgb, 0x0000004E)
	ENUM_ENTRY(ASTC8x6Unorm, 0x0000004F)
	ENUM_ENTRY(ASTC8x6UnormSrgb, 0x00000050)
	ENUM_ENTRY(ASTC8x8Unorm, 0x00000051)
	ENUM_ENTRY(ASTC8x8UnormSrgb, 0x00000052)
	ENUM_ENTRY(ASTC10x5Unorm, 0x00000053)
	ENUM_ENTRY(ASTC10x5UnormSrgb, 0x00000054)
	ENUM_ENTRY(ASTC10x6Unorm, 0x00000055)
	ENUM_ENTRY(ASTC10x6UnormSrgb, 0x00000056)
	ENUM_ENTRY(ASTC10x8Unorm, 0x00000057)
	ENUM_ENTRY(ASTC10x8UnormSrgb, 0x00000058)
	ENUM_ENTRY(ASTC10x10Unorm, 0x00000059)
	ENUM_ENTRY(ASTC10x10UnormSrgb, 0x0000005A)
	ENUM_ENTRY(ASTC12x10Unorm, 0x0000005B)
	ENUM_ENTRY(ASTC12x10UnormSrgb, 0x0000005C)
	ENUM_ENTRY(ASTC12x12Unorm, 0x0000005D)
	ENUM_ENTRY(ASTC12x12UnormSrgb, 0x0000005E)
	ENUM_ENTRY(R8BG8Biplanar420Unorm, 0x0000005F)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureSampleType)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Float, 0x00000001)
	ENUM_ENTRY(UnfilterableFloat, 0x00000002)
	ENUM_ENTRY(Depth, 0x00000003)
	ENUM_ENTRY(Sint, 0x00000004)
	ENUM_ENTRY(Uint, 0x00000005)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureViewDimension)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(_1D, 0x00000001)
	ENUM_ENTRY(_2D, 0x00000002)
	ENUM_ENTRY(_2DArray, 0x00000003)
	ENUM_ENTRY(Cube, 0x00000004)
	ENUM_ENTRY(CubeArray, 0x00000005)
	ENUM_ENTRY(_3D, 0x00000006)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(VertexFormat)
	ENUM_ENTRY(Undefined, 0x00000000)
	ENUM_ENTRY(Uint8x2, 0x00000001)
	ENUM_ENTRY(Uint8x4, 0x00000002)
	ENUM_ENTRY(Sint8x2, 0x00000003)
	ENUM_ENTRY(Sint8x4, 0x00000004)
	ENUM_ENTRY(Unorm8x2, 0x00000005)
	ENUM_ENTRY(Unorm8x4, 0x00000006)
	ENUM_ENTRY(Snorm8x2, 0x00000007)
	ENUM_ENTRY(Snorm8x4, 0x00000008)
	ENUM_ENTRY(Uint16x2, 0x00000009)
	ENUM_ENTRY(Uint16x4, 0x0000000A)
	ENUM_ENTRY(Sint16x2, 0x0000000B)
	ENUM_ENTRY(Sint16x4, 0x0000000C)
	ENUM_ENTRY(Unorm16x2, 0x0000000D)
	ENUM_ENTRY(Unorm16x4, 0x0000000E)
	ENUM_ENTRY(Snorm16x2, 0x0000000F)
	ENUM_ENTRY(Snorm16x4, 0x00000010)
	ENUM_ENTRY(Float16x2, 0x00000011)
	ENUM_ENTRY(Float16x4, 0x00000012)
	ENUM_ENTRY(Float32, 0x00000013)
	ENUM_ENTRY(Float32x2, 0x00000014)
	ENUM_ENTRY(Float32x3, 0x00000015)
	ENUM_ENTRY(Float32x4, 0x00000016)
	ENUM_ENTRY(Uint32, 0x00000017)
	ENUM_ENTRY(Uint32x2, 0x00000018)
	ENUM_ENTRY(Uint32x3, 0x00000019)
	ENUM_ENTRY(Uint32x4, 0x0000001A)
	ENUM_ENTRY(Sint32, 0x0000001B)
	ENUM_ENTRY(Sint32x2, 0x0000001C)
	ENUM_ENTRY(Sint32x3, 0x0000001D)
	ENUM_ENTRY(Sint32x4, 0x0000001E)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(VertexStepMode)
	ENUM_ENTRY(Vertex, 0x00000000)
	ENUM_ENTRY(Instance, 0x00000001)
	ENUM_ENTRY(VertexBufferNotUsed, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BufferUsage)
	ENUM_ENTRY(None, 0x00000000)
	ENUM_ENTRY(MapRead, 0x00000001)
	ENUM_ENTRY(MapWrite, 0x00000002)
	ENUM_ENTRY(CopySrc, 0x00000004)
	ENUM_ENTRY(CopyDst, 0x00000008)
	ENUM_ENTRY(Index, 0x00000010)
	ENUM_ENTRY(Vertex, 0x00000020)
	ENUM_ENTRY(Uniform, 0x00000040)
	ENUM_ENTRY(Storage, 0x00000080)
	ENUM_ENTRY(Indirect, 0x00000100)
	ENUM_ENTRY(QueryResolve, 0x00000200)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(BufferUsageFlags)
END
ENUM(ColorWriteMask)
	ENUM_ENTRY(None, 0x00000000)
	ENUM_ENTRY(Red, 0x00000001)
	ENUM_ENTRY(Green, 0x00000002)
	ENUM_ENTRY(Blue, 0x00000004)
	ENUM_ENTRY(Alpha, 0x00000008)
	ENUM_ENTRY(All, 0x0000000F)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(ColorWriteMaskFlags)
END
ENUM(MapMode)
	ENUM_ENTRY(None, 0x00000000)
	ENUM_ENTRY(Read, 0x00000001)
	ENUM_ENTRY(Write, 0x00000002)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(MapModeFlags)
END
ENUM(ShaderStage)
	ENUM_ENTRY(None, 0x00000000)
	ENUM_ENTRY(Vertex, 0x00000001)
	ENUM_ENTRY(Fragment, 0x00000002)
	ENUM_ENTRY(Compute, 0x00000004)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(ShaderStageFlags)
END
ENUM(TextureUsage)
	ENUM_ENTRY(None, 0x00000000)
	ENUM_ENTRY(CopySrc, 0x00000001)
	ENUM_ENTRY(CopyDst, 0x00000002)
	ENUM_ENTRY(TextureBinding, 0x00000004)
	ENUM_ENTRY(StorageBinding, 0x00000008)
	ENUM_ENTRY(RenderAttachment, 0x00000010)
	ENUM_ENTRY(Present, 0x00000020)
	ENUM_ENTRY(Force32, 0x7FFFFFFF)
END
ENUM(TextureUsageFlags)
END

// Structs
STRUCT(ChainedStruct)
	inline void setDefault();
END

STRUCT(ChainedStructOut)
	inline void setDefault();
END

STRUCT(BlendComponent)
	inline void setDefault();
END

STRUCT(Color)
	Color(double r, double g, double b, double a) : WGPUColor{ r, g, b, a } {}
	inline void setDefault();
END

STRUCT(ComputePassTimestampWrite)
	inline void setDefault();
END

STRUCT(DawnAdapterPropertiesPowerPreference)
	inline void setDefault();
END

STRUCT(DawnBufferDescriptorErrorInfoFromWireClient)
	inline void setDefault();
END

STRUCT(DawnCacheDeviceDescriptor)
	inline void setDefault();
END

STRUCT(DawnEncoderInternalUsageDescriptor)
	inline void setDefault();
END

STRUCT(DawnInstanceDescriptor)
	inline void setDefault();
END

STRUCT(DawnShaderModuleSPIRVOptionsDescriptor)
	inline void setDefault();
END

STRUCT(DawnTextureInternalUsageDescriptor)
	inline void setDefault();
END

STRUCT(DawnTogglesDescriptor)
	inline void setDefault();
END

STRUCT(DawnTogglesDeviceDescriptor)
	inline void setDefault();
END

STRUCT(Extent2D)
	inline void setDefault();
END

STRUCT(Extent3D)
	Extent3D(uint32_t width, uint32_t height, uint32_t depthOrArrayLayers) : WGPUExtent3D{ width, height, depthOrArrayLayers } {}
	inline void setDefault();
END

STRUCT(ExternalTextureBindingEntry)
	inline void setDefault();
END

STRUCT(ExternalTextureBindingLayout)
	inline void setDefault();
END

STRUCT(Limits)
	inline void setDefault();
END

STRUCT(Origin2D)
	inline void setDefault();
END

STRUCT(Origin3D)
	Origin3D(uint32_t x, uint32_t y, uint32_t z) : WGPUOrigin3D{ x, y, z } {}
	inline void setDefault();
END

STRUCT(PrimitiveDepthClipControl)
	inline void setDefault();
END

STRUCT(RenderPassDepthStencilAttachment)
	inline void setDefault();
END

STRUCT(RenderPassDescriptorMaxDrawCount)
	inline void setDefault();
END

STRUCT(RenderPassTimestampWrite)
	inline void setDefault();
END

STRUCT(ShaderModuleSPIRVDescriptor)
	inline void setDefault();
END

STRUCT(ShaderModuleWGSLDescriptor)
	inline void setDefault();
END

STRUCT(StencilFaceState)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromAndroidNativeWindow)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromCanvasHTMLSelector)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromMetalLayer)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromWaylandSurface)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromWindowsCoreWindow)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromWindowsHWND)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromWindowsSwapChainPanel)
	inline void setDefault();
END

STRUCT(SurfaceDescriptorFromXlibWindow)
	inline void setDefault();
END

STRUCT(VertexAttribute)
	inline void setDefault();
END

STRUCT(BlendState)
	inline void setDefault();
END

STRUCT(RenderPassColorAttachment)
	inline void setDefault();
END

STRUCT(VertexBufferLayout)
	inline void setDefault();
END


// Descriptors
DESCRIPTOR(AdapterProperties)
	inline void setDefault();
END

DESCRIPTOR(BindGroupEntry)
	inline void setDefault();
END

DESCRIPTOR(BufferBindingLayout)
	inline void setDefault();
END

DESCRIPTOR(BufferDescriptor)
	inline void setDefault();
END

DESCRIPTOR(CommandBufferDescriptor)
	inline void setDefault();
END

DESCRIPTOR(CommandEncoderDescriptor)
	inline void setDefault();
END

DESCRIPTOR(CompilationMessage)
	inline void setDefault();
END

DESCRIPTOR(ConstantEntry)
	inline void setDefault();
END

DESCRIPTOR(CopyTextureForBrowserOptions)
	inline void setDefault();
END

DESCRIPTOR(InstanceDescriptor)
	inline void setDefault();
END

DESCRIPTOR(MultisampleState)
	inline void setDefault();
END

DESCRIPTOR(PipelineLayoutDescriptor)
	inline void setDefault();
END

DESCRIPTOR(PrimitiveState)
	inline void setDefault();
END

DESCRIPTOR(QuerySetDescriptor)
	inline void setDefault();
END

DESCRIPTOR(QueueDescriptor)
	inline void setDefault();
END

DESCRIPTOR(RenderBundleDescriptor)
	inline void setDefault();
END

DESCRIPTOR(RenderBundleEncoderDescriptor)
	inline void setDefault();
END

DESCRIPTOR(RequestAdapterOptions)
	inline void setDefault();
END

DESCRIPTOR(SamplerBindingLayout)
	inline void setDefault();
END

DESCRIPTOR(SamplerDescriptor)
	inline void setDefault();
END

DESCRIPTOR(ShaderModuleDescriptor)
	inline void setDefault();
END

DESCRIPTOR(StorageTextureBindingLayout)
	inline void setDefault();
END

DESCRIPTOR(SurfaceDescriptor)
	inline void setDefault();
END

DESCRIPTOR(SwapChainDescriptor)
	inline void setDefault();
END

DESCRIPTOR(TextureBindingLayout)
	inline void setDefault();
END

DESCRIPTOR(TextureDataLayout)
	inline void setDefault();
END

DESCRIPTOR(TextureViewDescriptor)
	inline void setDefault();
END

DESCRIPTOR(BindGroupDescriptor)
	inline void setDefault();
END

DESCRIPTOR(BindGroupLayoutEntry)
	inline void setDefault();
END

DESCRIPTOR(CompilationInfo)
	inline void setDefault();
END

DESCRIPTOR(ComputePassDescriptor)
	inline void setDefault();
END

DESCRIPTOR(DepthStencilState)
	inline void setDefault();
END

DESCRIPTOR(ExternalTextureDescriptor)
	inline void setDefault();
END

DESCRIPTOR(ImageCopyBuffer)
	inline void setDefault();
END

DESCRIPTOR(ImageCopyExternalTexture)
	inline void setDefault();
END

DESCRIPTOR(ImageCopyTexture)
	inline void setDefault();
END

DESCRIPTOR(ProgrammableStageDescriptor)
	inline void setDefault();
END

DESCRIPTOR(RequiredLimits)
	inline void setDefault();
END

DESCRIPTOR(SupportedLimits)
	inline void setDefault();
END

DESCRIPTOR(TextureDescriptor)
	inline void setDefault();
END

DESCRIPTOR(BindGroupLayoutDescriptor)
	inline void setDefault();
END

DESCRIPTOR(ColorTargetState)
	inline void setDefault();
END

DESCRIPTOR(ComputePipelineDescriptor)
	inline void setDefault();
END

DESCRIPTOR(DeviceDescriptor)
	inline void setDefault();
END

DESCRIPTOR(RenderPassDescriptor)
	inline void setDefault();
END

DESCRIPTOR(VertexState)
	inline void setDefault();
END

DESCRIPTOR(FragmentState)
	inline void setDefault();
END

DESCRIPTOR(RenderPipelineDescriptor)
	inline void setDefault();
END


// Handles forward declarations
class Adapter;
class BindGroup;
class BindGroupLayout;
class Buffer;
class CommandBuffer;
class CommandEncoder;
class ComputePassEncoder;
class ComputePipeline;
class Device;
class ExternalTexture;
class Instance;
class PipelineLayout;
class QuerySet;
class Queue;
class RenderBundle;
class RenderBundleEncoder;
class RenderPassEncoder;
class RenderPipeline;
class Sampler;
class ShaderModule;
class Surface;
class SwapChain;
class Texture;
class TextureView;

// Callback types
using BufferMapCallback = std::function<void(BufferMapAsyncStatus status)>;
using CompilationInfoCallback = std::function<void(CompilationInfoRequestStatus status, const CompilationInfo& compilationInfo)>;
using CreateComputePipelineAsyncCallback = std::function<void(CreatePipelineAsyncStatus status, ComputePipeline pipeline, char const * message)>;
using CreateRenderPipelineAsyncCallback = std::function<void(CreatePipelineAsyncStatus status, RenderPipeline pipeline, char const * message)>;
using DeviceLostCallback = std::function<void(DeviceLostReason reason, char const * message)>;
using ErrorCallback = std::function<void(ErrorType type, char const * message)>;
using LoggingCallback = std::function<void(LoggingType type, char const * message)>;
using QueueWorkDoneCallback = std::function<void(QueueWorkDoneStatus status)>;
using RequestAdapterCallback = std::function<void(RequestAdapterStatus status, Adapter adapter, char const * message)>;
using RequestDeviceCallback = std::function<void(RequestDeviceStatus status, Device device, char const * message)>;
using ProcDeviceSetDeviceLostCallback = std::function<void(Device device, DeviceLostCallback&& callback)>;
using ProcDeviceSetLoggingCallback = std::function<void(Device device, LoggingCallback&& callback)>;
using ProcDeviceSetUncapturedErrorCallback = std::function<void(Device device, ErrorCallback&& callback)>;

// Handles detailed declarations
HANDLE(Adapter)
	Device createDevice(const DeviceDescriptor& descriptor);
	size_t enumerateFeatures(FeatureName * features);
	Instance getInstance();
	bool getLimits(SupportedLimits * limits);
	void getProperties(AdapterProperties * properties);
	bool hasFeature(FeatureName feature);
	std::unique_ptr<RequestDeviceCallback> requestDevice(const DeviceDescriptor& descriptor, RequestDeviceCallback&& callback);
	void reference();
	void release();
	Device requestDevice(const DeviceDescriptor& descriptor);
END

HANDLE(BindGroup)
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(BindGroupLayout)
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(Buffer)
	void destroy();
	void const * getConstMappedRange(size_t offset, size_t size);
	BufferMapState getMapState();
	void * getMappedRange(size_t offset, size_t size);
	uint64_t getSize();
	BufferUsage getUsage();
	std::unique_ptr<BufferMapCallback> mapAsync(MapModeFlags mode, size_t offset, size_t size, BufferMapCallback&& callback);
	void setLabel(char const * label);
	void unmap();
	void reference();
	void release();
END

HANDLE(CommandBuffer)
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(CommandEncoder)
	ComputePassEncoder beginComputePass(const ComputePassDescriptor& descriptor);
	RenderPassEncoder beginRenderPass(const RenderPassDescriptor& descriptor);
	void clearBuffer(Buffer buffer, uint64_t offset, uint64_t size);
	void copyBufferToBuffer(Buffer source, uint64_t sourceOffset, Buffer destination, uint64_t destinationOffset, uint64_t size);
	void copyBufferToTexture(const ImageCopyBuffer& source, const ImageCopyTexture& destination, const Extent3D& copySize);
	void copyTextureToBuffer(const ImageCopyTexture& source, const ImageCopyBuffer& destination, const Extent3D& copySize);
	void copyTextureToTexture(const ImageCopyTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize);
	void copyTextureToTextureInternal(const ImageCopyTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize);
	CommandBuffer finish(const CommandBufferDescriptor& descriptor);
	void injectValidationError(char const * message);
	void insertDebugMarker(char const * markerLabel);
	void popDebugGroup();
	void pushDebugGroup(char const * groupLabel);
	void resolveQuerySet(QuerySet querySet, uint32_t firstQuery, uint32_t queryCount, Buffer destination, uint64_t destinationOffset);
	void setLabel(char const * label);
	void writeBuffer(Buffer buffer, uint64_t bufferOffset, uint8_t const * data, uint64_t size);
	void writeTimestamp(QuerySet querySet, uint32_t queryIndex);
	void reference();
	void release();
END

HANDLE(ComputePassEncoder)
	void dispatch(uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ);
	void dispatchIndirect(Buffer indirectBuffer, uint64_t indirectOffset);
	void dispatchWorkgroups(uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ);
	void dispatchWorkgroupsIndirect(Buffer indirectBuffer, uint64_t indirectOffset);
	void end();
	void endPass();
	void insertDebugMarker(char const * markerLabel);
	void popDebugGroup();
	void pushDebugGroup(char const * groupLabel);
	void setBindGroup(uint32_t groupIndex, BindGroup group, uint32_t dynamicOffsetCount, uint32_t const * dynamicOffsets);
	void setBindGroup(uint32_t groupIndex, BindGroup group, const std::vector<uint32_t>& dynamicOffsets);
	void setBindGroup(uint32_t groupIndex, BindGroup group, const uint32_t& dynamicOffsets);
	void setLabel(char const * label);
	void setPipeline(ComputePipeline pipeline);
	void writeTimestamp(QuerySet querySet, uint32_t queryIndex);
	void reference();
	void release();
END

HANDLE(ComputePipeline)
	BindGroupLayout getBindGroupLayout(uint32_t groupIndex);
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(Device)
	BindGroup createBindGroup(const BindGroupDescriptor& descriptor);
	BindGroupLayout createBindGroupLayout(const BindGroupLayoutDescriptor& descriptor);
	Buffer createBuffer(const BufferDescriptor& descriptor);
	CommandEncoder createCommandEncoder(const CommandEncoderDescriptor& descriptor);
	ComputePipeline createComputePipeline(const ComputePipelineDescriptor& descriptor);
	std::unique_ptr<CreateComputePipelineAsyncCallback> createComputePipelineAsync(const ComputePipelineDescriptor& descriptor, CreateComputePipelineAsyncCallback&& callback);
	Buffer createErrorBuffer(const BufferDescriptor& descriptor);
	ExternalTexture createErrorExternalTexture();
	Texture createErrorTexture(const TextureDescriptor& descriptor);
	ExternalTexture createExternalTexture(const ExternalTextureDescriptor& externalTextureDescriptor);
	PipelineLayout createPipelineLayout(const PipelineLayoutDescriptor& descriptor);
	QuerySet createQuerySet(const QuerySetDescriptor& descriptor);
	RenderBundleEncoder createRenderBundleEncoder(const RenderBundleEncoderDescriptor& descriptor);
	RenderPipeline createRenderPipeline(const RenderPipelineDescriptor& descriptor);
	std::unique_ptr<CreateRenderPipelineAsyncCallback> createRenderPipelineAsync(const RenderPipelineDescriptor& descriptor, CreateRenderPipelineAsyncCallback&& callback);
	Sampler createSampler(const SamplerDescriptor& descriptor);
	ShaderModule createShaderModule(const ShaderModuleDescriptor& descriptor);
	SwapChain createSwapChain(Surface surface, const SwapChainDescriptor& descriptor);
	Texture createTexture(const TextureDescriptor& descriptor);
	void destroy();
	size_t enumerateFeatures(FeatureName * features);
	void forceLoss(DeviceLostReason type, char const * message);
	Adapter getAdapter();
	bool getLimits(SupportedLimits * limits);
	Queue getQueue();
	bool hasFeature(FeatureName feature);
	void injectError(ErrorType type, char const * message);
	std::unique_ptr<ErrorCallback> popErrorScope(ErrorCallback&& callback);
	void pushErrorScope(ErrorFilter filter);
	std::unique_ptr<DeviceLostCallback> setDeviceLostCallback(DeviceLostCallback&& callback);
	void setLabel(char const * label);
	std::unique_ptr<LoggingCallback> setLoggingCallback(LoggingCallback&& callback);
	std::unique_ptr<ErrorCallback> setUncapturedErrorCallback(ErrorCallback&& callback);
	void tick();
	void validateTextureDescriptor(const TextureDescriptor& descriptor);
	void reference();
	void release();
END

HANDLE(ExternalTexture)
	void destroy();
	void expire();
	void refresh();
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(Instance)
	Surface createSurface(const SurfaceDescriptor& descriptor);
	void processEvents();
	std::unique_ptr<RequestAdapterCallback> requestAdapter(const RequestAdapterOptions& options, RequestAdapterCallback&& callback);
	void reference();
	void release();
	Adapter requestAdapter(const RequestAdapterOptions& options);
END

HANDLE(PipelineLayout)
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(QuerySet)
	void destroy();
	uint32_t getCount();
	QueryType getType();
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(Queue)
	void copyExternalTextureForBrowser(const ImageCopyExternalTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize, const CopyTextureForBrowserOptions& options);
	void copyTextureForBrowser(const ImageCopyTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize, const CopyTextureForBrowserOptions& options);
	std::unique_ptr<QueueWorkDoneCallback> onSubmittedWorkDone(uint64_t signalValue, QueueWorkDoneCallback&& callback);
	void setLabel(char const * label);
	void submit(uint32_t commandCount, CommandBuffer const * commands);
	void submit(const std::vector<WGPUCommandBuffer>& commands);
	void submit(const WGPUCommandBuffer& commands);
	void writeBuffer(Buffer buffer, uint64_t bufferOffset, void const * data, size_t size);
	void writeTexture(const ImageCopyTexture& destination, void const * data, size_t dataSize, const TextureDataLayout& dataLayout, const Extent3D& writeSize);
	void reference();
	void release();
END

HANDLE(RenderBundle)
	void reference();
	void release();
END

HANDLE(RenderBundleEncoder)
	void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
	void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance);
	void drawIndexedIndirect(Buffer indirectBuffer, uint64_t indirectOffset);
	void drawIndirect(Buffer indirectBuffer, uint64_t indirectOffset);
	RenderBundle finish(const RenderBundleDescriptor& descriptor);
	void insertDebugMarker(char const * markerLabel);
	void popDebugGroup();
	void pushDebugGroup(char const * groupLabel);
	void setBindGroup(uint32_t groupIndex, BindGroup group, uint32_t dynamicOffsetCount, uint32_t const * dynamicOffsets);
	void setBindGroup(uint32_t groupIndex, BindGroup group, const std::vector<uint32_t>& dynamicOffsets);
	void setBindGroup(uint32_t groupIndex, BindGroup group, const uint32_t& dynamicOffsets);
	void setIndexBuffer(Buffer buffer, IndexFormat format, uint64_t offset, uint64_t size);
	void setLabel(char const * label);
	void setPipeline(RenderPipeline pipeline);
	void setVertexBuffer(uint32_t slot, Buffer buffer, uint64_t offset, uint64_t size);
	void reference();
	void release();
END

HANDLE(RenderPassEncoder)
	void beginOcclusionQuery(uint32_t queryIndex);
	void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
	void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance);
	void drawIndexedIndirect(Buffer indirectBuffer, uint64_t indirectOffset);
	void drawIndirect(Buffer indirectBuffer, uint64_t indirectOffset);
	void end();
	void endOcclusionQuery();
	void endPass();
	void executeBundles(uint32_t bundleCount, RenderBundle const * bundles);
	void executeBundles(const std::vector<WGPURenderBundle>& bundles);
	void executeBundles(const WGPURenderBundle& bundles);
	void insertDebugMarker(char const * markerLabel);
	void popDebugGroup();
	void pushDebugGroup(char const * groupLabel);
	void setBindGroup(uint32_t groupIndex, BindGroup group, uint32_t dynamicOffsetCount, uint32_t const * dynamicOffsets);
	void setBindGroup(uint32_t groupIndex, BindGroup group, const std::vector<uint32_t>& dynamicOffsets);
	void setBindGroup(uint32_t groupIndex, BindGroup group, const uint32_t& dynamicOffsets);
	void setBlendConstant(const Color& color);
	void setIndexBuffer(Buffer buffer, IndexFormat format, uint64_t offset, uint64_t size);
	void setLabel(char const * label);
	void setPipeline(RenderPipeline pipeline);
	void setScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
	void setStencilReference(uint32_t reference);
	void setVertexBuffer(uint32_t slot, Buffer buffer, uint64_t offset, uint64_t size);
	void setViewport(float x, float y, float width, float height, float minDepth, float maxDepth);
	void writeTimestamp(QuerySet querySet, uint32_t queryIndex);
	void reference();
	void release();
END

HANDLE(RenderPipeline)
	BindGroupLayout getBindGroupLayout(uint32_t groupIndex);
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(Sampler)
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(ShaderModule)
	std::unique_ptr<CompilationInfoCallback> getCompilationInfo(CompilationInfoCallback&& callback);
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(Surface)
	void reference();
	void release();
END

HANDLE(SwapChain)
	TextureView getCurrentTextureView();
	void present();
	void reference();
	void release();
END

HANDLE(Texture)
	TextureView createView(const TextureViewDescriptor& descriptor);
	void destroy();
	uint32_t getDepthOrArrayLayers();
	TextureDimension getDimension();
	TextureFormat getFormat();
	uint32_t getHeight();
	uint32_t getMipLevelCount();
	uint32_t getSampleCount();
	TextureUsage getUsage();
	uint32_t getWidth();
	void setLabel(char const * label);
	void reference();
	void release();
END

HANDLE(TextureView)
	void setLabel(char const * label);
	void reference();
	void release();
END


// Non-member procedures


Instance createInstance(const InstanceDescriptor& descriptor);

#ifdef WEBGPU_CPP_IMPLEMENTATION

inline Instance createInstance(const InstanceDescriptor& descriptor) {
	return wgpuCreateInstance(&descriptor);
}

// Handles members implementation
// Methods of ChainedStruct
inline void ChainedStruct::setDefault() {
}

// Methods of ChainedStructOut
inline void ChainedStructOut::setDefault() {
}

// Methods of AdapterProperties
inline void AdapterProperties::setDefault() {
}

// Methods of BindGroupEntry
inline void BindGroupEntry::setDefault() {
	offset = 0;
}

// Methods of BlendComponent
inline void BlendComponent::setDefault() {
	operation = BlendOperation::Add;
	srcFactor = BlendFactor::One;
	dstFactor = BlendFactor::Zero;
}

// Methods of BufferBindingLayout
inline void BufferBindingLayout::setDefault() {
	type = BufferBindingType::Uniform;
	hasDynamicOffset = false;
	minBindingSize = 0;
}

// Methods of BufferDescriptor
inline void BufferDescriptor::setDefault() {
	mappedAtCreation = false;
}

// Methods of Color
inline void Color::setDefault() {
}

// Methods of CommandBufferDescriptor
inline void CommandBufferDescriptor::setDefault() {
}

// Methods of CommandEncoderDescriptor
inline void CommandEncoderDescriptor::setDefault() {
}

// Methods of CompilationMessage
inline void CompilationMessage::setDefault() {
}

// Methods of ComputePassTimestampWrite
inline void ComputePassTimestampWrite::setDefault() {
}

// Methods of ConstantEntry
inline void ConstantEntry::setDefault() {
}

// Methods of CopyTextureForBrowserOptions
inline void CopyTextureForBrowserOptions::setDefault() {
}

// Methods of DawnAdapterPropertiesPowerPreference
inline void DawnAdapterPropertiesPowerPreference::setDefault() {
	powerPreference = PowerPreference::Undefined;
	((ChainedStructOut*)&chain)->setDefault();
	chain.sType = SType::DawnAdapterPropertiesPowerPreference;
}

// Methods of DawnBufferDescriptorErrorInfoFromWireClient
inline void DawnBufferDescriptorErrorInfoFromWireClient::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnBufferDescriptorErrorInfoFromWireClient;
}

// Methods of DawnCacheDeviceDescriptor
inline void DawnCacheDeviceDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnCacheDeviceDescriptor;
}

// Methods of DawnEncoderInternalUsageDescriptor
inline void DawnEncoderInternalUsageDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnEncoderInternalUsageDescriptor;
}

// Methods of DawnInstanceDescriptor
inline void DawnInstanceDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnInstanceDescriptor;
}

// Methods of DawnShaderModuleSPIRVOptionsDescriptor
inline void DawnShaderModuleSPIRVOptionsDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnShaderModuleSPIRVOptionsDescriptor;
}

// Methods of DawnTextureInternalUsageDescriptor
inline void DawnTextureInternalUsageDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnTextureInternalUsageDescriptor;
}

// Methods of DawnTogglesDescriptor
inline void DawnTogglesDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnTogglesDescriptor;
}

// Methods of DawnTogglesDeviceDescriptor
inline void DawnTogglesDeviceDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::DawnTogglesDeviceDescriptor;
}

// Methods of Extent2D
inline void Extent2D::setDefault() {
}

// Methods of Extent3D
inline void Extent3D::setDefault() {
	height = 1;
	depthOrArrayLayers = 1;
}

// Methods of ExternalTextureBindingEntry
inline void ExternalTextureBindingEntry::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::ExternalTextureBindingEntry;
}

// Methods of ExternalTextureBindingLayout
inline void ExternalTextureBindingLayout::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::ExternalTextureBindingLayout;
}

// Methods of InstanceDescriptor
inline void InstanceDescriptor::setDefault() {
}

// Methods of Limits
inline void Limits::setDefault() {
	maxTextureDimension1D = 0;
	maxTextureDimension2D = 0;
	maxTextureDimension3D = 0;
	maxTextureArrayLayers = 0;
	maxBindGroups = 0;
	maxBindingsPerBindGroup = 0;
	maxDynamicUniformBuffersPerPipelineLayout = 0;
	maxDynamicStorageBuffersPerPipelineLayout = 0;
	maxSampledTexturesPerShaderStage = 0;
	maxSamplersPerShaderStage = 0;
	maxStorageBuffersPerShaderStage = 0;
	maxStorageTexturesPerShaderStage = 0;
	maxUniformBuffersPerShaderStage = 0;
	maxUniformBufferBindingSize = 0;
	maxStorageBufferBindingSize = 0;
	minUniformBufferOffsetAlignment = 64;
	minStorageBufferOffsetAlignment = 16;
	maxVertexBuffers = 0;
	maxBufferSize = 0;
	maxVertexAttributes = 0;
	maxVertexBufferArrayStride = 0;
	maxInterStageShaderComponents = 0;
	maxInterStageShaderVariables = 0;
	maxColorAttachments = 0;
	maxColorAttachmentBytesPerSample = 0;
	maxComputeWorkgroupStorageSize = 0;
	maxComputeInvocationsPerWorkgroup = 0;
	maxComputeWorkgroupSizeX = 0;
	maxComputeWorkgroupSizeY = 0;
	maxComputeWorkgroupSizeZ = 0;
	maxComputeWorkgroupsPerDimension = 0;
}

// Methods of MultisampleState
inline void MultisampleState::setDefault() {
	count = 1;
	mask = 0xFFFFFFFF;
	alphaToCoverageEnabled = false;
}

// Methods of Origin2D
inline void Origin2D::setDefault() {
}

// Methods of Origin3D
inline void Origin3D::setDefault() {
	x = 0;
	y = 0;
	z = 0;
}

// Methods of PipelineLayoutDescriptor
inline void PipelineLayoutDescriptor::setDefault() {
}

// Methods of PrimitiveDepthClipControl
inline void PrimitiveDepthClipControl::setDefault() {
	unclippedDepth = false;
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::PrimitiveDepthClipControl;
}

// Methods of PrimitiveState
inline void PrimitiveState::setDefault() {
	topology = PrimitiveTopology::TriangleList;
	stripIndexFormat = IndexFormat::Undefined;
	frontFace = FrontFace::CCW;
	cullMode = CullMode::None;
}

// Methods of QuerySetDescriptor
inline void QuerySetDescriptor::setDefault() {
}

// Methods of QueueDescriptor
inline void QueueDescriptor::setDefault() {
}

// Methods of RenderBundleDescriptor
inline void RenderBundleDescriptor::setDefault() {
}

// Methods of RenderBundleEncoderDescriptor
inline void RenderBundleEncoderDescriptor::setDefault() {
	depthStencilFormat = TextureFormat::Undefined;
	depthReadOnly = false;
	stencilReadOnly = false;
	sampleCount = 1;
}

// Methods of RenderPassDepthStencilAttachment
inline void RenderPassDepthStencilAttachment::setDefault() {
	depthLoadOp = LoadOp::Undefined;
	depthStoreOp = StoreOp::Undefined;
	depthClearValue = 0;
	depthReadOnly = false;
	stencilLoadOp = LoadOp::Undefined;
	stencilStoreOp = StoreOp::Undefined;
	stencilClearValue = 0;
	stencilReadOnly = false;
}

// Methods of RenderPassDescriptorMaxDrawCount
inline void RenderPassDescriptorMaxDrawCount::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::RenderPassDescriptorMaxDrawCount;
}

// Methods of RenderPassTimestampWrite
inline void RenderPassTimestampWrite::setDefault() {
}

// Methods of RequestAdapterOptions
inline void RequestAdapterOptions::setDefault() {
	powerPreference = PowerPreference::Undefined;
	forceFallbackAdapter = false;
}

// Methods of SamplerBindingLayout
inline void SamplerBindingLayout::setDefault() {
	type = SamplerBindingType::Filtering;
}

// Methods of SamplerDescriptor
inline void SamplerDescriptor::setDefault() {
	addressModeU = AddressMode::ClampToEdge;
	addressModeV = AddressMode::ClampToEdge;
	addressModeW = AddressMode::ClampToEdge;
	magFilter = FilterMode::Nearest;
	minFilter = FilterMode::Nearest;
	mipmapFilter = FilterMode::Nearest;
	lodMinClamp = 0;
	lodMaxClamp = 32;
	compare = CompareFunction::Undefined;
}

// Methods of ShaderModuleDescriptor
inline void ShaderModuleDescriptor::setDefault() {
}

// Methods of ShaderModuleSPIRVDescriptor
inline void ShaderModuleSPIRVDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::ShaderModuleSPIRVDescriptor;
}

// Methods of ShaderModuleWGSLDescriptor
inline void ShaderModuleWGSLDescriptor::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::ShaderModuleWGSLDescriptor;
}

// Methods of StencilFaceState
inline void StencilFaceState::setDefault() {
	compare = CompareFunction::Always;
	failOp = StencilOperation::Keep;
	depthFailOp = StencilOperation::Keep;
	passOp = StencilOperation::Keep;
}

// Methods of StorageTextureBindingLayout
inline void StorageTextureBindingLayout::setDefault() {
	access = StorageTextureAccess::WriteOnly;
	format = TextureFormat::Undefined;
	viewDimension = TextureViewDimension::_2D;
}

// Methods of SurfaceDescriptor
inline void SurfaceDescriptor::setDefault() {
}

// Methods of SurfaceDescriptorFromAndroidNativeWindow
inline void SurfaceDescriptorFromAndroidNativeWindow::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromAndroidNativeWindow;
}

// Methods of SurfaceDescriptorFromCanvasHTMLSelector
inline void SurfaceDescriptorFromCanvasHTMLSelector::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromCanvasHTMLSelector;
}

// Methods of SurfaceDescriptorFromMetalLayer
inline void SurfaceDescriptorFromMetalLayer::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromMetalLayer;
}

// Methods of SurfaceDescriptorFromWaylandSurface
inline void SurfaceDescriptorFromWaylandSurface::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromWaylandSurface;
}

// Methods of SurfaceDescriptorFromWindowsCoreWindow
inline void SurfaceDescriptorFromWindowsCoreWindow::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromWindowsCoreWindow;
}

// Methods of SurfaceDescriptorFromWindowsHWND
inline void SurfaceDescriptorFromWindowsHWND::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromWindowsHWND;
}

// Methods of SurfaceDescriptorFromWindowsSwapChainPanel
inline void SurfaceDescriptorFromWindowsSwapChainPanel::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromWindowsSwapChainPanel;
}

// Methods of SurfaceDescriptorFromXlibWindow
inline void SurfaceDescriptorFromXlibWindow::setDefault() {
	((ChainedStruct*)&chain)->setDefault();
	chain.sType = SType::SurfaceDescriptorFromXlibWindow;
}

// Methods of SwapChainDescriptor
inline void SwapChainDescriptor::setDefault() {
	format = TextureFormat::Undefined;
}

// Methods of TextureBindingLayout
inline void TextureBindingLayout::setDefault() {
	sampleType = TextureSampleType::Float;
	viewDimension = TextureViewDimension::_2D;
	multisampled = false;
}

// Methods of TextureDataLayout
inline void TextureDataLayout::setDefault() {
}

// Methods of TextureViewDescriptor
inline void TextureViewDescriptor::setDefault() {
	format = TextureFormat::Undefined;
	dimension = TextureViewDimension::Undefined;
	baseMipLevel = 0;
	baseArrayLayer = 0;
	aspect = TextureAspect::All;
}

// Methods of VertexAttribute
inline void VertexAttribute::setDefault() {
	format = VertexFormat::Undefined;
}

// Methods of BindGroupDescriptor
inline void BindGroupDescriptor::setDefault() {
}

// Methods of BindGroupLayoutEntry
inline void BindGroupLayoutEntry::setDefault() {
	((BufferBindingLayout*)&buffer)->setDefault();
	((SamplerBindingLayout*)&sampler)->setDefault();
	((TextureBindingLayout*)&texture)->setDefault();
	((StorageTextureBindingLayout*)&storageTexture)->setDefault();
	buffer.type = BufferBindingType::Undefined;
	sampler.type = SamplerBindingType::Undefined;
	storageTexture.access = StorageTextureAccess::Undefined;
	texture.sampleType = TextureSampleType::Undefined;
	buffer.type = BufferBindingType::Undefined;
	sampler.type = SamplerBindingType::Undefined;
	storageTexture.access = StorageTextureAccess::Undefined;
	texture.sampleType = TextureSampleType::Undefined;
}

// Methods of BlendState
inline void BlendState::setDefault() {
	((BlendComponent*)&color)->setDefault();
	((BlendComponent*)&alpha)->setDefault();
}

// Methods of CompilationInfo
inline void CompilationInfo::setDefault() {
}

// Methods of ComputePassDescriptor
inline void ComputePassDescriptor::setDefault() {
}

// Methods of DepthStencilState
inline void DepthStencilState::setDefault() {
	format = TextureFormat::Undefined;
	depthWriteEnabled = false;
	depthCompare = CompareFunction::Always;
	stencilReadMask = 0xFFFFFFFF;
	stencilWriteMask = 0xFFFFFFFF;
	depthBias = 0;
	depthBiasSlopeScale = 0;
	depthBiasClamp = 0;
	((StencilFaceState*)&stencilFront)->setDefault();
	((StencilFaceState*)&stencilBack)->setDefault();
}

// Methods of ExternalTextureDescriptor
inline void ExternalTextureDescriptor::setDefault() {
	((Origin2D*)&visibleOrigin)->setDefault();
	((Extent2D*)&visibleSize)->setDefault();
}

// Methods of ImageCopyBuffer
inline void ImageCopyBuffer::setDefault() {
	((TextureDataLayout*)&layout)->setDefault();
}

// Methods of ImageCopyExternalTexture
inline void ImageCopyExternalTexture::setDefault() {
	((Origin3D*)&origin)->setDefault();
	((Extent2D*)&naturalSize)->setDefault();
}

// Methods of ImageCopyTexture
inline void ImageCopyTexture::setDefault() {
	mipLevel = 0;
	aspect = TextureAspect::All;
	((Origin3D*)&origin)->setDefault();
}

// Methods of ProgrammableStageDescriptor
inline void ProgrammableStageDescriptor::setDefault() {
}

// Methods of RenderPassColorAttachment
inline void RenderPassColorAttachment::setDefault() {
	loadOp = LoadOp::Undefined;
	storeOp = StoreOp::Undefined;
	((Color*)&clearValue)->setDefault();
}

// Methods of RequiredLimits
inline void RequiredLimits::setDefault() {
	((Limits*)&limits)->setDefault();
}

// Methods of SupportedLimits
inline void SupportedLimits::setDefault() {
	((Limits*)&limits)->setDefault();
}

// Methods of TextureDescriptor
inline void TextureDescriptor::setDefault() {
	dimension = TextureDimension::_2D;
	format = TextureFormat::Undefined;
	mipLevelCount = 1;
	sampleCount = 1;
	((Extent3D*)&size)->setDefault();
}

// Methods of VertexBufferLayout
inline void VertexBufferLayout::setDefault() {
	stepMode = VertexStepMode::Vertex;
}

// Methods of BindGroupLayoutDescriptor
inline void BindGroupLayoutDescriptor::setDefault() {
}

// Methods of ColorTargetState
inline void ColorTargetState::setDefault() {
	format = TextureFormat::Undefined;
}

// Methods of ComputePipelineDescriptor
inline void ComputePipelineDescriptor::setDefault() {
	((ProgrammableStageDescriptor*)&compute)->setDefault();
}

// Methods of DeviceDescriptor
inline void DeviceDescriptor::setDefault() {
	((QueueDescriptor*)&defaultQueue)->setDefault();
}

// Methods of RenderPassDescriptor
inline void RenderPassDescriptor::setDefault() {
}

// Methods of VertexState
inline void VertexState::setDefault() {
}

// Methods of FragmentState
inline void FragmentState::setDefault() {
}

// Methods of RenderPipelineDescriptor
inline void RenderPipelineDescriptor::setDefault() {
	((VertexState*)&vertex)->setDefault();
	((PrimitiveState*)&primitive)->setDefault();
	((MultisampleState*)&multisample)->setDefault();
}

// Methods of Adapter
inline Device Adapter::createDevice(const DeviceDescriptor& descriptor) {
	return wgpuAdapterCreateDevice(m_raw, &descriptor);
}
inline size_t Adapter::enumerateFeatures(FeatureName * features) {
	return wgpuAdapterEnumerateFeatures(m_raw, reinterpret_cast<WGPUFeatureName *>(features));
}
inline Instance Adapter::getInstance() {
	return wgpuAdapterGetInstance(m_raw);
}
inline bool Adapter::getLimits(SupportedLimits * limits) {
	return wgpuAdapterGetLimits(m_raw, limits);
}
inline void Adapter::getProperties(AdapterProperties * properties) {
	return wgpuAdapterGetProperties(m_raw, properties);
}
inline bool Adapter::hasFeature(FeatureName feature) {
	return wgpuAdapterHasFeature(m_raw, static_cast<WGPUFeatureName>(feature));
}
inline std::unique_ptr<RequestDeviceCallback> Adapter::requestDevice(const DeviceDescriptor& descriptor, RequestDeviceCallback&& callback) {
	auto handle = std::make_unique<RequestDeviceCallback>(callback);
	static auto cCallback = [](WGPURequestDeviceStatus status, WGPUDevice device, char const * message, void * userdata) -> void {
		RequestDeviceCallback& callback = *reinterpret_cast<RequestDeviceCallback*>(userdata);
		callback(static_cast<RequestDeviceStatus>(status), device, message);
	};
	wgpuAdapterRequestDevice(m_raw, &descriptor, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Adapter::reference() {
	return wgpuAdapterReference(m_raw);
}
inline void Adapter::release() {
	return wgpuAdapterRelease(m_raw);
}


// Methods of BindGroup
inline void BindGroup::setLabel(char const * label) {
	return wgpuBindGroupSetLabel(m_raw, label);
}
inline void BindGroup::reference() {
	return wgpuBindGroupReference(m_raw);
}
inline void BindGroup::release() {
	return wgpuBindGroupRelease(m_raw);
}


// Methods of BindGroupLayout
inline void BindGroupLayout::setLabel(char const * label) {
	return wgpuBindGroupLayoutSetLabel(m_raw, label);
}
inline void BindGroupLayout::reference() {
	return wgpuBindGroupLayoutReference(m_raw);
}
inline void BindGroupLayout::release() {
	return wgpuBindGroupLayoutRelease(m_raw);
}


// Methods of Buffer
inline void Buffer::destroy() {
	return wgpuBufferDestroy(m_raw);
}
inline void const * Buffer::getConstMappedRange(size_t offset, size_t size) {
	return wgpuBufferGetConstMappedRange(m_raw, offset, size);
}
inline BufferMapState Buffer::getMapState() {
	return static_cast<BufferMapState>(wgpuBufferGetMapState(m_raw));
}
inline void * Buffer::getMappedRange(size_t offset, size_t size) {
	return wgpuBufferGetMappedRange(m_raw, offset, size);
}
inline uint64_t Buffer::getSize() {
	return wgpuBufferGetSize(m_raw);
}
inline BufferUsage Buffer::getUsage() {
	return static_cast<BufferUsage>(wgpuBufferGetUsage(m_raw));
}
inline std::unique_ptr<BufferMapCallback> Buffer::mapAsync(MapModeFlags mode, size_t offset, size_t size, BufferMapCallback&& callback) {
	auto handle = std::make_unique<BufferMapCallback>(callback);
	static auto cCallback = [](WGPUBufferMapAsyncStatus status, void * userdata) -> void {
		BufferMapCallback& callback = *reinterpret_cast<BufferMapCallback*>(userdata);
		callback(static_cast<BufferMapAsyncStatus>(status));
	};
	wgpuBufferMapAsync(m_raw, static_cast<WGPUMapModeFlags>(mode), offset, size, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Buffer::setLabel(char const * label) {
	return wgpuBufferSetLabel(m_raw, label);
}
inline void Buffer::unmap() {
	return wgpuBufferUnmap(m_raw);
}
inline void Buffer::reference() {
	return wgpuBufferReference(m_raw);
}
inline void Buffer::release() {
	return wgpuBufferRelease(m_raw);
}


// Methods of CommandBuffer
inline void CommandBuffer::setLabel(char const * label) {
	return wgpuCommandBufferSetLabel(m_raw, label);
}
inline void CommandBuffer::reference() {
	return wgpuCommandBufferReference(m_raw);
}
inline void CommandBuffer::release() {
	return wgpuCommandBufferRelease(m_raw);
}


// Methods of CommandEncoder
inline ComputePassEncoder CommandEncoder::beginComputePass(const ComputePassDescriptor& descriptor) {
	return wgpuCommandEncoderBeginComputePass(m_raw, &descriptor);
}
inline RenderPassEncoder CommandEncoder::beginRenderPass(const RenderPassDescriptor& descriptor) {
	return wgpuCommandEncoderBeginRenderPass(m_raw, &descriptor);
}
inline void CommandEncoder::clearBuffer(Buffer buffer, uint64_t offset, uint64_t size) {
	return wgpuCommandEncoderClearBuffer(m_raw, buffer, offset, size);
}
inline void CommandEncoder::copyBufferToBuffer(Buffer source, uint64_t sourceOffset, Buffer destination, uint64_t destinationOffset, uint64_t size) {
	return wgpuCommandEncoderCopyBufferToBuffer(m_raw, source, sourceOffset, destination, destinationOffset, size);
}
inline void CommandEncoder::copyBufferToTexture(const ImageCopyBuffer& source, const ImageCopyTexture& destination, const Extent3D& copySize) {
	return wgpuCommandEncoderCopyBufferToTexture(m_raw, &source, &destination, &copySize);
}
inline void CommandEncoder::copyTextureToBuffer(const ImageCopyTexture& source, const ImageCopyBuffer& destination, const Extent3D& copySize) {
	return wgpuCommandEncoderCopyTextureToBuffer(m_raw, &source, &destination, &copySize);
}
inline void CommandEncoder::copyTextureToTexture(const ImageCopyTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize) {
	return wgpuCommandEncoderCopyTextureToTexture(m_raw, &source, &destination, &copySize);
}
inline void CommandEncoder::copyTextureToTextureInternal(const ImageCopyTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize) {
	return wgpuCommandEncoderCopyTextureToTextureInternal(m_raw, &source, &destination, &copySize);
}
inline CommandBuffer CommandEncoder::finish(const CommandBufferDescriptor& descriptor) {
	return wgpuCommandEncoderFinish(m_raw, &descriptor);
}
inline void CommandEncoder::injectValidationError(char const * message) {
	return wgpuCommandEncoderInjectValidationError(m_raw, message);
}
inline void CommandEncoder::insertDebugMarker(char const * markerLabel) {
	return wgpuCommandEncoderInsertDebugMarker(m_raw, markerLabel);
}
inline void CommandEncoder::popDebugGroup() {
	return wgpuCommandEncoderPopDebugGroup(m_raw);
}
inline void CommandEncoder::pushDebugGroup(char const * groupLabel) {
	return wgpuCommandEncoderPushDebugGroup(m_raw, groupLabel);
}
inline void CommandEncoder::resolveQuerySet(QuerySet querySet, uint32_t firstQuery, uint32_t queryCount, Buffer destination, uint64_t destinationOffset) {
	return wgpuCommandEncoderResolveQuerySet(m_raw, querySet, firstQuery, queryCount, destination, destinationOffset);
}
inline void CommandEncoder::setLabel(char const * label) {
	return wgpuCommandEncoderSetLabel(m_raw, label);
}
inline void CommandEncoder::writeBuffer(Buffer buffer, uint64_t bufferOffset, uint8_t const * data, uint64_t size) {
	return wgpuCommandEncoderWriteBuffer(m_raw, buffer, bufferOffset, data, size);
}
inline void CommandEncoder::writeTimestamp(QuerySet querySet, uint32_t queryIndex) {
	return wgpuCommandEncoderWriteTimestamp(m_raw, querySet, queryIndex);
}
inline void CommandEncoder::reference() {
	return wgpuCommandEncoderReference(m_raw);
}
inline void CommandEncoder::release() {
	return wgpuCommandEncoderRelease(m_raw);
}


// Methods of ComputePassEncoder
inline void ComputePassEncoder::dispatch(uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) {
	return wgpuComputePassEncoderDispatch(m_raw, workgroupCountX, workgroupCountY, workgroupCountZ);
}
inline void ComputePassEncoder::dispatchIndirect(Buffer indirectBuffer, uint64_t indirectOffset) {
	return wgpuComputePassEncoderDispatchIndirect(m_raw, indirectBuffer, indirectOffset);
}
inline void ComputePassEncoder::dispatchWorkgroups(uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) {
	return wgpuComputePassEncoderDispatchWorkgroups(m_raw, workgroupCountX, workgroupCountY, workgroupCountZ);
}
inline void ComputePassEncoder::dispatchWorkgroupsIndirect(Buffer indirectBuffer, uint64_t indirectOffset) {
	return wgpuComputePassEncoderDispatchWorkgroupsIndirect(m_raw, indirectBuffer, indirectOffset);
}
inline void ComputePassEncoder::end() {
	return wgpuComputePassEncoderEnd(m_raw);
}
inline void ComputePassEncoder::endPass() {
	return wgpuComputePassEncoderEndPass(m_raw);
}
inline void ComputePassEncoder::insertDebugMarker(char const * markerLabel) {
	return wgpuComputePassEncoderInsertDebugMarker(m_raw, markerLabel);
}
inline void ComputePassEncoder::popDebugGroup() {
	return wgpuComputePassEncoderPopDebugGroup(m_raw);
}
inline void ComputePassEncoder::pushDebugGroup(char const * groupLabel) {
	return wgpuComputePassEncoderPushDebugGroup(m_raw, groupLabel);
}
inline void ComputePassEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, uint32_t dynamicOffsetCount, uint32_t const * dynamicOffsets) {
	return wgpuComputePassEncoderSetBindGroup(m_raw, groupIndex, group, dynamicOffsetCount, dynamicOffsets);
}
inline void ComputePassEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, const std::vector<uint32_t>& dynamicOffsets) {
	return wgpuComputePassEncoderSetBindGroup(m_raw, groupIndex, group, static_cast<uint32_t>(dynamicOffsets.size()), dynamicOffsets.data());
}
inline void ComputePassEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, const uint32_t& dynamicOffsets) {
	return wgpuComputePassEncoderSetBindGroup(m_raw, groupIndex, group, 1, &dynamicOffsets);
}
inline void ComputePassEncoder::setLabel(char const * label) {
	return wgpuComputePassEncoderSetLabel(m_raw, label);
}
inline void ComputePassEncoder::setPipeline(ComputePipeline pipeline) {
	return wgpuComputePassEncoderSetPipeline(m_raw, pipeline);
}
inline void ComputePassEncoder::writeTimestamp(QuerySet querySet, uint32_t queryIndex) {
	return wgpuComputePassEncoderWriteTimestamp(m_raw, querySet, queryIndex);
}
inline void ComputePassEncoder::reference() {
	return wgpuComputePassEncoderReference(m_raw);
}
inline void ComputePassEncoder::release() {
	return wgpuComputePassEncoderRelease(m_raw);
}


// Methods of ComputePipeline
inline BindGroupLayout ComputePipeline::getBindGroupLayout(uint32_t groupIndex) {
	return wgpuComputePipelineGetBindGroupLayout(m_raw, groupIndex);
}
inline void ComputePipeline::setLabel(char const * label) {
	return wgpuComputePipelineSetLabel(m_raw, label);
}
inline void ComputePipeline::reference() {
	return wgpuComputePipelineReference(m_raw);
}
inline void ComputePipeline::release() {
	return wgpuComputePipelineRelease(m_raw);
}


// Methods of Device
inline BindGroup Device::createBindGroup(const BindGroupDescriptor& descriptor) {
	return wgpuDeviceCreateBindGroup(m_raw, &descriptor);
}
inline BindGroupLayout Device::createBindGroupLayout(const BindGroupLayoutDescriptor& descriptor) {
	return wgpuDeviceCreateBindGroupLayout(m_raw, &descriptor);
}
inline Buffer Device::createBuffer(const BufferDescriptor& descriptor) {
	return wgpuDeviceCreateBuffer(m_raw, &descriptor);
}
inline CommandEncoder Device::createCommandEncoder(const CommandEncoderDescriptor& descriptor) {
	return wgpuDeviceCreateCommandEncoder(m_raw, &descriptor);
}
inline ComputePipeline Device::createComputePipeline(const ComputePipelineDescriptor& descriptor) {
	return wgpuDeviceCreateComputePipeline(m_raw, &descriptor);
}
inline std::unique_ptr<CreateComputePipelineAsyncCallback> Device::createComputePipelineAsync(const ComputePipelineDescriptor& descriptor, CreateComputePipelineAsyncCallback&& callback) {
	auto handle = std::make_unique<CreateComputePipelineAsyncCallback>(callback);
	static auto cCallback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, char const * message, void * userdata) -> void {
		CreateComputePipelineAsyncCallback& callback = *reinterpret_cast<CreateComputePipelineAsyncCallback*>(userdata);
		callback(static_cast<CreatePipelineAsyncStatus>(status), pipeline, message);
	};
	wgpuDeviceCreateComputePipelineAsync(m_raw, &descriptor, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline Buffer Device::createErrorBuffer(const BufferDescriptor& descriptor) {
	return wgpuDeviceCreateErrorBuffer(m_raw, &descriptor);
}
inline ExternalTexture Device::createErrorExternalTexture() {
	return wgpuDeviceCreateErrorExternalTexture(m_raw);
}
inline Texture Device::createErrorTexture(const TextureDescriptor& descriptor) {
	return wgpuDeviceCreateErrorTexture(m_raw, &descriptor);
}
inline ExternalTexture Device::createExternalTexture(const ExternalTextureDescriptor& externalTextureDescriptor) {
	return wgpuDeviceCreateExternalTexture(m_raw, &externalTextureDescriptor);
}
inline PipelineLayout Device::createPipelineLayout(const PipelineLayoutDescriptor& descriptor) {
	return wgpuDeviceCreatePipelineLayout(m_raw, &descriptor);
}
inline QuerySet Device::createQuerySet(const QuerySetDescriptor& descriptor) {
	return wgpuDeviceCreateQuerySet(m_raw, &descriptor);
}
inline RenderBundleEncoder Device::createRenderBundleEncoder(const RenderBundleEncoderDescriptor& descriptor) {
	return wgpuDeviceCreateRenderBundleEncoder(m_raw, &descriptor);
}
inline RenderPipeline Device::createRenderPipeline(const RenderPipelineDescriptor& descriptor) {
	return wgpuDeviceCreateRenderPipeline(m_raw, &descriptor);
}
inline std::unique_ptr<CreateRenderPipelineAsyncCallback> Device::createRenderPipelineAsync(const RenderPipelineDescriptor& descriptor, CreateRenderPipelineAsyncCallback&& callback) {
	auto handle = std::make_unique<CreateRenderPipelineAsyncCallback>(callback);
	static auto cCallback = [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, char const * message, void * userdata) -> void {
		CreateRenderPipelineAsyncCallback& callback = *reinterpret_cast<CreateRenderPipelineAsyncCallback*>(userdata);
		callback(static_cast<CreatePipelineAsyncStatus>(status), pipeline, message);
	};
	wgpuDeviceCreateRenderPipelineAsync(m_raw, &descriptor, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline Sampler Device::createSampler(const SamplerDescriptor& descriptor) {
	return wgpuDeviceCreateSampler(m_raw, &descriptor);
}
inline ShaderModule Device::createShaderModule(const ShaderModuleDescriptor& descriptor) {
	return wgpuDeviceCreateShaderModule(m_raw, &descriptor);
}
inline SwapChain Device::createSwapChain(Surface surface, const SwapChainDescriptor& descriptor) {
	return wgpuDeviceCreateSwapChain(m_raw, surface, &descriptor);
}
inline Texture Device::createTexture(const TextureDescriptor& descriptor) {
	return wgpuDeviceCreateTexture(m_raw, &descriptor);
}
inline void Device::destroy() {
	return wgpuDeviceDestroy(m_raw);
}
inline size_t Device::enumerateFeatures(FeatureName * features) {
	return wgpuDeviceEnumerateFeatures(m_raw, reinterpret_cast<WGPUFeatureName *>(features));
}
inline void Device::forceLoss(DeviceLostReason type, char const * message) {
	return wgpuDeviceForceLoss(m_raw, static_cast<WGPUDeviceLostReason>(type), message);
}
inline Adapter Device::getAdapter() {
	return wgpuDeviceGetAdapter(m_raw);
}
inline bool Device::getLimits(SupportedLimits * limits) {
	return wgpuDeviceGetLimits(m_raw, limits);
}
inline Queue Device::getQueue() {
	return wgpuDeviceGetQueue(m_raw);
}
inline bool Device::hasFeature(FeatureName feature) {
	return wgpuDeviceHasFeature(m_raw, static_cast<WGPUFeatureName>(feature));
}
inline void Device::injectError(ErrorType type, char const * message) {
	return wgpuDeviceInjectError(m_raw, static_cast<WGPUErrorType>(type), message);
}
inline std::unique_ptr<ErrorCallback> Device::popErrorScope(ErrorCallback&& callback) {
	auto handle = std::make_unique<ErrorCallback>(callback);
	static auto cCallback = [](WGPUErrorType type, char const * message, void * userdata) -> void {
		ErrorCallback& callback = *reinterpret_cast<ErrorCallback*>(userdata);
		callback(static_cast<ErrorType>(type), message);
	};
	wgpuDevicePopErrorScope(m_raw, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Device::pushErrorScope(ErrorFilter filter) {
	return wgpuDevicePushErrorScope(m_raw, static_cast<WGPUErrorFilter>(filter));
}
inline std::unique_ptr<DeviceLostCallback> Device::setDeviceLostCallback(DeviceLostCallback&& callback) {
	auto handle = std::make_unique<DeviceLostCallback>(callback);
	static auto cCallback = [](WGPUDeviceLostReason reason, char const * message, void * userdata) -> void {
		DeviceLostCallback& callback = *reinterpret_cast<DeviceLostCallback*>(userdata);
		callback(static_cast<DeviceLostReason>(reason), message);
	};
	wgpuDeviceSetDeviceLostCallback(m_raw, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Device::setLabel(char const * label) {
	return wgpuDeviceSetLabel(m_raw, label);
}
inline std::unique_ptr<LoggingCallback> Device::setLoggingCallback(LoggingCallback&& callback) {
	auto handle = std::make_unique<LoggingCallback>(callback);
	static auto cCallback = [](WGPULoggingType type, char const * message, void * userdata) -> void {
		LoggingCallback& callback = *reinterpret_cast<LoggingCallback*>(userdata);
		callback(static_cast<LoggingType>(type), message);
	};
	wgpuDeviceSetLoggingCallback(m_raw, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline std::unique_ptr<ErrorCallback> Device::setUncapturedErrorCallback(ErrorCallback&& callback) {
	auto handle = std::make_unique<ErrorCallback>(callback);
	static auto cCallback = [](WGPUErrorType type, char const * message, void * userdata) -> void {
		ErrorCallback& callback = *reinterpret_cast<ErrorCallback*>(userdata);
		callback(static_cast<ErrorType>(type), message);
	};
	wgpuDeviceSetUncapturedErrorCallback(m_raw, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Device::tick() {
	return wgpuDeviceTick(m_raw);
}
inline void Device::validateTextureDescriptor(const TextureDescriptor& descriptor) {
	return wgpuDeviceValidateTextureDescriptor(m_raw, &descriptor);
}
inline void Device::reference() {
	return wgpuDeviceReference(m_raw);
}
inline void Device::release() {
	return wgpuDeviceRelease(m_raw);
}


// Methods of ExternalTexture
inline void ExternalTexture::destroy() {
	return wgpuExternalTextureDestroy(m_raw);
}
inline void ExternalTexture::expire() {
	return wgpuExternalTextureExpire(m_raw);
}
inline void ExternalTexture::refresh() {
	return wgpuExternalTextureRefresh(m_raw);
}
inline void ExternalTexture::setLabel(char const * label) {
	return wgpuExternalTextureSetLabel(m_raw, label);
}
inline void ExternalTexture::reference() {
	return wgpuExternalTextureReference(m_raw);
}
inline void ExternalTexture::release() {
	return wgpuExternalTextureRelease(m_raw);
}


// Methods of Instance
inline Surface Instance::createSurface(const SurfaceDescriptor& descriptor) {
	return wgpuInstanceCreateSurface(m_raw, &descriptor);
}
inline void Instance::processEvents() {
	return wgpuInstanceProcessEvents(m_raw);
}
inline std::unique_ptr<RequestAdapterCallback> Instance::requestAdapter(const RequestAdapterOptions& options, RequestAdapterCallback&& callback) {
	auto handle = std::make_unique<RequestAdapterCallback>(callback);
	static auto cCallback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, char const * message, void * userdata) -> void {
		RequestAdapterCallback& callback = *reinterpret_cast<RequestAdapterCallback*>(userdata);
		callback(static_cast<RequestAdapterStatus>(status), adapter, message);
	};
	wgpuInstanceRequestAdapter(m_raw, &options, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Instance::reference() {
	return wgpuInstanceReference(m_raw);
}
inline void Instance::release() {
	return wgpuInstanceRelease(m_raw);
}


// Methods of PipelineLayout
inline void PipelineLayout::setLabel(char const * label) {
	return wgpuPipelineLayoutSetLabel(m_raw, label);
}
inline void PipelineLayout::reference() {
	return wgpuPipelineLayoutReference(m_raw);
}
inline void PipelineLayout::release() {
	return wgpuPipelineLayoutRelease(m_raw);
}


// Methods of QuerySet
inline void QuerySet::destroy() {
	return wgpuQuerySetDestroy(m_raw);
}
inline uint32_t QuerySet::getCount() {
	return wgpuQuerySetGetCount(m_raw);
}
inline QueryType QuerySet::getType() {
	return static_cast<QueryType>(wgpuQuerySetGetType(m_raw));
}
inline void QuerySet::setLabel(char const * label) {
	return wgpuQuerySetSetLabel(m_raw, label);
}
inline void QuerySet::reference() {
	return wgpuQuerySetReference(m_raw);
}
inline void QuerySet::release() {
	return wgpuQuerySetRelease(m_raw);
}


// Methods of Queue
inline void Queue::copyExternalTextureForBrowser(const ImageCopyExternalTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize, const CopyTextureForBrowserOptions& options) {
	return wgpuQueueCopyExternalTextureForBrowser(m_raw, &source, &destination, &copySize, &options);
}
inline void Queue::copyTextureForBrowser(const ImageCopyTexture& source, const ImageCopyTexture& destination, const Extent3D& copySize, const CopyTextureForBrowserOptions& options) {
	return wgpuQueueCopyTextureForBrowser(m_raw, &source, &destination, &copySize, &options);
}
inline std::unique_ptr<QueueWorkDoneCallback> Queue::onSubmittedWorkDone(uint64_t signalValue, QueueWorkDoneCallback&& callback) {
	auto handle = std::make_unique<QueueWorkDoneCallback>(callback);
	static auto cCallback = [](WGPUQueueWorkDoneStatus status, void * userdata) -> void {
		QueueWorkDoneCallback& callback = *reinterpret_cast<QueueWorkDoneCallback*>(userdata);
		callback(static_cast<QueueWorkDoneStatus>(status));
	};
	wgpuQueueOnSubmittedWorkDone(m_raw, signalValue, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void Queue::setLabel(char const * label) {
	return wgpuQueueSetLabel(m_raw, label);
}
inline void Queue::submit(uint32_t commandCount, CommandBuffer const * commands) {
	return wgpuQueueSubmit(m_raw, commandCount, reinterpret_cast<WGPUCommandBuffer const *>(commands));
}
inline void Queue::submit(const std::vector<WGPUCommandBuffer>& commands) {
	return wgpuQueueSubmit(m_raw, static_cast<uint32_t>(commands.size()), commands.data());
}
inline void Queue::submit(const WGPUCommandBuffer& commands) {
	return wgpuQueueSubmit(m_raw, 1, &commands);
}
inline void Queue::writeBuffer(Buffer buffer, uint64_t bufferOffset, void const * data, size_t size) {
	return wgpuQueueWriteBuffer(m_raw, buffer, bufferOffset, data, size);
}
inline void Queue::writeTexture(const ImageCopyTexture& destination, void const * data, size_t dataSize, const TextureDataLayout& dataLayout, const Extent3D& writeSize) {
	return wgpuQueueWriteTexture(m_raw, &destination, data, dataSize, &dataLayout, &writeSize);
}
inline void Queue::reference() {
	return wgpuQueueReference(m_raw);
}
inline void Queue::release() {
	return wgpuQueueRelease(m_raw);
}


// Methods of RenderBundle
inline void RenderBundle::reference() {
	return wgpuRenderBundleReference(m_raw);
}
inline void RenderBundle::release() {
	return wgpuRenderBundleRelease(m_raw);
}


// Methods of RenderBundleEncoder
inline void RenderBundleEncoder::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
	return wgpuRenderBundleEncoderDraw(m_raw, vertexCount, instanceCount, firstVertex, firstInstance);
}
inline void RenderBundleEncoder::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) {
	return wgpuRenderBundleEncoderDrawIndexed(m_raw, indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
}
inline void RenderBundleEncoder::drawIndexedIndirect(Buffer indirectBuffer, uint64_t indirectOffset) {
	return wgpuRenderBundleEncoderDrawIndexedIndirect(m_raw, indirectBuffer, indirectOffset);
}
inline void RenderBundleEncoder::drawIndirect(Buffer indirectBuffer, uint64_t indirectOffset) {
	return wgpuRenderBundleEncoderDrawIndirect(m_raw, indirectBuffer, indirectOffset);
}
inline RenderBundle RenderBundleEncoder::finish(const RenderBundleDescriptor& descriptor) {
	return wgpuRenderBundleEncoderFinish(m_raw, &descriptor);
}
inline void RenderBundleEncoder::insertDebugMarker(char const * markerLabel) {
	return wgpuRenderBundleEncoderInsertDebugMarker(m_raw, markerLabel);
}
inline void RenderBundleEncoder::popDebugGroup() {
	return wgpuRenderBundleEncoderPopDebugGroup(m_raw);
}
inline void RenderBundleEncoder::pushDebugGroup(char const * groupLabel) {
	return wgpuRenderBundleEncoderPushDebugGroup(m_raw, groupLabel);
}
inline void RenderBundleEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, uint32_t dynamicOffsetCount, uint32_t const * dynamicOffsets) {
	return wgpuRenderBundleEncoderSetBindGroup(m_raw, groupIndex, group, dynamicOffsetCount, dynamicOffsets);
}
inline void RenderBundleEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, const std::vector<uint32_t>& dynamicOffsets) {
	return wgpuRenderBundleEncoderSetBindGroup(m_raw, groupIndex, group, static_cast<uint32_t>(dynamicOffsets.size()), dynamicOffsets.data());
}
inline void RenderBundleEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, const uint32_t& dynamicOffsets) {
	return wgpuRenderBundleEncoderSetBindGroup(m_raw, groupIndex, group, 1, &dynamicOffsets);
}
inline void RenderBundleEncoder::setIndexBuffer(Buffer buffer, IndexFormat format, uint64_t offset, uint64_t size) {
	return wgpuRenderBundleEncoderSetIndexBuffer(m_raw, buffer, static_cast<WGPUIndexFormat>(format), offset, size);
}
inline void RenderBundleEncoder::setLabel(char const * label) {
	return wgpuRenderBundleEncoderSetLabel(m_raw, label);
}
inline void RenderBundleEncoder::setPipeline(RenderPipeline pipeline) {
	return wgpuRenderBundleEncoderSetPipeline(m_raw, pipeline);
}
inline void RenderBundleEncoder::setVertexBuffer(uint32_t slot, Buffer buffer, uint64_t offset, uint64_t size) {
	return wgpuRenderBundleEncoderSetVertexBuffer(m_raw, slot, buffer, offset, size);
}
inline void RenderBundleEncoder::reference() {
	return wgpuRenderBundleEncoderReference(m_raw);
}
inline void RenderBundleEncoder::release() {
	return wgpuRenderBundleEncoderRelease(m_raw);
}


// Methods of RenderPassEncoder
inline void RenderPassEncoder::beginOcclusionQuery(uint32_t queryIndex) {
	return wgpuRenderPassEncoderBeginOcclusionQuery(m_raw, queryIndex);
}
inline void RenderPassEncoder::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
	return wgpuRenderPassEncoderDraw(m_raw, vertexCount, instanceCount, firstVertex, firstInstance);
}
inline void RenderPassEncoder::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) {
	return wgpuRenderPassEncoderDrawIndexed(m_raw, indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
}
inline void RenderPassEncoder::drawIndexedIndirect(Buffer indirectBuffer, uint64_t indirectOffset) {
	return wgpuRenderPassEncoderDrawIndexedIndirect(m_raw, indirectBuffer, indirectOffset);
}
inline void RenderPassEncoder::drawIndirect(Buffer indirectBuffer, uint64_t indirectOffset) {
	return wgpuRenderPassEncoderDrawIndirect(m_raw, indirectBuffer, indirectOffset);
}
inline void RenderPassEncoder::end() {
	return wgpuRenderPassEncoderEnd(m_raw);
}
inline void RenderPassEncoder::endOcclusionQuery() {
	return wgpuRenderPassEncoderEndOcclusionQuery(m_raw);
}
inline void RenderPassEncoder::endPass() {
	return wgpuRenderPassEncoderEndPass(m_raw);
}
inline void RenderPassEncoder::executeBundles(uint32_t bundleCount, RenderBundle const * bundles) {
	return wgpuRenderPassEncoderExecuteBundles(m_raw, bundleCount, reinterpret_cast<WGPURenderBundle const *>(bundles));
}
inline void RenderPassEncoder::executeBundles(const std::vector<WGPURenderBundle>& bundles) {
	return wgpuRenderPassEncoderExecuteBundles(m_raw, static_cast<uint32_t>(bundles.size()), bundles.data());
}
inline void RenderPassEncoder::executeBundles(const WGPURenderBundle& bundles) {
	return wgpuRenderPassEncoderExecuteBundles(m_raw, 1, &bundles);
}
inline void RenderPassEncoder::insertDebugMarker(char const * markerLabel) {
	return wgpuRenderPassEncoderInsertDebugMarker(m_raw, markerLabel);
}
inline void RenderPassEncoder::popDebugGroup() {
	return wgpuRenderPassEncoderPopDebugGroup(m_raw);
}
inline void RenderPassEncoder::pushDebugGroup(char const * groupLabel) {
	return wgpuRenderPassEncoderPushDebugGroup(m_raw, groupLabel);
}
inline void RenderPassEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, uint32_t dynamicOffsetCount, uint32_t const * dynamicOffsets) {
	return wgpuRenderPassEncoderSetBindGroup(m_raw, groupIndex, group, dynamicOffsetCount, dynamicOffsets);
}
inline void RenderPassEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, const std::vector<uint32_t>& dynamicOffsets) {
	return wgpuRenderPassEncoderSetBindGroup(m_raw, groupIndex, group, static_cast<uint32_t>(dynamicOffsets.size()), dynamicOffsets.data());
}
inline void RenderPassEncoder::setBindGroup(uint32_t groupIndex, BindGroup group, const uint32_t& dynamicOffsets) {
	return wgpuRenderPassEncoderSetBindGroup(m_raw, groupIndex, group, 1, &dynamicOffsets);
}
inline void RenderPassEncoder::setBlendConstant(const Color& color) {
	return wgpuRenderPassEncoderSetBlendConstant(m_raw, &color);
}
inline void RenderPassEncoder::setIndexBuffer(Buffer buffer, IndexFormat format, uint64_t offset, uint64_t size) {
	return wgpuRenderPassEncoderSetIndexBuffer(m_raw, buffer, static_cast<WGPUIndexFormat>(format), offset, size);
}
inline void RenderPassEncoder::setLabel(char const * label) {
	return wgpuRenderPassEncoderSetLabel(m_raw, label);
}
inline void RenderPassEncoder::setPipeline(RenderPipeline pipeline) {
	return wgpuRenderPassEncoderSetPipeline(m_raw, pipeline);
}
inline void RenderPassEncoder::setScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
	return wgpuRenderPassEncoderSetScissorRect(m_raw, x, y, width, height);
}
inline void RenderPassEncoder::setStencilReference(uint32_t reference) {
	return wgpuRenderPassEncoderSetStencilReference(m_raw, reference);
}
inline void RenderPassEncoder::setVertexBuffer(uint32_t slot, Buffer buffer, uint64_t offset, uint64_t size) {
	return wgpuRenderPassEncoderSetVertexBuffer(m_raw, slot, buffer, offset, size);
}
inline void RenderPassEncoder::setViewport(float x, float y, float width, float height, float minDepth, float maxDepth) {
	return wgpuRenderPassEncoderSetViewport(m_raw, x, y, width, height, minDepth, maxDepth);
}
inline void RenderPassEncoder::writeTimestamp(QuerySet querySet, uint32_t queryIndex) {
	return wgpuRenderPassEncoderWriteTimestamp(m_raw, querySet, queryIndex);
}
inline void RenderPassEncoder::reference() {
	return wgpuRenderPassEncoderReference(m_raw);
}
inline void RenderPassEncoder::release() {
	return wgpuRenderPassEncoderRelease(m_raw);
}


// Methods of RenderPipeline
inline BindGroupLayout RenderPipeline::getBindGroupLayout(uint32_t groupIndex) {
	return wgpuRenderPipelineGetBindGroupLayout(m_raw, groupIndex);
}
inline void RenderPipeline::setLabel(char const * label) {
	return wgpuRenderPipelineSetLabel(m_raw, label);
}
inline void RenderPipeline::reference() {
	return wgpuRenderPipelineReference(m_raw);
}
inline void RenderPipeline::release() {
	return wgpuRenderPipelineRelease(m_raw);
}


// Methods of Sampler
inline void Sampler::setLabel(char const * label) {
	return wgpuSamplerSetLabel(m_raw, label);
}
inline void Sampler::reference() {
	return wgpuSamplerReference(m_raw);
}
inline void Sampler::release() {
	return wgpuSamplerRelease(m_raw);
}


// Methods of ShaderModule
inline std::unique_ptr<CompilationInfoCallback> ShaderModule::getCompilationInfo(CompilationInfoCallback&& callback) {
	auto handle = std::make_unique<CompilationInfoCallback>(callback);
	static auto cCallback = [](WGPUCompilationInfoRequestStatus status, WGPUCompilationInfo const * compilationInfo, void * userdata) -> void {
		CompilationInfoCallback& callback = *reinterpret_cast<CompilationInfoCallback*>(userdata);
		callback(static_cast<CompilationInfoRequestStatus>(status), *reinterpret_cast<CompilationInfo const *>(compilationInfo));
	};
	wgpuShaderModuleGetCompilationInfo(m_raw, cCallback, reinterpret_cast<void*>(handle.get()));
	return handle;
}
inline void ShaderModule::setLabel(char const * label) {
	return wgpuShaderModuleSetLabel(m_raw, label);
}
inline void ShaderModule::reference() {
	return wgpuShaderModuleReference(m_raw);
}
inline void ShaderModule::release() {
	return wgpuShaderModuleRelease(m_raw);
}


// Methods of Surface
inline void Surface::reference() {
	return wgpuSurfaceReference(m_raw);
}
inline void Surface::release() {
	return wgpuSurfaceRelease(m_raw);
}


// Methods of SwapChain
inline TextureView SwapChain::getCurrentTextureView() {
	return wgpuSwapChainGetCurrentTextureView(m_raw);
}
inline void SwapChain::present() {
	return wgpuSwapChainPresent(m_raw);
}
inline void SwapChain::reference() {
	return wgpuSwapChainReference(m_raw);
}
inline void SwapChain::release() {
	return wgpuSwapChainRelease(m_raw);
}


// Methods of Texture
inline TextureView Texture::createView(const TextureViewDescriptor& descriptor) {
	return wgpuTextureCreateView(m_raw, &descriptor);
}
inline void Texture::destroy() {
	return wgpuTextureDestroy(m_raw);
}
inline uint32_t Texture::getDepthOrArrayLayers() {
	return wgpuTextureGetDepthOrArrayLayers(m_raw);
}
inline TextureDimension Texture::getDimension() {
	return static_cast<TextureDimension>(wgpuTextureGetDimension(m_raw));
}
inline TextureFormat Texture::getFormat() {
	return static_cast<TextureFormat>(wgpuTextureGetFormat(m_raw));
}
inline uint32_t Texture::getHeight() {
	return wgpuTextureGetHeight(m_raw);
}
inline uint32_t Texture::getMipLevelCount() {
	return wgpuTextureGetMipLevelCount(m_raw);
}
inline uint32_t Texture::getSampleCount() {
	return wgpuTextureGetSampleCount(m_raw);
}
inline TextureUsage Texture::getUsage() {
	return static_cast<TextureUsage>(wgpuTextureGetUsage(m_raw));
}
inline uint32_t Texture::getWidth() {
	return wgpuTextureGetWidth(m_raw);
}
inline void Texture::setLabel(char const * label) {
	return wgpuTextureSetLabel(m_raw, label);
}
inline void Texture::reference() {
	return wgpuTextureReference(m_raw);
}
inline void Texture::release() {
	return wgpuTextureRelease(m_raw);
}


// Methods of TextureView
inline void TextureView::setLabel(char const * label) {
	return wgpuTextureViewSetLabel(m_raw, label);
}
inline void TextureView::reference() {
	return wgpuTextureViewReference(m_raw);
}
inline void TextureView::release() {
	return wgpuTextureViewRelease(m_raw);
}



// Extra implementations
inline Adapter Instance::requestAdapter(const RequestAdapterOptions& options) {
	Adapter adapter = nullptr;
	bool requestEnded = false;

	auto onAdapterRequestEnded = [&adapter, &requestEnded](RequestAdapterStatus status, Adapter _adapter, char const * message) {
		if (status == RequestAdapterStatus::Success) {
			adapter = _adapter;
		} else {
			std::cout << "Could not get WebGPU adapter: " << message << std::endl;
		}
		requestEnded = true;
	};

	requestAdapter(options, onAdapterRequestEnded);

	assert(requestEnded);
	return adapter;
}

inline Device Adapter::requestDevice(const DeviceDescriptor& descriptor) {
	WGPUDevice device = nullptr;
	bool requestEnded = false;

	auto onDeviceRequestEnded = [&device, &requestEnded](RequestDeviceStatus status, Device _device, char const * message) {
		if (status == RequestDeviceStatus::Success) {
			device = _device;
		} else {
			std::cout << "Could not get WebGPU adapter: " << message << std::endl;
		}
		requestEnded = true;
	};

	requestDevice(descriptor, onDeviceRequestEnded);

	assert(requestEnded);
	return device;
}

#endif // WEBGPU_CPP_IMPLEMENTATION

#undef HANDLE
#undef DESCRIPTOR
#undef ENUM
#undef ENUM_ENTRY
#undef END

} // namespace wgpu
