Skip to content

Commit

Permalink
fix sokol-nim code generator for sokol-gfx bindings cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Oct 19, 2024
1 parent 4c270e5 commit 03ca680
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 62 deletions.
163 changes: 101 additions & 62 deletions src/shdc/generators/sokolnim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -278,21 +278,10 @@ void SokolNimGenerator::gen_shader_desc_func(const GenInput& gen, const ProgramR
Slang::Enum slang = Slang::from_index(i);
if (gen.args.slang & Slang::bit(slang)) {
l_open("of {}:\n", backend(slang));
for (int attr_index = 0; attr_index < StageAttr::Num; attr_index++) {
const StageAttr& attr = prog.vs().inputs[attr_index];
if (attr.slot >= 0) {
if (Slang::is_glsl(slang)) {
l("result.attrs[{}].name = \"{}\"\n", attr_index, attr.name);
} else if (Slang::is_hlsl(slang)) {
l("result.attrs[{}].semName = \"{}\"\n", attr_index, attr.sem_name);
l("result.attrs[{}].semIndex = {}\n", attr_index, attr.sem_index);
}
}
}
for (int stage_index = 0; stage_index < ShaderStage::Num; stage_index++) {
const ShaderStageArrayInfo& info = shader_stage_array_info(gen, prog, ShaderStage::from_index(stage_index), slang);
const StageReflection& refl = prog.stages[stage_index];
const std::string dsn = fmt::format("result.{}", pystring::lower(ShaderStage::to_str(refl.stage)));
const std::string dsn = fmt::format("result.{}", info.stage == ShaderStage::Vertex ? "vertexFunc" : "fragmentFunc");
if (info.has_bytecode) {
l("{}.bytecode.ptr = {}\n", dsn, info.bytecode_array_name);
l("{}.bytecode.size = {}\n", dsn, info.bytecode_array_size);
Expand All @@ -309,66 +298,108 @@ void SokolNimGenerator::gen_shader_desc_func(const GenInput& gen, const ProgramR
}
}
l("{}.entry = \"{}\"\n", dsn, refl.entry_point_by_slang(slang));
for (int ub_index = 0; ub_index < Bindings::MaxUniformBlocks; ub_index++) {
const UniformBlock* ub = refl.bindings.find_uniform_block_by_sokol_slot(ub_index);
if (ub) {
const std::string ubn = fmt::format("{}.uniformBlocks[{}]", dsn, ub_index);
l("{}.size = {}\n", ubn, roundup(ub->struct_info.size, 16));
l("{}.layout = uniformLayoutStd140\n", ubn);
if (Slang::is_glsl(slang) && (ub->struct_info.struct_items.size() > 0)) {
if (ub->flattened) {
l("{}.uniforms[0].name = \"{}\"\n", ubn, ub->name);
// NOT A BUG (to take the type from the first struct item, but the size from the toplevel ub)
l("{}.uniforms[0].type = {}\n", ubn, flattened_uniform_type(ub->struct_info.struct_items[0].type));
l("{}.uniforms[0].arrayCount = {}\n", ubn, roundup(ub->struct_info.size, 16) / 16);
} else {
for (int u_index = 0; u_index < (int)ub->struct_info.struct_items.size(); u_index++) {
const Type& u = ub->struct_info.struct_items[u_index];
const std::string un = fmt::format("{}.uniforms[{}]", ubn, u_index);
l("{}.name = \"{}.{}\"\n", un, ub->inst_name, u.name);
l("{}.type = {}\n", un, uniform_type(u.type));
l(".arrayCount = {}\n", un, u.array_count);
}
}
for (int attr_index = 0; attr_index < StageAttr::Num; attr_index++) {
const StageAttr& attr = prog.vs().inputs[attr_index];
if (attr.slot >= 0) {
if (Slang::is_glsl(slang)) {
l("result.attrs[{}].glslName = \"{}\"\n", attr_index, attr.name);
} else if (Slang::is_hlsl(slang)) {
l("result.attrs[{}].hlslSemName = \"{}\"\n", attr_index, attr.sem_name);
l("result.attrs[{}].hlslSemIndex = {}\n", attr_index, attr.sem_index);
}
}
}
for (int ub_index = 0; ub_index < Bindings::MaxUniformBlocks; ub_index++) {
const UniformBlock* ub = prog.bindings.find_uniform_block_by_sokol_slot(ub_index);
if (ub) {
const std::string ubn = fmt::format("result.uniformBlocks[{}]", ub_index);
l("{}.stage = {}\n", ubn, shader_stage(ub->stage));
l("{}.layout = uniformLayoutStd140\n", ubn);
l("{}.size = {}\n", ubn, roundup(ub->struct_info.size, 16));
if (Slang::is_hlsl(slang)) {
l("{}.hlslRegisterBN = {}\n", ubn, ub->hlsl_register_b_n);
} else if (Slang::is_msl(slang)) {
l("{}.mslBufferN = {}\n", ubn, ub->msl_buffer_n);
} else if (Slang::is_wgsl(slang)) {
l("{}.wgslGroup0BindingN = {}\n", ubn, ub->wgsl_group0_binding_n);
} else if (Slang::is_glsl(slang) && (ub->struct_info.struct_items.size() > 0)) {
if (ub->flattened) {
// NOT A BUG (to take the type from the first struct item, but the size from the toplevel ub)
l("{}.glslUniforms[0].type = {}\n", ubn, flattened_uniform_type(ub->struct_info.struct_items[0].type));
l("{}.glslUniforms[0].arrayCount = {}\n", ubn, roundup(ub->struct_info.size, 16) / 16);
l("{}.glslUniforms[0].glslName = \"{}\"\n", ubn, ub->name);
} else {
for (int u_index = 0; u_index < (int)ub->struct_info.struct_items.size(); u_index++) {
const Type& u = ub->struct_info.struct_items[u_index];
const std::string un = fmt::format("{}.uniforms[{}]", ubn, u_index);
l("{}.type = {}\n", un, uniform_type(u.type));
l("{}.offset = {}\n", un, u.offset);
l("{}.arrayCount = {}\n", un, u.array_count);
l("{}.glslName = \"{}.{}\"\n", un, ub->inst_name, u.name);
}
}
}
}
for (int sbuf_index = 0; sbuf_index < Bindings::MaxStorageBuffers; sbuf_index++) {
const StorageBuffer* sbuf = refl.bindings.find_storage_buffer_by_sokol_slot(sbuf_index);
if (sbuf) {
const std::string& sbn = fmt::format("{}.storageBuffers[{}]", dsn, sbuf_index);
l("{}.used = true\n", sbn);
l("{}.readonly = {}\n", sbn, sbuf->readonly);
}
for (int sbuf_index = 0; sbuf_index < Bindings::MaxStorageBuffers; sbuf_index++) {
const StorageBuffer* sbuf = prog.bindings.find_storage_buffer_by_sokol_slot(sbuf_index);
if (sbuf) {
const std::string& sbn = fmt::format("result.storageBuffers[{}]", sbuf_index);
l("{}.stage = {}\n", sbn, shader_stage(sbuf->stage));
l("{}.readonly = {}\n", sbn, sbuf->readonly);
if (Slang::is_hlsl(slang)) {
l("{}.hlslRegisterTN = {}\n", sbn, sbuf->hlsl_register_t_n);
} else if (Slang::is_msl(slang)) {
l("{}.mslBufferN = {}\n", sbn, sbuf->msl_buffer_n);
} else if (Slang::is_wgsl(slang)) {
l("{}.wgslGroup1BindingN = {}\n", sbn, sbuf->wgsl_group1_binding_n);
} else if (Slang::is_glsl(slang)) {
l("{}.glslBindingN = {}\n", sbn, sbuf->glsl_binding_n);
}
}
for (int img_index = 0; img_index < Bindings::MaxImages; img_index++) {
const Image* img = refl.bindings.find_image_by_sokol_slot(img_index);
if (img) {
const std::string in = fmt::format("{}.images[{}]", dsn, img_index);
l("{}.used = true\n", in);
l("{}.multisampled = {}\n", in, img->multisampled ? "true" : "false");
l("{}.imageType = {}\n", in, image_type(img->type));
l("{}.sampleType = {}\n", in, image_sample_type(img->sample_type));
}
for (int img_index = 0; img_index < Bindings::MaxImages; img_index++) {
const Image* img = prog.bindings.find_image_by_sokol_slot(img_index);
if (img) {
const std::string in = fmt::format("result.images[{}]", img_index);
l("{}.stage = {}\n", in, shader_stage(img->stage));
l("{}.multisampled = {}\n", in, img->multisampled ? "true" : "false");
l("{}.imageType = {}\n", in, image_type(img->type));
l("{}.sampleType = {}\n", in, image_sample_type(img->sample_type));
if (Slang::is_hlsl(slang)) {
l("{}.hlslRegisterTN = {}\n", in, img->hlsl_register_t_n);
} else if (Slang::is_msl(slang)) {
l("{}.mslTextureN = {}\n", in, img->msl_texture_n);
} else if (Slang::is_wgsl(slang)) {
l("{}.wgslGroup1BindingN = {}\n", in, img->wgsl_group1_binding_n);
}
}
for (int smp_index = 0; smp_index < Bindings::MaxSamplers; smp_index++) {
const Sampler* smp = refl.bindings.find_sampler_by_sokol_slot(smp_index);
if (smp) {
const std::string sn = fmt::format("{}.samplers[{}]", dsn, smp_index);
l("{}.used = true\n", sn);
l("{}.samplerType = {}\n", sn, sampler_type(smp->type));
}
for (int smp_index = 0; smp_index < Bindings::MaxSamplers; smp_index++) {
const Sampler* smp = prog.bindings.find_sampler_by_sokol_slot(smp_index);
if (smp) {
const std::string sn = fmt::format("result.samplers[{}]", smp_index);
l("{}.stage = {}\n", sn, shader_stage(smp->stage));
l("{}.samplerType = {}\n", sn, sampler_type(smp->type));
if (Slang::is_hlsl(slang)) {
l("{}.hlslRegisterSN = {}\n", sn, smp->hlsl_register_s_n);
} else if (Slang::is_msl(slang)) {
l("{}.mslSamplerN = {}\n", sn, smp->msl_sampler_n);
} else if (Slang::is_wgsl(slang)) {
l("{}.wgslGroup1BindingN = {}\n", sn, smp->wgsl_group1_binding_n);
}
}
for (int img_smp_index = 0; img_smp_index < Bindings::MaxImageSamplers; img_smp_index++) {
const ImageSampler* img_smp = refl.bindings.find_image_sampler_by_sokol_slot(img_smp_index);
if (img_smp) {
const std::string isn = fmt::format("{}.imageSamplerPairs[{}]", dsn, img_smp_index);
l("{}.used = true\n", isn);
l("{}.imageSlot = {}\n", isn, refl.bindings.find_image_by_name(img_smp->image_name)->sokol_slot);
l("{}.samplerSlot = {}\n", isn, refl.bindings.find_sampler_by_name(img_smp->sampler_name)->sokol_slot);
if (Slang::is_glsl(slang)) {
l("{}.glslName = \"{}\"\n", isn, img_smp->name);
}
}
for (int img_smp_index = 0; img_smp_index < Bindings::MaxImageSamplers; img_smp_index++) {
const ImageSampler* img_smp = prog.bindings.find_image_sampler_by_sokol_slot(img_smp_index);
if (img_smp) {
const std::string isn = fmt::format("result.imageSamplerPairs[{}]", img_smp_index);
l("{}.stage = {}\n", isn, shader_stage(img_smp->stage));
l("{}.imageSlot = {}\n", isn, prog.bindings.find_image_by_name(img_smp->image_name)->sokol_slot);
l("{}.samplerSlot = {}\n", isn, prog.bindings.find_sampler_by_name(img_smp->sampler_name)->sokol_slot);
if (Slang::is_glsl(slang)) {
l("{}.glslName = \"{}\"\n", isn, img_smp->name);
}
}
}
Expand Down Expand Up @@ -416,6 +447,14 @@ std::string SokolNimGenerator::get_shader_desc_help(const std::string& prog_name
return fmt::format("{}ShaderDesc(sg.queryBackend())\n", to_camel_case(prog_name));
}

std::string SokolNimGenerator::shader_stage(ShaderStage::Enum e) {
switch (e) {
case ShaderStage::Vertex: return "shaderStageVertex";
case ShaderStage::Fragment: return "shaderStageFragment";
default: return "INVALID";
}
}

std::string SokolNimGenerator::uniform_type(Type::Enum e) {
switch (e) {
case Type::Float: return "uniformTypeFloat";
Expand Down
1 change: 1 addition & 0 deletions src/shdc/generators/sokolnim.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class SokolNimGenerator: public Generator {
virtual std::string shader_bytecode_array_name(const std::string& snippet_name, Slang::Enum slang);
virtual std::string shader_source_array_name(const std::string& snippet_name, Slang::Enum slang);
virtual std::string get_shader_desc_help(const std::string& prog_name);
virtual std::string shader_stage(refl::ShaderStage::Enum e);
virtual std::string uniform_type(refl::Type::Enum e);
virtual std::string flattened_uniform_type(refl::Type::Enum e);
virtual std::string image_type(refl::ImageType::Enum e);
Expand Down

0 comments on commit 03ca680

Please sign in to comment.