236 lines
11 KiB
C++
236 lines
11 KiB
C++
#include <psemek/wgpu/device.hpp>
|
|
#include <psemek/wgpu/external/webgpu.h>
|
|
|
|
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));
|
|
}
|
|
|
|
compute_pipeline device::create_compute_pipeline(compute_pipeline::descriptor const & desc)
|
|
{
|
|
std::vector<WGPUConstantEntry> constants;
|
|
for (auto const & constant_in : desc.compute.constants)
|
|
{
|
|
auto & constant_out = 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;
|
|
}
|
|
|
|
WGPUComputePipelineDescriptor descriptor = {};
|
|
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
|
|
descriptor.label = desc.label.data();
|
|
descriptor.layout = (WGPUPipelineLayout)desc.layout.get();
|
|
descriptor.compute.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.compute.chain);
|
|
descriptor.compute.module = (WGPUShaderModule)desc.compute.module.get();
|
|
descriptor.compute.entryPoint = desc.compute.entry_point.data();
|
|
descriptor.compute.constantCount = constants.size();
|
|
descriptor.compute.constants = constants.data();
|
|
|
|
return compute_pipeline(wgpuDeviceCreateComputePipeline((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<WGPUConstantEntry> 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<WGPUVertexBufferLayout> 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<WGPUConstantEntry> fragment_constants;
|
|
std::vector<WGPUColorTargetState> 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<WGPUShaderModuleCompilationHint> 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);
|
|
}
|
|
|
|
}
|