Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

link-time constants in reflection API #5709

Closed
PierreEVEN opened this issue Nov 29, 2024 · 3 comments
Closed

link-time constants in reflection API #5709

PierreEVEN opened this issue Nov 29, 2024 · 3 comments
Labels
SPF:Proposal Slang Proposed Feature: Proposal - A Slang feature which has been proposed, but not yet implemented

Comments

@PierreEVEN
Copy link

Hi,

As discussed in #5664 (comment), I think it would be nice to be able to get a list of available link-time constants 'parameters', for example to generate shader permutations.

I'm working on a toy game engine, and I was searching for a convenient way to automatically handle shaders permutations.
Looking at the slang syntax, I thought that using link-time constants would be a good idea as it doesn't requires to compile the modules again like the examples provided in the user guide. I would only need to inject a module that set the value for each constant parameter.

Short example :

Slang code : PlayGround Link

Cpp-side :

// STEP ONE : use the reflection API to get a list of link-time constant parameters => we store this in a map named "static_switches"

// Example of how I would use the reflection API to populate the static_switches map. This doesn't exists in the current version of slang.
std::unordered_map<std::string, bool> static_switches;
for (const auto& param : module->getLayout()->getLinkTimeConstants())
    static_switches->emplace(param->get_name(), param->get_default_value());


// STEP TWO : each time we need a different combination of static_switches values, we inject the desired values as follows :

// This currently works as expected, no change are required here.
std::vector<slang::IComponentType*> components;
if (!static_switches.keys().empty())
{
    std::string generated_module;
    for (const auto& sw: static_switches)
        generated_module += std::format("export static const bool {} = {};", sw.first, sw.second ? "true" : "false");

    auto permutation_values_src = UnownedRawBlob::create(generated_module.c_str(), generated_module.size());
    components.emplace_back(session->loadModuleFromSource("permutation-values", "permutation-values.slang", permutation_values_src));
}
components.emplace_back(entry_point);
Slang::ComPtr<slang::IComponentType> program;
session->createCompositeComponentType(components.data(), components.size(), program.writeRef());

// then link + getEntryPointCode

Currently there is no way to get a list of link-time constants, so I have to manually parse the shader file to retrieve them, which is not a very clean approach.
Also optionally, it would be nice if we can get the default value (which is probable harder to implement)

@PierreEVEN PierreEVEN changed the title [] Have link-time constants in reflection API link-time constants in reflection API Nov 29, 2024
@bmillsNV bmillsNV added the SPF:Proposal Slang Proposed Feature: Proposal - A Slang feature which has been proposed, but not yet implemented label Dec 5, 2024
@bmillsNV bmillsNV added this to the Q1 2025 (Winter) milestone Dec 5, 2024
@bmillsNV
Copy link
Collaborator

bmillsNV commented Dec 5, 2024

Feature request. We'll evaluate this next quarter when figuring out our priorities. In the meantime, we welcome contributions if anyone wants to take this one up.

@jjiangweilan
Copy link

I found a way to get the name of link-time constants

    auto moduleReflection = module->getModuleReflection();
    for (auto child : moduleReflection->getChildren())
    {
        auto type = child->getKind();
        if (type == slang::DeclReflection::Kind::Variable)
        {
            auto asVariable = child->asVariable();
            bool hasExtern = asVariable->findModifier(slang::Modifier::Extern) != nullptr;
            bool hasStatic = asVariable->findModifier(slang::Modifier::Static) != nullptr;
            bool hasConst = asVariable->findModifier(slang::Modifier::Const) != nullptr;

            // bool hasDefault = asVariable->hasDefaultValue(); // you can know if it has default value, but I haven't find a way to know the exact value assigned

            if (hasExtern && hasStatic && hasConst)
            {
                std::string name = child->getName(); // name of the link-time constants
            }
        }
    }

@PierreEVEN
Copy link
Author

I found a way to get the name of link-time constants

    auto moduleReflection = module->getModuleReflection();
    for (auto child : moduleReflection->getChildren())
    {
        auto type = child->getKind();
        if (type == slang::DeclReflection::Kind::Variable)
        {
            auto asVariable = child->asVariable();
            bool hasExtern = asVariable->findModifier(slang::Modifier::Extern) != nullptr;
            bool hasStatic = asVariable->findModifier(slang::Modifier::Static) != nullptr;
            bool hasConst = asVariable->findModifier(slang::Modifier::Const) != nullptr;

            // bool hasDefault = asVariable->hasDefaultValue(); // you can know if it has default value, but I haven't find a way to know the exact value assigned

            if (hasExtern && hasStatic && hasConst)
            {
                std::string name = child->getName(); // name of the link-time constants
            }
        }
    }

Works as expected

Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SPF:Proposal Slang Proposed Feature: Proposal - A Slang feature which has been proposed, but not yet implemented
Projects
None yet
Development

No branches or pull requests

3 participants