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

Shader:getVariables #839

Open
bjornbytes opened this issue Feb 6, 2025 · 1 comment
Open

Shader:getVariables #839

bjornbytes opened this issue Feb 6, 2025 · 1 comment
Labels

Comments

@bjornbytes
Copy link
Owner

Requested in chat. Use case is reflecting shader variables for an inspector/debug UI.

Thought about exposing separate getBuffers, getTextures, getSamplers, etc. methods, but this seems too messy, and you have to name them like getBufferNames to make it clear they don't return resources, just the resource names. It's more clean to just have getVariables and let the user filter them, or maybe accept some filter params eventually.

LÖVE has a corresponding feature request with some discussion: love2d/love#2137

Current API idea is Shader:getVariables to match the existing Shader:hasVariable. Other names would be possible. getUniforms doesn't make sense because this will also expose "resources" like buffers/textures. getInputs could be good, but I feel it is slightly less clear than "variable".

The return value would be a table where the key is a variable name and the value is the type of variable. One big question is whether it returns the type of a uniform, like this:

{
  radius = 'float',
  direction = 'vec3',
  transforms = 'buffer'
}

This seems good, but we support structs/arrays too. Should we return complicated format tables like this?

{
  lights = {
    name = 'lights',
    stride = 32,
    length = 8,
    offset = 0,
    type = {
      { name = 'pos', type = 'f32x3', offset = 0 },
      { name = 'type', type = 'u32', offset = 12 },
      { name = 'color', type = 'f32x4', offset = 16 }
    }
  },
  sky = 'texture',
  transforms = 'buffer'
}

This doesn't feel right, it feels like the method is returning too much information. I lean towards just returning the basic "variable type" and leaving further metadata to other methods. So the keys are variable names and the values are a new VariableType enum, like this:

{
  lights = 'uniform',
  sky = 'texture',
  transforms = 'buffer'
}

We could expand Shader:getBufferFormat to support uniforms too, so that you can get the full format. This makes the name confusing though since now it works with both uniforms and buffers. It could be renamed to Shader:getDataFormat, Shader:getVariableFormat, etc., or we could just leave it as-is without too much trouble.

@bjornbytes bjornbytes added the feature yay label Feb 6, 2025
@bjornbytes
Copy link
Owner Author

Tried implementing this. The main challenge is that we don't actually know variable names for anything in the C code, we just know their hashes. So we'll have to do the thing where we measure how many bytes we need for all the uniform/resource names, allocate extra space in the names array, save a name pointer for everything, and copy them out of the spirv.

Since we only need these names for :getVariables, it might actually make more sense to just store separate resourceNames and uniformNames arrays? We don't want/need to add the name to ShaderResource or DataField.

@bjornbytes bjornbytes added the v0.19.0 omg label Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant