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

Add boolN types #4

Open
redorav opened this issue Apr 2, 2018 · 8 comments
Open

Add boolN types #4

redorav opened this issue Apr 2, 2018 · 8 comments
Assignees
Labels

Comments

@redorav
Copy link
Owner

redorav commented Apr 2, 2018

No description provided.

@redorav redorav added the feature label Apr 2, 2018
@redorav redorav self-assigned this Apr 2, 2018
@natevm
Copy link

natevm commented Sep 1, 2024

@redorav Is this feature still planned? I find myself frequently using HLSL's any, all, select, or and and intrinsics with vector bool components. It would be really helpful for adoption on my end if these were added (if not already)

@redorav
Copy link
Owner Author

redorav commented Sep 2, 2024

Hi @natevm let me respond in parts

  1. any and all already return a single bool, and in hlsl always return a bool you can put into a conditional so that's something that already has the correct functionality and you can use

  2. select already exists. It returns a float4 that can be used with any or all

  3. or and and are not possible to implement in C++ because of old and silly operator rules that I haven't been able to work around. In short, one cannot create a function called and or or. This gets really annoying considering that the latest HLSL standard deprecates && and || in favor of and and or. I don't really know how to get around this other than perhaps create another set of functions called or_vec or and_vec but I haven't made up my mind and you can still use the traditional operators to get what you need

The only reason boolN might be desirable is that it avoids an intermediate check for 0 so it would be slightly faster. However, the cost to pay is quite big in terms of implementation and I never really got to it and no one found it useful anyway.

Hopefully that answers your question, if you have more questions let me know

@natevm
Copy link

natevm commented Sep 2, 2024

Really, I’m aiming for a framework where I can share slang code with the host. I agree that the direction HLSL went with this is frustrating…

In slang, both && and || are legal, so I don’t actually use and or or. However, slang throws a warning whenever integers are implicitly cast to Booleans, which happens with select where the first operator is a Boolean of a given component t width. So a lot of code there ends up having vectorized Boolean types.

Would it be less work to implement some sort of typedef to have BoolN’s map to uintN’s?

@redorav
Copy link
Owner Author

redorav commented Sep 2, 2024

What does your code look like so I can get an idea of what you're looking to make work?

A boolN is not like a uintN as far as I can tell, a boolN as far as I know only takes 2 values, 0 and 0xffffffff, and those are used as masks.

HLSL++ treats floatN and uintN and "bools" when they return from a function like == or != in the sense that they get preemptively masked so they can be passed to other functions that require masks.

In HLSL these implicit conversions have never been warnings so I'm not sure why Slang would be more pedantic about these. I have a feeling you'll have an easier time convincing Slang to be less strict about it.

In any case let's see the code and discuss it

@natevm
Copy link

natevm commented Sep 2, 2024

I’m working on some BVH traversal code where a BVH node has 8 children. I loop over two sets of four, and have several vectorized tests producing flags per child node processed per-component. I have a bool4 isHit which comes from a four-wide box intersection test, and a bool4 isNode, bool4 isEmpty, and bool4 isLeaf as well, which are logically combined together in a SIMD-style way to reduce thread diverge and instruction counts.

Slang targets more than just DXIR. I’m less familiar there, but with SPIR-V, there is no assumption about true values being 0xffffffff.
image

In any case, incompatibilities like this are a really unfortunate deal breaker.

@natevm
Copy link

natevm commented Sep 2, 2024

HLSL++ treats floatN and uintN and "bools" when they return from a function like == or != in the sense that they get preemptively masked so they can be passed to other functions that require masks.

floatN and uintN are not Boolean’s, but the binary comparison operators == and != return component-wise boolean vectors in both HLSL and in Slang. You’d then use an any or all to reduce the vector down to a single Boolean value.

Iiuc, the motivation behind these intrinsics, beyond performance, are to give HLSL more well defined behavior for shortcircuiting.

@natevm
Copy link

natevm commented Sep 2, 2024

In HLSL these implicit conversions have never been warnings so I'm not sure why Slang would be more pedantic about these. I have a feeling you'll have an easier time convincing Slang to be less strict about it.

One of the motivating reasons for why folks use slang at the moment is the more strict type behavior. How strict the type safeness is becomes more of a subjective debate, and there is a compiler flag to disable the warnings, but personally I find that they help me avoid bugs. I’m not really willing to disable those warnings to adopt a library like this.

@redorav
Copy link
Owner Author

redorav commented Sep 3, 2024

I understand that you don't want to disable the warnings in Slang, and that's fine. However, consider that this is a library that takes HLSL as the model and not GLSL for example. There are compromises and things it cannot or are inconvenient to do. There are also concessions where it is simple to do so. Ultimately, the library may not work for you or you may want to fork it.

I have been thinking about how to best implement boolN types. First off there are some requirements. Certain implicit conversions happen all the time. This works float4 mask = (a != b); and swizzles such as float4 mask = (a != b).xxyy also work, both in HLSL and currently in hlsl++

Simply adding a boolN type means that I now lose the swizzle functionality or I need to implement a full-on type to interact with the existing ones. I hesitate to add those because of compile times, but I also don't know how these interact with e.g. double types. Those would also need to interact with bools but now conversions with doubles become more difficult instead of staying in double land.

In turn something like select() becomes more complicated because it needs to turn a boolN into a size that is compatible with the size of double. double4 result = select(boolVector, result1, result2) means that I need to turn boolVector into a mask somehow whereas the current implementation already works.

None of these are huge problems, but I don't plan on doing this in the near term and I'd have to think it through properly. If you have a proposal and would like to suggest something I'm all ears

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

2 participants