Skip to content

Add GL_EXT_spirv_intrinsics_string extension#333

Open
rdb wants to merge 1 commit into
KhronosGroup:mainfrom
rdb:spirv-intrinsics-string
Open

Add GL_EXT_spirv_intrinsics_string extension#333
rdb wants to merge 1 commit into
KhronosGroup:mainfrom
rdb:spirv-intrinsics-string

Conversation

@rdb

@rdb rdb commented Jun 28, 2026

Copy link
Copy Markdown

This is the second half of #331, adding the string part (see #332 for the variadic extension). They are separate extensions because they describe orthogonal features with minimal interaction. The glslang implementation will follow soon.

This extension builds on GL_EXT_spirv_intrinsics and adds a spirv_string pseudo-type that is only valid as a formal parameter type in a spirv_instruction-qualified function declaration. It furthermore provides the ability for literal string arguments to be passed to those parameters, as well as to variadic tails (when the variadic extension is enabled). It is lowered to an OpString whose result id is used as the operand.

The main conundrum I've had to work through was determining whether literal strings are treated as primary expressions (which matches what glslang implements, eg. allowing a parenthesized ("foo")), or can only be used as function call arguments (which matches what can actually be derived from the motivating GL_EXT_debug_printf extension, though it is a bit light on the actual grammar).

I have deliberately decided to stick with the most restrictive reading of what is actually specified, since doing otherwise would ask this extension to do much more work to more generally define strings as a type and expression. I deemed that to be out of scope for an extension that just aims to represent functions like debugPrintfEXT as a spirv_instruction. It may be worth revisiting this in a future extension that reusably and more generally defines string expressions in GLSL, or the referenced extensions should be revised to define the grammar in more detail and this one changed to match.

@Tobski Tobski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good too - just a couple review comments and would request some more eyes and a draft impl before accepting.

Comment on lines +136 to +142
If GL_EXT_spirv_intrinsics_variadic is enabled, a literal string
argument may also match an unqualified variadic tail of a function
declaration qualified with `spirv_instruction`. In that case, an
OpString is also generated and its result <id> is appended as the
corresponding operand. It is a compile-time error for a literal string
to match a variadic tail with a `spirv_by_reference` or `spirv_literal`
qualifier.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest that the tail has to be qualified with spirv_string to make this work - non-string arguments ignore it, but strings will be converted to OpString arguments.

The rationale for this is that otherwise you are making concrete, with no get out, how strings should be passed to intrinsics, and I'd like to leave the door open to passing them as byte arrays in future.

By requiring spirv_string here, it leaves the door open for strings-as-byte-arrays to be passed as arguments in future.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess spirv_string isn't a qualifier per say... so maybe not exactly that? But I do think there should be something to distinguish this behavior.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, that's a good point... spirv_string isn't a qualifier as you say (and it would probably create parser ambiguity to introduce it as one here), but some way to say "if there is a string, encode it as OpString" sounds like it would be necessary... I will think about this.

Comment on lines +198 to +204
void debugPrintfEXT(spirv_string format, ...);

void main()
{
float x = 1.0;
debugPrintfEXT("x = %f\n", x);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be illustrative to have an example with a string passed in the variadic tail.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I could modify the example to add an "%s" argument to printf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants