Skip to content

[mlir][dxsa] Add dcl_function_body and dcl_function_table#134

Open
asavonic wants to merge 4 commits into
dxsa-mlirfrom
dxsa-mlir-functions
Open

[mlir][dxsa] Add dcl_function_body and dcl_function_table#134
asavonic wants to merge 4 commits into
dxsa-mlirfrom
dxsa-mlir-functions

Conversation

@asavonic
Copy link
Copy Markdown
Contributor

DX assembly programs support "virtual" inlining of subroutines by defining a set of functions that might be called for a call site.
The compiler then prepares an inlined specialization for every possible callee. The actual specialization is selected at runtime.

On DXBC level, functions are declared and identified by numbers, grouped into tables, and tables are grouped as interfaces:

// Function table for AmbientLight.
dcl_function_body fb0
dcl_function_table ft0 = { fb0 }

// Function table for DirectionalLight.
dcl_function_body fb1
dcl_function_table ft1 = { fb1 }

// main's MyMaterial parameter.
dcl_interface fp0[1][1] = { ft0, ft1 };

// main shader code

// call AmbientLight or DirectionalLight based on function pointer bound
fcall fp0[0][0]

This patchset adds only dcl_function_body and dcl_function_table. Interfaces are going to be in a separate patch.

@asavonic asavonic requested a review from tagolog May 22, 2026 15:31
Comment thread mlir/test/Target/DXSA/inputs/dcl_function_body.bin
Comment thread mlir/lib/Target/DXSA/BinaryParser.cpp Outdated
Comment thread mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td Outdated
let description = [{

The `dxsa.dcl_function_body` declares a unique function body #
whose code will appear later in the program at `label fb#`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe remove references to "fb#" syntax as we are not using it in the mlir for now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment thread mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td Outdated
Comment thread mlir/lib/Target/DXSA/BinaryParser.cpp Outdated
Comment thread mlir/lib/Target/DXSA/BinaryParser.cpp Outdated

// CHECK-LABEL: module

// dcl_function_body fb1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe it is worth no to mix the ops from prev asm with the current MLIR ops? This can be a bit misleading.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree. Removed.

@asavonic asavonic force-pushed the dxsa-mlir-functions branch from 543afcc to cfe95be Compare May 28, 2026 15:06
@asavonic
Copy link
Copy Markdown
Contributor Author

Also changed syntax a bit to spell out what the array means:

dxsa.dcl_function_table 0, <functions = [0, 1]>

@asavonic asavonic force-pushed the dxsa-mlir-functions branch from cfe95be to d03dc8a Compare May 29, 2026 00:57
let arguments = (ins F32Attr:$max_tessfactor);
let assemblyFormat = "$max_tessfactor attr-dict";
let hasVerifier = 1;
let arguments = (ins I32Attr:$index);
Copy link
Copy Markdown

@tagolog tagolog May 29, 2026

Choose a reason for hiding this comment

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

This argument is positive by design, I vote to restrict it.

Suggested change
let arguments = (ins I32Attr:$index);
let arguments = (ins ConfinedAttr<I32Attr, [IntNonNegative]>:$index);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you. Added restriction.

let assemblyFormat =
"$operand `,` $struct_byte_stride `,` $struct_count attr-dict";
let hasVerifier = 1;
let arguments = (ins I32Attr:$index, DenseI32ArrayAttr:$functions);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
let arguments = (ins I32Attr:$index, DenseI32ArrayAttr:$functions);
let arguments = (ins ConfinedAttr<I32Attr, [IntNonNegative]>:$index, DenseI32ArrayAttr:$functions);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

return builder.buildDclHsJoinPhaseInstanceCount(*count, loc);
}
FailureOr<Instruction> parseDclFunctionTable(Location loc) {
auto index = parseToken();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Extended length bit [31] for dcl_function_table is unhandled

The spec says the regular 7-bit length field can overflow, in which case bit [31] is set and the real length lives in the next DWORD:

d3d12TokenizedProgramFormat.hpp#L2486-L2490

// [30:24] Instruction length in DWORDs including the opcode token.
// [31]    0 normally. 1 if extended operand definition, meaning next DWORD
//         contains extended operand description.  If it is extended, then
//         it contains the actual instruction length in DWORDs, since
//         it may not fit into 7 bits if enough functions are defined.

DirectXShaderCompiler handles this explicitly ShaderBinary.cpp#L548-L558

Right now the parser ignores extended length bit for these opcodes and silently parses the next DWORD as function table identifier.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Added handling of extended length token.

@asavonic asavonic force-pushed the dxsa-mlir-functions branch from f563c68 to ea9b7f1 Compare May 29, 2026 14:21
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