WebGPU wrapper wip: add shader module object

This commit is contained in:
Nikita Lisitsa 2023-12-31 13:51:15 +03:00
parent 20a114eb41
commit 260d584df8
5 changed files with 252 additions and 2 deletions

View file

@ -0,0 +1,24 @@
#pragma once
#include <psemek/wgpu/detail/object.hpp>
namespace psemek::wgpu
{
struct pipeline_layout
: detail::object<pipeline_layout>
{
using detail::object<pipeline_layout>::object;
static void reference(void * ptr);
static void release(void * ptr);
private:
explicit pipeline_layout(void * ptr)
: detail::object<pipeline_layout>(ptr)
{}
friend struct device;
};
}

View file

@ -0,0 +1,120 @@
#pragma once
#include <psemek/wgpu/chained_struct.hpp>
#include <psemek/wgpu/pipeline_layout.hpp>
#include <psemek/wgpu/detail/object.hpp>
#include <psemek/util/span.hpp>
#include <cstdint>
#include <string>
#include <functional>
#include <vector>
namespace psemek::wgpu
{
enum class shader_stage {
none = 0x00000000,
vertex = 0x00000001,
fragment = 0x00000002,
compute = 0x00000004,
};
struct shader_module
: detail::object<shader_module>
{
using detail::object<shader_module>::object;
enum class compilation_info_request_status : std::uint32_t
{
success = 0x00000000,
error = 0x00000001,
device_lost = 0x00000002,
unknown = 0x00000003,
};
enum class compilation_message_type : std::uint32_t
{
error = 0x00000000,
warning = 0x00000001,
info = 0x00000002,
};
struct compilation_message
{
std::vector<chained_struct> chain = {};
std::string message = {};
compilation_message_type type;
std::uint64_t line_num;
std::uint64_t line_pos;
std::uint64_t offset;
std::uint64_t length;
std::uint64_t utf16_line_pos;
std::uint64_t utf16_offset;
std::uint64_t utf16_length;
};
struct compilation_info
{
std::vector<chained_struct> chain = {};
std::vector<compilation_message> messages = {};
};
struct compilation_hint
{
std::vector<chained_struct> chain = {};
std::string entryPoint;
pipeline_layout layout;
};
struct define
{
char const * name;
char const * value;
};
struct descriptor
{
std::vector<chained_struct> chain = {};
std::string label = {};
std::vector<compilation_hint> hints = {};
};
struct spirv_descriptor
{
util::span<std::uint32_t const> code;
};
struct wgsl_descriptor
{
char const * code;
};
struct glsl_descriptor
{
shader_stage stage;
char const * code;
std::vector<define> defines = {};
};
using compilation_info_callback = std::function<void(compilation_info_request_status, compilation_info const &)>;
void get_compilation_info(compilation_info_callback const & callback);
void set_label(std::string const & label);
static void reference(void * ptr);
static void release(void * ptr);
private:
explicit shader_module(void * ptr)
: detail::object<shader_module>(ptr)
{}
friend struct device;
};
detail::chained_struct_ptr to_chained_struct(shader_module::spirv_descriptor const & value);
detail::chained_struct_ptr to_chained_struct(shader_module::wgsl_descriptor const & value);
detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor const & value);
}

View file

@ -8,7 +8,7 @@
WGPUComputePipeline
- WGPUDevice
+ WGPUInstance
WGPUPipelineLayout
- WGPUPipelineLayout
+ WGPUQuerySet
+ WGPUQueue
WGPURenderBundle
@ -16,7 +16,7 @@
- WGPURenderPassEncoder
WGPURenderPipeline
WGPUSampler
WGPUShaderModule
+ WGPUShaderModule
+ WGPUSurface
+ WGPUTexture
+ WGPUTextureView

View file

@ -0,0 +1,17 @@
#include <psemek/wgpu/pipeline_layout.hpp>
#include <psemek/wgpu/external/webgpu.h>
namespace psemek::wgpu
{
void pipeline_layout::reference(void * ptr)
{
wgpuPipelineLayoutReference((WGPUPipelineLayout)ptr);
}
void pipeline_layout::release(void * ptr)
{
wgpuPipelineLayoutRelease((WGPUPipelineLayout)ptr);
}
}

View file

@ -0,0 +1,89 @@
#include <psemek/wgpu/shader_module.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
#include <memory>
namespace psemek::wgpu
{
void shader_module::get_compilation_info(compilation_info_callback const & callback)
{
auto userdata = new compilation_info_callback(callback);
auto real_callback = [](WGPUCompilationInfoRequestStatus status, WGPUCompilationInfo const * info, void * userdata)
{
std::unique_ptr<compilation_info_callback> callback((compilation_info_callback *)userdata);
// TODO support chained struct
compilation_info cinfo;
if (info)
{
for (std::size_t i = 0; i < info->messageCount; ++i)
{
auto & message = cinfo.messages.emplace_back();
auto & message_in = info->messages[i];
message.message = message_in.message;
message.type = (compilation_message_type)message_in.type;
message.line_num = message_in.lineNum;
message.line_pos = message_in.linePos;
message.offset = message_in.offset;
message.length = message_in.length;
message.utf16_line_pos = message_in.utf16LinePos;
message.utf16_offset = message_in.utf16Offset;
message.utf16_length = message_in.utf16Length;
}
}
if (*callback) (*callback)((compilation_info_request_status)status, cinfo);
};
wgpuShaderModuleGetCompilationInfo((WGPUShaderModule)get(), real_callback, userdata);
}
void shader_module::set_label(std::string const & label)
{
wgpuShaderModuleSetLabel((WGPUShaderModule)get(), label.data());
}
void shader_module::reference(void * ptr)
{
wgpuShaderModuleReference((WGPUShaderModule)ptr);
}
void shader_module::release(void * ptr)
{
wgpuShaderModuleRelease((WGPUShaderModule)ptr);
}
detail::chained_struct_ptr to_chained_struct(shader_module::spirv_descriptor const & value)
{
WGPUShaderModuleSPIRVDescriptor chained = {};
chained.chain.sType = WGPUSType_ShaderModuleSPIRVDescriptor;
chained.codeSize = value.code.size(); // TODO: is it in bytes or in words?
chained.code = value.code.data();
return detail::make_chained_struct(chained);
}
detail::chained_struct_ptr to_chained_struct(shader_module::wgsl_descriptor const & value)
{
WGPUShaderModuleWGSLDescriptor chained = {};
chained.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
chained.code = value.code;
return detail::make_chained_struct(chained);
}
detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor const & value)
{
WGPUShaderModuleGLSLDescriptor chained = {};
chained.chain.sType = (WGPUSType)WGPUSType_ShaderModuleGLSLDescriptor;
chained.stage = (WGPUShaderStage)value.stage;
chained.code = value.code;
chained.defineCount = value.defines.size();
static_assert(sizeof(WGPUShaderDefine) == sizeof(shader_module::define));
chained.defines = (WGPUShaderDefine *)value.defines.data();
return detail::make_chained_struct(chained);
}
}