Add idl codegen

This commit is contained in:
Cloud Wu 2019-02-27 17:49:28 +08:00
parent 1243551c22
commit e9cd8b5532
5 changed files with 1432 additions and 0 deletions

93
scripts/bgfx-idl.lua Normal file
View File

@ -0,0 +1,93 @@
-- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
-- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
local idl = require "idl"
local codegen = require "codegen"
assert(loadfile("bgfx.idl" , "t", idl))()
codegen.nameconversion(idl.types, idl.funcs)
local code_temp_include = [[
/*
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
/*
*
* AUTO GENERATED! DO NOT EDIT!
*
*/
$c99decl
/**/
typedef struct bgfx_interface_vtbl
{
$interface_struct
} bgfx_interface_vtbl_t;
]]
local code_temp_impl = [[
/*
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
/*
*
* AUTO GENERATED! DO NOT EDIT!
*
*/
$c99
/**/
BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version)
{
if (_version == BGFX_API_VERSION)
{
static bgfx_interface_vtbl_t s_bgfx_interface =
{
$interface_import
};
return &s_bgfx_interface;
}
return NULL;
}
]]
local function codes()
local temp = {}
local action = {
c99 = "\n",
c99decl = "\n",
interface_struct = "\n\t",
interface_import = ",\n\t\t\t",
}
for k in pairs(action) do
temp[k] = {}
end
for _, f in ipairs(idl.funcs) do
for k in pairs(action) do
table.insert(temp[k], (codegen["gen_"..k](f)))
end
end
for k, ident in pairs(action) do
temp[k] = table.concat(temp[k], ident)
end
return temp
end
local codes_tbl = codes()
for filename, temp in pairs {
["../include/bgfx/c99/bgfx.idl.h"] = code_temp_include ,
["../src/bgfx.idl.inl"] = code_temp_impl } do
print ("Generate " .. filename)
local out = io.open(filename, "wb")
out:write((temp:gsub("$([%l%d_]+)", codes_tbl)))
out:close()
end

955
scripts/bgfx.idl Normal file
View File

@ -0,0 +1,955 @@
-- bgfx interface
typedef "bool"
typedef "char"
typedef "float"
typedef "int32_t"
typedef "uint8_t"
typedef "uint16_t"
typedef "uint32_t"
typedef "uint64_t"
typedef "uintptr_t"
typedef "va_list"
typedef "void"
typedef "Attachment"
typedef "Caps"
typedef "Encoder"
typedef "Init"
typedef "InstanceDataBuffer"
typedef "InternalData"
typedef "Memory"
typedef "PlatformData"
typedef "ReleaseFn"
typedef "Stats"
typedef "TextureInfo"
typedef "Transform"
typedef "TransientIndexBuffer"
typedef "TransientVertexBuffer"
typedef "UniformInfo"
typedef "VertexDecl"
typedef "ViewId"
typedef.Access { enum }
typedef.Attrib { enum }
typedef.AttribType { enum }
typedef.BackbufferRatio { enum }
typedef.OcclusionQueryResult { enum }
typedef.RenderFrame { enum }
typedef.RendererType { enum }
typedef.TextureFormat { enum }
typedef.TopologyConvert { enum }
typedef.TopologySort { enum }
typedef.UniformType { enum }
typedef.ViewMode { enum }
typedef.DynamicIndexBufferHandle { handle }
typedef.DynamicVertexBufferHandle { handle }
typedef.FrameBufferHandle { handle }
typedef.IndexBufferHandle { handle }
typedef.IndirectBufferHandle { handle }
typedef.OcclusionQueryHandle { handle }
typedef.ProgramHandle { handle }
typedef.ShaderHandle { handle }
typedef.TextureHandle { handle }
typedef.UniformHandle { handle }
typedef.VertexBufferHandle { handle }
typedef.VertexDeclHandle { handle }
func.VertexDecl.begin
"void"
.renderer "RendererType::Enum"
func.VertexDecl.add
"void"
.attrib "Attrib::Enum"
.num "uint8_t"
.type "AttribType::Enum"
.normalized "bool"
.asInt "bool"
func.VertexDecl.decode { const }
"void"
.attrib "Attrib::Enum"
.num "uint8_t &" { out }
.type "AttribType::Enum &" { out }
.normalized "bool &" { out }
.asInt "bool &" { out }
func.VertexDecl.has { const }
"bool"
.attrib "Attrib::Enum"
func.VertexDecl.skip
"void"
.num "uint8_t"
-- Notice: `end` is a keyword in lua
func.VertexDecl["end"]
"void"
func.vertexPack
"void"
.input "const float *"
.inputNormalized "bool"
.attr "Attrib::Enum"
.decl "const VertexDecl &"
.data "void *"
.index "uint32_t"
func.vertexUnpack
"void"
.output "float *" { out }
.attr "Attrib::Enum"
.decl "const VertexDecl &"
.data "const void *"
.index "uint32_t"
func.vertexConvert
"void"
.dstDecl "const VertexDecl &"
.dstData "void *"
.srcDecl "const VertexDecl &"
.srcData "const void *"
.num "uint32_t"
func.weldVertices
"uint16_t"
.output "uint16_t *"
.decl "const VertexDecl &"
.data "const void *"
.num "uint16_t"
.epsilon "float"
func.topologyConvert
"uint32_t"
.conversion "TopologyConvert::Enum"
.dst "void *" { out }
.dstSize "uint32_t"
.indices "const void *"
.numIndices "uint32_t"
.index32 "bool"
func.topologySortTriList
"void"
.sort "TopologySort::Enum"
.dst "void *" { out }
.dstSize "uint32_t"
.dir "const float *"
.pos "const float *"
.vertices "const void *"
.stride "uint32_t"
.indices "const void *"
.numIndices "uint32_t"
.index32 "bool"
func.getSupportedRenderers
"uint8_t"
.max "uint8_t"
.enum "RendererType::Enum *" { out }
func.getRendererName
"const char *"
.type "RendererType::Enum"
local init_ctor = [[
BX_PLACEMENT_NEW(_init, bgfx::Init);
]]
func.initCtor { cfunc = init_ctor }
"void"
.init "Init *"
local init = [[
bgfx_init_t init = *_init;
if (init.callback != NULL)
{
static bgfx::CallbackC99 s_callback;
s_callback.m_interface = init.callback;
init.callback = reinterpret_cast<bgfx_callback_interface_t *>(&s_callback);
}
if (init.allocator != NULL)
{
static bgfx::AllocatorC99 s_allocator;
s_allocator.m_interface = init.allocator;
init.allocator = reinterpret_cast<bgfx_allocator_interface_t *>(&s_allocator);
}
union { const bgfx_init_t* c; const bgfx::Init* cpp; } in;
in.c = &init;
return bgfx::init(*in.cpp);
]]
func.init { cfunc = init }
"bool"
.init "const Init &"
func.shutdown
"void"
func.reset
"void"
.width "uint32_t"
.height "uint32_t"
.flags "uint32_t"
.format "TextureFormat::Enum"
func.frame
"uint32_t"
.capture "bool"
func.getRendererType
"RendererType::Enum"
func.getCaps
"const Caps *"
func.getStats
"const Stats *"
func.alloc
"const Memory *"
.size "uint32_t"
func.copy
"const Memory *"
.data "const void *"
.size "uint32_t"
func.makeRef
"const Memory *"
.data "const void *"
.size "uint32_t"
func.makeRef { cname = "make_ref_release" }
"const Memory *"
.data "const void *"
.size "uint32_t"
.releaseFn "ReleaseFn"
.userData "void *"
func.setDebug
"void"
.debug "uint32_t"
func.dbgTextClear
"void"
.attr "uint8_t"
.small "bool"
func.dbgTextPrintf { vararg = "dbgTextPrintfVargs" }
"void"
.x "uint16_t"
.y "uint16_t"
.attr "uint8_t"
.format "const char *"
func.dbgTextPrintfVargs { cname = "dbg_text_vprintf" }
"void"
.x "uint16_t"
.y "uint16_t"
.attr "uint8_t"
.format "const char *"
.argList "va_list"
func.dbgTextImage
"void"
.x "uint16_t"
.y "uint16_t"
.width "uint16_t"
.height "uint16_t"
.data "const void *"
.pitch "uint16_t"
func.createIndexBuffer
"IndexBufferHandle"
.mem "const Memory *"
.flags "uint16_t"
func.setName { cname = "set_index_buffer_name" }
"void"
.handle "IndexBufferHandle"
.name "const char *"
.len "int32_t"
func.destroy { cname = "destroy_index_buffer" }
"void"
.handle "IndexBufferHandle"
func.createVertexBuffer
"VertexBufferHandle"
.mem "const Memory *"
.decl "const VertexDecl &"
.flags "uint16_t"
func.setName { cname = "set_vertex_buffer_name" }
"void"
.handle "VertexBufferHandle"
.name "const char *"
.len "int32_t"
func.destroy { cname = "destroy_vertex_buffer" }
"void"
.handle "VertexBufferHandle"
func.createDynamicIndexBuffer
"DynamicIndexBufferHandle"
.num "uint32_t"
.flags "uint16_t"
func.createDynamicIndexBuffer { cname = "create_dynamic_index_buffer_mem" }
"DynamicIndexBufferHandle"
.mem "const Memory *"
.flags "uint16_t"
func.update { cname = "update_dynamic_index_buffer" }
"void"
.handle "DynamicIndexBufferHandle"
.startIndex "uint32_t"
.mem "const Memory *"
func.destroy { cname = "destroy_dynamic_index_buffer" }
"void"
.handle "DynamicIndexBufferHandle"
func.createDynamicVertexBuffer
"DynamicVertexBufferHandle"
.num "uint32_t"
.decl "const VertexDecl &"
.flags "uint16_t"
func.createDynamicVertexBuffer { cname = "create_dynamic_vertex_buffer_mem" }
"DynamicVertexBufferHandle"
.mem "const Memory *"
.decl "const VertexDecl &"
.flags "uint16_t"
func.update { cname = "update_dynamic_vertex_buffer" }
"void"
.handle "DynamicVertexBufferHandle"
.startVertex "uint32_t"
.mem "const Memory *"
func.destroy { cname = "destroy_dynamic_vertex_buffer" }
"void"
.handle "DynamicVertexBufferHandle"
func.getAvailTransientIndexBuffer
"uint32_t"
.num "uint32_t"
func.getAvailTransientVertexBuffer
"uint32_t"
.num "uint32_t"
.decl "const VertexDecl &"
func.getAvailInstanceDataBuffer
"uint32_t"
.num "uint32_t"
.stride "uint16_t"
func.allocTransientIndexBuffer
"void"
.tib "TransientIndexBuffer *" { out }
.num "uint32_t"
func.allocTransientVertexBuffer
"void"
.tvb "TransientVertexBuffer *" { out }
.num "uint32_t"
.decl "const VertexDecl &"
func.allocTransientBuffers
"bool"
.tvb "TransientVertexBuffer *" { out }
.decl "const VertexDecl &"
.numVertices "uint32_t"
.tib "TransientIndexBuffer *" { out }
.numIndices "uint32_t"
func.allocInstanceDataBuffer
"void"
.idb "InstanceDataBuffer *" { out }
.num "uint32_t"
.stride "uint16_t"
func.createIndirectBuffer
"IndirectBufferHandle"
.num "uint32_t"
func.destroy { cname = "destroy_indirect_buffer" }
"void"
.handle "IndirectBufferHandle"
func.createShader
"ShaderHandle"
.mem "const Memory *"
func.getShaderUniforms
"uint16_t"
.handle "ShaderHandle"
.uniforms "UniformHandle *" { out }
.max "uint16_t"
func.setName { cname = "set_shader_name" }
"void"
.handle "ShaderHandle"
.name "const char *"
.len "int32_t"
func.destroy { cname = "destroy_shader" }
"void"
.handle "ShaderHandle"
func.createProgram
"ProgramHandle"
.vsh "ShaderHandle"
.fsh "ShaderHandle"
.destroyShaders "bool"
func.createProgram { cname = "create_compute_program" }
"ProgramHandle"
.csh "ShaderHandle"
.destroyShaders "bool"
func.destroy { cname = "destroy_program" }
"void"
.handle "ProgramHandle"
func.isTextureValid
"bool"
.depth "uint16_t"
.cubeMap "bool"
.numLayers "uint16_t"
.format "TextureFormat::Enum"
.flags "uint64_t"
func.calcTextureSize
"void"
.info "TextureInfo &" { out }
.width "uint16_t"
.height "uint16_t"
.depth "uint16_t"
.cubeMap "bool"
.hasMips "bool"
.numLayers "uint16_t"
.format "TextureFormat::Enum"
func.createTexture
"TextureHandle"
.mem "const Memory *"
.flags "uint64_t"
.skip "uint8_t"
.info "TextureInfo *" { out }
func.createTexture2D
"TextureHandle"
.width "uint16_t"
.height "uint16_t"
.hasMips "bool"
.numLayers "uint16_t"
.format "TextureFormat::Enum"
.flags "uint64_t"
.mem "const Memory *"
func.createTexture2D { cname = "create_texture_2d_scaled" }
"TextureHandle"
.ratio "BackbufferRatio::Enum"
.hasMips "bool"
.numLayers "uint16_t"
.format "TextureFormat::Enum"
.flags "uint64_t"
func.createTexture3D
"TextureHandle"
.width "uint16_t"
.height "uint16_t"
.depth "uint16_t"
.hasMips "bool"
.format "TextureFormat::Enum"
.flags "uint64_t"
.mem "const Memory *"
func.createTextureCube
"TextureHandle"
.size "uint16_t"
.hasMips "bool"
.numLayers "uint16_t"
.format "TextureFormat::Enum"
.flags "uint64_t"
.mem "const Memory *"
func.updateTexture2D
"void"
.handle "TextureHandle"
.layer "uint16_t"
.mip "uint16_t"
.x "uint16_t"
.y "uint16_t"
.width "uint16_t"
.height "uint16_t"
.mem "const Memory *"
.pitch "uint16_t"
func.updateTexture3D
"void"
.handle "TextureHandle"
.mip "uint16_t"
.x "uint16_t"
.y "uint16_t"
.z "uint16_t"
.width "uint16_t"
.height "uint16_t"
.depth "uint16_t"
.mem "const Memory *"
func.updateTextureCube
"void"
.handle "TextureHandle"
.layer "uint16_t"
.side "uint8_t"
.mip "uint8_t"
.x "uint16_t"
.y "uint16_t"
.width "uint16_t"
.height "uint16_t"
.mem "const Memory *"
.pitch "uint16_t"
func.readTexture
"uint32_t"
.handle "TextureHandle"
.data "void *"
.mip "uint8_t"
func.setName { cname = "set_texture_name" }
"void"
.handle "TextureHandle"
.name "const char *"
.len "int32_t"
func.getDirectAccessPtr
"void *"
.handle "TextureHandle"
func.destroy { cname = "destroy_texture" }
"void"
.handle "TextureHandle"
func.createFrameBuffer
"FrameBufferHandle"
.width "uint16_t"
.height "uint16_t"
.format "TextureFormat::Enum"
.textureFlags "uint64_t"
func.createFrameBuffer { cname = "create_frame_buffer_scaled" }
"FrameBufferHandle"
.ratio "BackbufferRatio::Enum"
.format "TextureFormat::Enum"
.textureFlags "uint64_t"
func.createFrameBuffer { cname = "create_frame_buffer_from_handles" }
"FrameBufferHandle"
.num "uint8_t"
.handles "const TextureHandle *"
.destroyTexture "bool"
func.createFrameBuffer { cname = "create_frame_buffer_from_attachment" }
"FrameBufferHandle"
.num "uint8_t"
.handles "const Attachment *"
.destroyTexture "bool"
func.createFrameBuffer { cname = "create_frame_buffer_from_nwh" }
"FrameBufferHandle"
.nwh "void *"
.width "uint16_t"
.height "uint16_t"
.format "TextureFormat::Enum"
.depthFormat "TextureFormat::Enum"
func.setName { cname = "set_frame_buffer_name" }
"void"
.handle "FrameBufferHandle"
.name "const char *"
.len "int32_t"
func.getTexture
"TextureHandle"
.handle "FrameBufferHandle"
.attachment "uint8_t"
func.destroy { cname = "destroy_frame_buffer" }
"void"
.handle "FrameBufferHandle"
func.createUniform
"UniformHandle"
.name "const char *"
.type "UniformType::Enum"
.num "uint16_t"
func.getUniformInfo
"void"
.handle "UniformHandle"
.info "UniformInfo &" { out }
func.destroy { cname = "destroy_uniform" }
"void"
.handle "UniformHandle"
func.createOcclusionQuery
"OcclusionQueryHandle"
func.getResult
"OcclusionQueryResult::Enum"
.handle "OcclusionQueryHandle"
.result "int32_t *" { out }
func.destroy { cname = "destroy_occlusion_query" }
"void"
.handle "OcclusionQueryHandle"
func.setPaletteColor
"void"
.index "uint8_t"
.rgba "const float *"
func.setViewName
"void"
.id "ViewId"
.name "const char *"
func.setViewRect
"void"
.id "ViewId"
.x "uint16_t"
.y "uint16_t"
.width "uint16_t"
.height "uint16_t"
func.setViewRect { cname = "set_view_rect_ratio" }
"void"
.id "ViewId"
.x "uint16_t"
.y "uint16_t"
.ratio "BackbufferRatio::Enum"
func.setViewScissor
"void"
.id "ViewId"
.x "uint16_t"
.y "uint16_t"
.width "uint16_t"
.height "uint16_t"
func.setViewClear
"void"
.id "ViewId"
.flags "uint16_t"
.rgba "uint32_t"
.depth "float"
.stencil "uint8_t"
func.setViewClear { cname = "set_view_clear_mrt" }
"void"
.id "ViewId"
.flags "uint16_t"
.depth "float"
.stencil "uint8_t"
.c0 "uint8_t"
.c1 "uint8_t"
.c2 "uint8_t"
.c3 "uint8_t"
.c4 "uint8_t"
.c5 "uint8_t"
.c6 "uint8_t"
.c7 "uint8_t"
func.setViewMode
"void"
.id "ViewId"
.mode "ViewMode::Enum"
func.setViewFrameBuffer
"void"
.id "ViewId"
.handle "FrameBufferHandle"
func.setViewTransform
"void"
.id "ViewId"
.view "const void *"
.proj "const void *"
func.setViewOrder
"void"
.id "ViewId"
.num "uint16_t"
.order "const ViewId *"
func.begin { cname = "encoder_begin" }
"Encoder *"
.forThread "bool"
func["end"] { cname = "encoder_end" }
"void"
.encoder "Encoder *"
func.Encoder.setMarker
"void"
.marker "const char *"
func.Encoder.setState
"void"
.state "uint64_t"
.rgba "uint32_t"
func.Encoder.setCondition
"void"
.handle "OcclusionQueryHandle"
.visible "bool"
func.Encoder.setStencil
"void"
.fstencil "uint32_t"
.bstencil "uint32_t"
func.Encoder.setScissor
"uint16_t"
.x "uint16_t"
.y "uint16_t"
.width "uint16_t"
.height "uint16_t"
func.Encoder.setScissor { cname = "set_scissor_cached" }
"void"
.cache "uint16_t"
func.Encoder.setTransform
"uint32_t"
.mtx "const void *"
.num "uint16_t"
func.Encoder.setTransform { cname = "set_transform_cached" }
"void"
.cache "uint32_t"
.num "uint16_t"
func.Encoder.allocTransform
"uint32_t"
.transform "Transform *" { out }
.num "uint16_t"
func.Encoder.setUniform
"void"
.handle "UniformHandle"
.value "const void *"
.num "uint16_t"
func.Encoder.setIndexBuffer
"void"
.handle "IndexBufferHandle"
.firstIndex "uint32_t"
.numIndices "uint32_t"
func.Encoder.setIndexBuffer { cname = "set_dynamic_index_buffer" }
"void"
.handle "DynamicIndexBufferHandle"
.firstIndex "uint32_t"
.numIndices "uint32_t"
func.Encoder.setIndexBuffer { cname = "set_transient_index_buffer" }
"void"
.tib "const TransientIndexBuffer *"
.firstIndex "uint32_t"
.numIndices "uint32_t"
func.Encoder.setVertexBuffer
"void"
.stream "uint8_t"
.handle "VertexBufferHandle"
.startVertex "uint32_t"
.numVertices "uint32_t"
func.Encoder.setVertexBuffer { cname = "set_dynamic_vertex_buffer" }
"void"
.stream "uint8_t"
.handle "DynamicVertexBufferHandle"
.startVertex "uint32_t"
.numVertices "uint32_t"
func.Encoder.setVertexBuffer { cname = "set_transient_vertex_buffer" }
"void"
.stream "uint8_t"
.tvb "const TransientVertexBuffer *"
.startVertex "uint32_t"
.numVertices "uint32_t"
func.Encoder.setVertexCount
"void"
.numVertices "uint32_t"
func.Encoder.setInstanceDataBuffer
"void"
.idb "const InstanceDataBuffer *"
.start "uint32_t"
.num "uint32_t"
func.Encoder.setInstanceDataBuffer { cname = "set_instance_data_from_vertex_buffer" }
"void"
.handle "VertexBufferHandle"
.startVertex "uint32_t"
.num "uint32_t"
func.Encoder.setInstanceDataBuffer { cname = "set_instance_data_from_dynamic_vertex_buffer" }
"void"
.handle "DynamicVertexBufferHandle"
.startVertex "uint32_t"
.num "uint32_t"
func.Encoder.setInstanceCount
"void"
.numInstances "uint32_t"
func.Encoder.setTexture
"void"
.stage "uint8_t"
.sampler "UniformHandle"
.handle "TextureHandle"
.flags "uint32_t"
func.Encoder.touch
"void"
.id "ViewId"
func.Encoder.submit
"void"
.id "ViewId"
.program "ProgramHandle"
.depth "uint32_t"
.preserveState "bool"
func.Encoder.submit { cname = "submit_occlusion_query" }
"void"
.id "ViewId"
.program "ProgramHandle"
.occlusionQuery "OcclusionQueryHandle"
.depth "uint32_t"
.preserveState "bool"
func.Encoder.submit { cname = "submit_indirect" }
"void"
.id "ViewId"
.program "ProgramHandle"
.indirectHandle "IndirectBufferHandle"
.start "uint16_t"
.num "uint16_t"
.depth "uint32_t"
.preserveState "bool"
func.Encoder.setBuffer { cname = "set_compute_index_buffer" }
"void"
.stage "uint8_t"
.handle "IndexBufferHandle"
.access "Access::Enum"
func.Encoder.setBuffer { cname = "set_compute_vertex_buffer" }
"void"
.stage "uint8_t"
.handle "VertexBufferHandle"
.access "Access::Enum"
func.Encoder.setBuffer { cname = "set_compute_dynamic_index_buffer" }
"void"
.stage "uint8_t"
.handle "DynamicIndexBufferHandle"
.access "Access::Enum"
func.Encoder.setBuffer { cname = "set_compute_dynamic_vertex_buffer" }
"void"
.stage "uint8_t"
.handle "DynamicVertexBufferHandle"
.access "Access::Enum"
func.Encoder.setBuffer { cname = "set_compute_indirect_buffer" }
"void"
.stage "uint8_t"
.handle "IndirectBufferHandle"
.access "Access::Enum"
func.Encoder.setImage
"void"
.stage "uint8_t"
.handle "TextureHandle"
.mip "uint8_t"
.access "Access::Enum"
.format "TextureFormat::Enum"
func.Encoder.dispatch
"void"
.id "ViewId"
.program "ProgramHandle"
.numX "uint32_t"
.numY "uint32_t"
.numZ "uint32_t"
func.Encoder.dispatch { cname = "dispatch_indirect" }
"void"
.id "ViewId"
.program "ProgramHandle"
.indirectHandle "IndirectBufferHandle"
.start "uint16_t"
.num "uint16_t"
func.Encoder.discard
"void"
func.Encoder.blit
"void"
.id "ViewId"
.dst "TextureHandle"
.dstMip "uint8_t"
.dstX "uint16_t"
.dstY "uint16_t"
.dstZ "uint16_t"
.src "TextureHandle"
.srcMip "uint8_t"
.srcX "uint16_t"
.srcY "uint16_t"
.srcZ "uint16_t"
.width "uint16_t"
.height "uint16_t"
.depth "uint16_t"
func.requestScreenShot
"void"
.handle "FrameBufferHandle"
.filePath "const char *"
func.renderFrame
"RenderFrame::Enum"
.msecs "int32_t"
func.setPlatformData
"void"
.data "const PlatformData &"
func.getInternalData
"const InternalData *"
func.overrideInternal { cname = "override_internal_texture_ptr" }
"uintptr_t"
.handle "TextureHandle"
.ptr "uintptr_t"
func.overrideInternal { cname = "override_internal_texture" }
"uintptr_t"
.handle "TextureHandle"
.width "uint16_t"
.height "uint16_t"
.numMips "uint8_t"
.format "TextureFormat::Enum"
.flags "uint32_t"

271
scripts/codegen.lua Normal file
View File

@ -0,0 +1,271 @@
-- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
-- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
local codegen = {}
local function camelcase_to_underscorecase(name)
local tmp = {}
for v in name:gmatch "[%u%d]+%l*" do
tmp[#tmp+1] = v:lower()
end
return table.concat(tmp, "_")
end
local function convert_typename(name)
if name:match "^%u" then
return "bgfx_" .. camelcase_to_underscorecase(name) .. "_t"
else
return name
end
end
local function convert_funcname(name)
name = name:gsub("^%l", string.upper) -- Change to upper CamlCase
return camelcase_to_underscorecase(name)
end
local function convert_arg(all_types, arg, what)
local t, postfix = arg.fulltype:match "(%a[%a%d_:]*)%s*([*&]+)%s*$"
if t then
arg.type = t
if postfix == "&" then
arg.ref = true
end
else
arg.type = arg.fulltype
end
local ctype = all_types[arg.type]
if not ctype then
error ("Undefined type " .. arg.fulltype .. " for " .. what)
end
arg.ctype = arg.fulltype:gsub(arg.type, ctype.cname):gsub("&", "*")
if ctype.cname ~= arg.type then
arg.cpptype = arg.fulltype:gsub(arg.type, "bgfx::"..arg.type)
else
arg.cpptype = arg.fulltype
end
if arg.ref then
arg.ptype = arg.cpptype:gsub("&", "*")
end
end
local function alternative_name(name)
if name:sub(1,1) == "_" then
return name:sub(2)
else
return name .. "_"
end
end
local function gen_arg_conversion(all_types, arg)
if arg.ctype == arg.fulltype then
-- do not need conversion
arg.aname = arg.name
return
end
local ctype = all_types[arg.type]
if ctype.handle and arg.type == arg.fulltype then
local aname = alternative_name(arg.name)
arg.aname = aname .. ".cpp"
arg.conversion = string.format(
"union { %s c; bgfx::%s cpp; } %s = { %s };" ,
ctype.cname, arg.type, aname, arg.name)
elseif arg.ref then
if ctype.cname == arg.type then
arg.aname = "*" .. arg.name
elseif arg.out and ctype.enum then
local aname = alternative_name(arg.name)
local cpptype = arg.cpptype:match "(.-)%s*&" -- remove &
arg.aname = aname
arg.conversion = string.format("%s %s;", cpptype, aname)
arg.out_conversion = string.format("*%s = (%s)%s;", arg.name, ctype.cname, aname)
else
arg.aname = alternative_name(arg.name)
arg.conversion = string.format(
"%s %s = *(%s)%s;",
arg.cpptype, arg.aname, arg.ptype, arg.name)
end
else
arg.aname = string.format(
"(%s)%s",
arg.cpptype, arg.name)
end
end
local function gen_ret_conversion(all_types, func)
local postfix = { func.vararg and "va_end(argList);" }
func.ret_postfix = postfix
for _, arg in ipairs(func.args) do
if arg.out_conversion then
postfix[#postfix+1] = arg.out_conversion
end
end
local ctype = all_types[func.ret.type]
if ctype.handle then
func.ret_conversion = string.format(
"union { %s c; bgfx::%s cpp; } handle_ret;" ,
ctype.cname, func.ret.type)
func.ret_prefix = "handle_ret.cpp = "
postfix[#postfix+1] = "return handle_ret.c;"
elseif func.ret.fulltype ~= "void" then
local ctype_conversion = func.ret.type == func.ret.ctype and "" or ("(" .. func.ret.ctype .. ")")
if #postfix > 0 then
func.ret_prefix = string.format("%s retValue = %s", func.ret.ctype , ctype_conversion)
postfix[#postfix+1] = "return retValue;"
else
func.ret_prefix = string.format("return %s", ctype_conversion)
end
end
end
function codegen.nameconversion(all_types, all_funcs)
local enums = {}
for k,v in pairs(all_types) do
if not v.cname then
v.cname = convert_typename(k)
end
if v.enum then
enums[#enums+1] = k
end
end
for _, e in ipairs(enums) do
local t = all_types[e]
all_types[e] = nil
all_types[e .. "::Enum"] = t
end
for _,v in ipairs(all_funcs) do
if v.cname == nil then
v.cname = convert_funcname(v.name)
end
if v.class then
v.cname = convert_funcname(v.class) .. "_" .. v.cname
end
for _, arg in ipairs(v.args) do
convert_arg(all_types, arg, v.name)
gen_arg_conversion(all_types, arg)
end
if v.vararg then
local args = v.args
local vararg = {
name = "",
ctype = "...",
aname = "argList",
conversion = string.format(
"va_list argList;\n\tva_start(argList, %s);",
args[#args].name),
}
args[#args + 1] = vararg
v.implname = v.vararg
else
v.implname = v.name
end
convert_arg(all_types, v.ret, v.name .. "@rettype")
gen_ret_conversion(all_types, v)
if v.class then
local classname = v.class
if v.const then
classname = "const " .. classname
end
local classtype = { fulltype = classname .. "*" }
convert_arg(all_types, classtype, "class member " .. v.name)
v.this = classtype.ctype .. " _this"
v.this_conversion = string.format( "%s This = (%s)_this;", classtype.cpptype, classtype.cpptype)
end
end
end
local function lines(tbl)
if #tbl == 0 then
return "//EMPTYLINE"
else
return table.concat(tbl, "\n\t")
end
end
local function remove_emptylines(txt)
return (txt:gsub("\t//EMPTYLINE\n", ""))
end
local function codetemp(func)
local conversion = {}
local args = {}
local callargs = {}
local cppfunc
if func.class then
-- It's a member function
args[1] = func.this
conversion[1] = func.this_conversion
cppfunc = "This->" .. func.name
else
cppfunc = "bgfx::" .. func.implname
end
for _, arg in ipairs(func.args) do
conversion[#conversion+1] = arg.conversion
args[#args+1] = arg.ctype .. " " .. arg.name
callargs[#callargs+1] = arg.aname
end
conversion[#conversion+1] = func.ret_conversion
return {
RET = func.ret.ctype,
FUNCNAME = func.cname,
ARGS = table.concat(args, ", "),
CONVERSION = lines(conversion),
PRERET = func.ret_prefix or "",
CPPFUNC = cppfunc,
CALLARGS = table.concat(callargs, ", "),
POSTRET = lines(func.ret_postfix),
CODE = func.cfunc,
}
end
local function apply_template(func, temp)
func.codetemp = func.codetemp or codetemp(func)
return (temp:gsub("$(%u+)", func.codetemp))
end
local c99temp = [[
BGFX_C_API $RET bgfx_$FUNCNAME($ARGS)
{
$CONVERSION
$PRERET$CPPFUNC($CALLARGS);
$POSTRET
}
]]
local c99usertemp = [[
BGFX_C_API $RET bgfx_$FUNCNAME($ARGS)
{
$CODE
}
]]
function codegen.gen_c99(func)
if func.cfunc then
return apply_template(func, c99usertemp)
else
return remove_emptylines(apply_template(func, c99temp))
end
end
local template_function_declaration = [[
/**/
BGFX_C_API $RET bgfx_$FUNCNAME($ARGS);
]]
function codegen.gen_c99decl(func)
return apply_template(func, template_function_declaration)
end
function codegen.gen_interface_struct(func)
return apply_template(func, "$RET (*$FUNCNAME)($ARGS);")
end
function codegen.gen_interface_import(func)
return "bgfx_" .. func.cname
end
return codegen

View File

@ -48,6 +48,14 @@ newoption {
description = "Enable building examples.",
}
dofile "bgfx-idl.lua"
newaction {
trigger = "idl",
description = "Generate bgfx interface source code",
execute = doidl
}
solution "bgfx"
configurations {
"Debug",

105
scripts/idl.lua Normal file
View File

@ -0,0 +1,105 @@
-- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
-- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
local idl = {}
local all_types = {}
local function typedef(_, typename)
assert(all_types[typename] == nil, "Duplicate type")
local t = {}
all_types[typename] = t
local function type_attrib(attrib)
assert(type(attrib) == "table", "type attrib should be a table")
for _, a in ipairs(attrib) do
t[a] = true
end
end
return function(cname)
local typ = type(cname)
if typ == "table" then
type_attrib(cname)
return
end
assert(typ == "string" , "type should be a string")
t.cname = cname
return type_attrib
end
end
idl.typedef = setmetatable({} , { __index = typedef, __call = typedef })
idl.types = all_types
local all_funcs = {}
local function duplicate_arg_name(name)
error ("Duplicate arg name " .. name)
end
local function funcdef(_, funcname)
local f = { name = funcname , args = {} }
all_funcs[#all_funcs+1] = f
local args
local function args_desc(obj, args_name)
obj[args_name] = duplicate_arg_name
return function (fulltype)
local arg = {
name = "_" .. args_name,
fulltype = fulltype,
}
f.args[#f.args+1] = arg
local function arg_attrib(_, attrib )
assert(type(attrib) == "table", "Arg attributes should be a table")
for _, a in ipairs(attrib) do
arg[a] = true
end
return args
end
return setmetatable( {} , {
__index = function(_, name)
return args_desc(obj, name)
end
, __call = arg_attrib } )
end
end
args = setmetatable({}, { __index = args_desc })
local function rettype(value)
assert(type(value) == "string", "Need return type")
f.ret = { fulltype = value }
return args
end
local function funcdef(value)
if type(value) == "table" then
for k,v in pairs(value) do
if type(k) == "number" then
f[v] = true
else
f[k] = v
end
end
return rettype
end
return rettype(value)
end
local function classfunc(_, methodname)
f.class = f.name
f.name = methodname
return funcdef
end
return setmetatable({} , { __index = classfunc, __call = function(_, value) return funcdef(value) end })
end
idl.func = setmetatable({}, { __index = funcdef })
idl.funcs = all_funcs
idl.handle = "handle"
idl.enum = "enum"
idl.out = "out"
idl.const = "const"
return setmetatable(idl , { __index = function (_, keyword)
error (tostring(keyword) .. " is invalid")
end})