#include #include namespace psemek::wgpu { queue device::get_queue() { auto ptr = wgpuDeviceGetQueue((WGPUDevice)get()); // Queue is actually owned by the device // Reference it to prevent destroying wgpuQueueReference(ptr); return queue(ptr); } buffer device::create_buffer(buffer::descriptor const & desc) { WGPUBufferDescriptor descriptor = {}; descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); descriptor.label = desc.label.data(); descriptor.usage = (WGPUBufferUsageFlags)desc.usage; descriptor.size = desc.size; descriptor.mappedAtCreation = desc.mapped_at_creation; return buffer(wgpuDeviceCreateBuffer((WGPUDevice)get(), &descriptor)); } command_encoder device::create_command_encoder(command_encoder::descriptor const & desc) { WGPUCommandEncoderDescriptor descriptor = {}; descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); descriptor.label = desc.label.data(); return command_encoder(wgpuDeviceCreateCommandEncoder((WGPUDevice)get(), &descriptor)); } query_set device::create_query_set(query_set::descriptor const & desc) { WGPUQuerySetDescriptor descriptor = {}; descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); descriptor.label = desc.label.data(); descriptor.type = (WGPUQueryType)desc.type; descriptor.count = desc.count; return query_set(wgpuDeviceCreateQuerySet((WGPUDevice)get(), &descriptor)); } render_pipeline device::create_render_pipeline(render_pipeline::descriptor const & desc) { WGPURenderPipelineDescriptor descriptor = {}; std::vector vertex_constants; for (auto const & constant_in : desc.vertex.constants) { auto & constant_out = vertex_constants.emplace_back(); constant_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(constant_in.chain); constant_out.key = constant_in.key.data(); constant_out.value = constant_in.value; } std::vector vertex_buffers; for (auto const & buffer_in : desc.vertex.buffers) { auto & buffer_out = vertex_buffers.emplace_back(); buffer_out.arrayStride = buffer_in.array_stride; buffer_out.stepMode = (WGPUVertexStepMode)buffer_in.step_mode; buffer_out.attributeCount = buffer_in.attributes.size(); static_assert(sizeof(WGPUVertexAttribute) == sizeof(vertex_attribute)); buffer_out.attributes = (WGPUVertexAttribute const *)buffer_in.attributes.data(); } descriptor.vertex.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.vertex.chain); descriptor.vertex.module = (WGPUShaderModule)desc.vertex.module.get(); descriptor.vertex.entryPoint = desc.vertex.entry_point.data(); descriptor.vertex.constantCount = vertex_constants.size(); descriptor.vertex.constants = vertex_constants.data(); descriptor.vertex.bufferCount = vertex_buffers.size(); descriptor.vertex.buffers = vertex_buffers.data(); descriptor.primitive.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.primitive.chain); descriptor.primitive.topology = (WGPUPrimitiveTopology)desc.primitive.topology; descriptor.primitive.stripIndexFormat = (WGPUIndexFormat)desc.primitive.strip_index_format; descriptor.primitive.frontFace = (WGPUFrontFace)desc.primitive.front_face; descriptor.primitive.cullMode = (WGPUCullMode)desc.primitive.cull_mode; WGPUDepthStencilState depth_stencil_state = {}; if (desc.depth_stencil) { depth_stencil_state.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.depth_stencil->chain); depth_stencil_state.format = (WGPUTextureFormat)desc.depth_stencil->format; depth_stencil_state.depthWriteEnabled = desc.depth_stencil->depth_write; depth_stencil_state.depthCompare = (WGPUCompareFunction)desc.depth_stencil->depth_compare; depth_stencil_state.stencilFront.compare = (WGPUCompareFunction)desc.depth_stencil->stencil_front.compare; depth_stencil_state.stencilFront.failOp = (WGPUStencilOperation)desc.depth_stencil->stencil_front.fail_op; depth_stencil_state.stencilFront.depthFailOp = (WGPUStencilOperation)desc.depth_stencil->stencil_front.depth_fail_op; depth_stencil_state.stencilFront.passOp = (WGPUStencilOperation)desc.depth_stencil->stencil_front.pass_op; depth_stencil_state.stencilBack.compare = (WGPUCompareFunction)desc.depth_stencil->stencil_back.compare; depth_stencil_state.stencilBack.failOp = (WGPUStencilOperation)desc.depth_stencil->stencil_back.fail_op; depth_stencil_state.stencilBack.depthFailOp = (WGPUStencilOperation)desc.depth_stencil->stencil_back.depth_fail_op; depth_stencil_state.stencilBack.passOp = (WGPUStencilOperation)desc.depth_stencil->stencil_back.pass_op; depth_stencil_state.stencilReadMask = desc.depth_stencil->stencil_read_mask; depth_stencil_state.stencilWriteMask = desc.depth_stencil->stencil_write_mask; depth_stencil_state.depthBias = desc.depth_stencil->depth_bias; depth_stencil_state.depthBiasSlopeScale = desc.depth_stencil->depth_bias_slope_scale; depth_stencil_state.depthBiasClamp = desc.depth_stencil->depth_bias_clamp; descriptor.depthStencil = &depth_stencil_state; } descriptor.multisample.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.multisample.chain); descriptor.multisample.count = desc.multisample.count; descriptor.multisample.mask = desc.multisample.mask; descriptor.multisample.alphaToCoverageEnabled = desc.multisample.alpha_to_coverage; WGPUFragmentState fragment_state = {}; std::vector fragment_constants; std::vector color_targets; if (desc.fragment) { for (auto const & constant_in : desc.fragment->constants) { auto & constant_out = fragment_constants.emplace_back(); constant_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(constant_in.chain); constant_out.key = constant_in.key.data(); constant_out.value = constant_in.value; } for (auto const & target_in : desc.fragment->targets) { auto & target_out = color_targets.emplace_back(); target_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(target_in.chain); target_out.format = (WGPUTextureFormat)target_in.format; static_assert(sizeof(WGPUBlendState) == sizeof(blend_state)); target_out.blend = (WGPUBlendState *)(target_in.blend ? &(*target_in.blend) : nullptr); target_out.writeMask = (WGPUColorWriteMaskFlags)target_in.write_mask; } fragment_state.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.fragment->chain); fragment_state.module = (WGPUShaderModule)desc.fragment->module.get(); fragment_state.entryPoint = desc.fragment->entry_point.data(); fragment_state.constantCount = fragment_constants.size(); fragment_state.constants = fragment_constants.data(); fragment_state.targetCount = color_targets.size(); fragment_state.targets = color_targets.data(); descriptor.fragment = &fragment_state; } return render_pipeline(wgpuDeviceCreateRenderPipeline((WGPUDevice)get(), &descriptor)); } sampler device::create_sampler(sampler::descriptor const & desc) { WGPUSamplerDescriptor descriptor = {}; descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); descriptor.label = desc.label.data(); descriptor.addressModeU = (WGPUAddressMode)desc.address_mode_u; descriptor.addressModeV = (WGPUAddressMode)desc.address_mode_v; descriptor.addressModeW = (WGPUAddressMode)desc.address_mode_w; descriptor.magFilter = (WGPUFilterMode)desc.mag_filter; descriptor.minFilter = (WGPUFilterMode)desc.min_filter; descriptor.mipmapFilter = (WGPUMipmapFilterMode)desc.mipmap_filter; descriptor.lodMinClamp = desc.lod_clamp.min; descriptor.lodMaxClamp = desc.lod_clamp.max; descriptor.compare = (WGPUCompareFunction)desc.compare; descriptor.maxAnisotropy = desc.maxAnisotropy; return sampler(wgpuDeviceCreateSampler((WGPUDevice)get(), &descriptor)); } shader_module device::create_shader_module(shader_module::descriptor const & desc) { std::vector hints; for (auto const & hint_in : desc.hints) { auto & hint = hints.emplace_back(); hint.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(hint_in.chain); hint.entryPoint = hint_in.entry_point.data(); hint.layout = (WGPUPipelineLayout)hint_in.layout.get(); } WGPUShaderModuleDescriptor descriptor = {}; descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); descriptor.label = desc.label.data(); descriptor.hintCount = hints.size(); descriptor.hints = hints.data(); return shader_module(wgpuDeviceCreateShaderModule((WGPUDevice)get(), &descriptor)); } texture device::create_texture(texture::descriptor const & desc) { WGPUTextureDescriptor descriptor = {}; descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); descriptor.label = desc.label.data(); descriptor.usage = (WGPUTextureUsageFlags)desc.usage; descriptor.dimension = (WGPUTextureDimension)desc.dimension; descriptor.size = {desc.size[0], desc.size[1], desc.size[2]}; descriptor.format = (WGPUTextureFormat)desc.format; descriptor.mipLevelCount = desc.mip_level_count; descriptor.sampleCount = desc.sample_count; descriptor.viewFormatCount = desc.view_formats.size(); descriptor.viewFormats = (WGPUTextureFormat *)desc.view_formats.data(); return texture(wgpuDeviceCreateTexture((WGPUDevice)get(), &descriptor)); } void device::reference(void * ptr) { wgpuDeviceReference((WGPUDevice)ptr); } void device::release(void * ptr) { wgpuDeviceRelease((WGPUDevice)ptr); } }