-
Notifications
You must be signed in to change notification settings - Fork 245
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
Initial implementation of SP#015 DescriptorHandle<T>
.
#6028
Conversation
/format |
🌈 Formatted, please merge the changes from this PR |
ResourcePtr<T>
.DescriptorHandle<T>
.
DescriptorHandle<T>
.DescriptorHandle<T>
.
Just looked over the proposal. LGTM 👍🏻 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
I left some questions, but I probably have some misunderstandings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
where T : IOpaqueDescriptor | ||
{ | ||
[require(hlsl_glsl_spirv)] | ||
__init(uint2 value); // For HLSL, GLSL and SPIRV targets only. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing this constructor also requires a certain shader model version of SPIR-V capability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another note is that I'd expect that operation to be de facto available for CPU and CUDA targets as well, since the representation of a handle on those platforms is "just bits" and should fit in 64 bits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to have a convenience constructor that takes a UInt64
on targets that support such a type. That could be directly implemented on targets that can support it that way, and can decompose the 64-bit integer into a uint2
on the others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On CPU and CUDA, a StructuredBuffer
is actually 16 bytes, storing both a pointer and a size to support the GetDimension
operation, so we can't actually support this constructor on CPU/CUDA for all resource types, unfortunately.
} | ||
``` | ||
|
||
All builtin types that implements `IOpaqueDescriptor` interface provide a convenience typealias for `DescriptorHandle<T>`. For example, `Texture2D.Handle` is an alias for `DescriptorHandle<Texture2D>`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a comment on this proposal, but I wonder if that behavior could be provided automatically via an extension
on types that conform to IOpaqueDescriptor
along the lines of:
extension<T : IOpaqueDescriptor> T
{
typealias Handle = DescriptorHandle<T>;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is originally implemented this way but I hit a bug in the type system. I need to fix the type system first before this is possible.
|
||
- `operator *` to deference the pointer and obatin the actual descriptor handle `T`. | ||
- Implicit conversion to `T` when used in a location that expects `T`. | ||
- When targeting HLSL, GLSL and SPIRV, `DescriptorHandle<T>` can be casted to and from a `uint2` value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be explicit that this only supports explicit casts, and not implicit type conversions?
In my own usage, I try to distinguish (explicit) casting from (implicit) conversion of types, but the distinction might be too subtle to rely on somebody reading this document to know off-hand (and there are also people who apply those terms differently).
- `operator *` to deference the pointer and obatin the actual descriptor handle `T`. | ||
- Implicit conversion to `T` when used in a location that expects `T`. | ||
- When targeting HLSL, GLSL and SPIRV, `DescriptorHandle<T>` can be casted to and from a `uint2` value. | ||
- Equality comparison. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this implicitly means equality and inequality.
If we end up adding some kind of IHashable
interface to the core library, then we'd also want descriptor handles to be hashable.
// Alternatively, the following syntax is also allowed, to | ||
// make `DescriptorHandle` appear more like a pointer: | ||
t->Sample(*sampler, float2(0, 0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to this proposal, but I find it distasteful that we are adding more and more C++-isms to our language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack, but not something we can do here since this was already added to the language along with the pointer support.
If the descriptor handle value is not uniform and `nonuniform` is not called, the result may be | ||
undefined. | ||
|
||
### Combind Texture Samplers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "Combind" -> "Combined"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't expect the following to change in this document, but in order to raise a discussion point:
The term "combined texture sampler" is one I find unfortunate, because a "texture sampler" superficially sounds like a thing that samples textures, rather than a pair of two things: a texture and a sampler. Adding the adjective "combined" doesn't do a whole lot to dissuade somebody from that interpretation.
When possible, I tend to refer to such things as "combined texture-sampler pairs." A "texture-sampler pair" clearly communicates that it is (semantically) a pair, and what it is a pair of: a texture and a sampler. In this context the "combined" prefix makes it clear that while the thing is semantically a pair, something might be done as part of combining them, so that the resulting combination could be different from what would result from forming such a pair type in user code.
|
||
### Combind Texture Samplers | ||
|
||
On platforms without native support for combined texture samplers, we will use both components of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah... this part of things makes subtle use of the fact that the (current) D3D case only needs 32 bits to represent a handle, so that a uint2
is actually sufficient for storing two handles (a texture handle and a sampler handle).
This choice would break down the line if handles on D3D eventually become 64-bit values. All of the descriptor types except combined texture-sampler pairs would be able to adapt (using all the bits of the uint2
), but combined texture-sampler pairs would require changes to the DescriptorHandle<>
type given here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true, and in that case we will need to change the size of DescriptorHandle<Sampler2D>
on D3D. Note that with this revised proposal, DescriptorHandle size is target dependent and we are allowed to make it having different size based on the underlying descriptor type.
// At this stage, we can safely remove the generic `getDescriptorFromHandle` function | ||
// despite it being marked `export`. | ||
for (auto inst : module->getGlobalInsts()) | ||
{ | ||
if (auto genFunc = as<IRGeneric>(inst)) | ||
{ | ||
if (!genFunc->hasUses()) | ||
{ | ||
toRemove.add(genFunc); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a risk that this logic could remove IR generics that it shouldn't, in some future scenario?
I suppose that we don't anticipate any of our targets supporting actual generics in binary code (only specialized or dynamic-dispatch-ified versions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree there is risk, and we would have to deal with this issue in the future.
0666eb5
…#6028) * Initial implementation of `ResourcePtr<T>`. * Update docs * Fix build error. * Add more discussion. * Update documentation. * Update TOC. * Fix. * Fix. * Add test case for custom `getResourceFromBindlessHandle`. * Add namehint to generated descriptor heap param. * Fix. * Fix. * format code * Rename to `DescriptorHandle`, and add `T.Handle` alias. * Fix compiler error. * Fix. * Fix build. * Renames. * Fix documentation. * Documentation fix. --------- Co-authored-by: slangbot <[email protected]>
Closes #6038.
Closes #6010.