Skip to content

[HLSL] Add descriptor table metadata parsing #142492

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

Open
wants to merge 66 commits into
base: main
Choose a base branch
from

Conversation

joaosaffran
Copy link
Contributor

  • adds parsing from metadata into dxcontainer binary
  • adds validations as described in the spec
  • adds testing scenarios
    Closes: #126640

return Flags == FlagT::DESCRIPTORS_VOLATILE;
}

// The data-specific flags are mutually exclusive.
Copy link
Contributor

Choose a reason for hiding this comment

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

the descriptor flags are also mutually exclusive. Do we want an explicit check for this? It seems like it is covered below. Maybe it is good for clarity?

DESCRIPTOR_RANGE(1, UAV)
DESCRIPTOR_RANGE(2, CBV)
DESCRIPTOR_RANGE(3, Sampler)
DESCRIPTOR_RANGE(4, NONE)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we have a value for NONE here? A value of 4 in the metadata would certainly be invalid, and this appears to be unused.

Copy link
Contributor Author

@joaosaffran joaosaffran Jun 18, 2025

Choose a reason for hiding this comment

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

This came as a request from another PR, where Finn mentioned those values are useful in the frontend, since we are planning on sharing this, I've added those back.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you have a link to that conversation handy? I'd like to see how NONE would be used here...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is an example use case of NONE in the frontend:

std::optional<RootFlags> Flags = RootFlags::None;
.

But that discussion was in the context of flags, I will remove this one from here, since it doesn't seem to match the pattern of other NONE values

Comment on lines 200 to 202
.Default(-1u);

if (Range.RangeType == -1u)
Copy link
Contributor

Choose a reason for hiding this comment

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

Clearer to use ~0U rather than -1U, and this way avoids some warnings from MSVC in any case.

@@ -174,6 +174,94 @@ static bool parseRootDescriptors(LLVMContext *Ctx,
return false;
}

static bool parseDescriptorRange(LLVMContext *Ctx,
mcdxbc::RootSignatureDesc &RSD,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is RSD passed in here?

Comment on lines 355 to 359
if (Version == 1) {
if (IsSampler)
return Flags == FlagT::NONE;
return Flags == FlagT::DESCRIPTORS_VOLATILE;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

These values are still incorrect. As I mentioned in #142492 (comment) samplers can only have DESCRIPTORS_VOLATILE, and otherwise this needs to be DATA_VOLATILE.

Also, please add a test for this - we should be catching that this is obviously wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is some confusion in the spec, there are 2 sections saying different values are valid for this field. Reached in private to discuss this.

I'll add the test.

Comment on lines +398 to +399
// When no descriptor flag is set, any data flag is allowed.
return (Flags & ~DataFlags) == FlagT::NONE;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not correct. Samplers can never have the DATA_* flags set.

Comment on lines 612 to 621
OS << indent(2) << "- Range Type: " << Range.RangeType << "\n";
OS << indent(4) << "Register Space: " << Range.RegisterSpace << "\n";
OS << indent(4)
<< "Base Shader Register: " << Range.BaseShaderRegister << "\n";
OS << indent(4) << "Num Descriptors: " << Range.NumDescriptors
<< "\n";
OS << indent(4) << "Offset In Descriptors From Table Start: "
<< Range.OffsetInDescriptorsFromTableStart << "\n";
if (RS.Version > 1)
OS << indent(4) << "Flags: " << Range.Flags << "\n";
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it's just me, but I find using the indent() function with a small constant to be quite a bit less clear than just putting the spaces in the strings. Consider:

          OS << "  - Range Type: " << Range.RangeType << "\n"
             << "    Register Space: " << Range.RegisterSpace << "\n"
             << "    Base Shader Register: " << Range.BaseShaderRegister << "\n"
             << "    Num Descriptors: " << Range.NumDescriptors << "\n"
             << "    Offset In Descriptors From Table Start: "
             << Range.OffsetInDescriptorsFromTableStart << "\n";
          if (RS.Version > 1)
            OS << "    Flags: " << Range.Flags << "\n";

Here, you can see how the strings line up just by looking at them. Though admittedly it can get a bit messier with longer lines. IMO indent() is mostly useful when the indentation varies depending on context, or is large enough that just writing it out makes things less readable.

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

Successfully merging this pull request may close these issues.

5 participants