【发布时间】:2020-07-23 12:46:15
【问题描述】:
我在检查标志时遇到问题。由于某种原因,它总是返回 True。 (同样的功能在 CPU 上也能正常工作。)
bool HasFlag(uint data, uint flag) { return (data & flag) == flag; }
检查:
if (HasFlag(tag, Invisible | Deleted))
在没有函数的情况下编写检查时,一切都被认为是正确的:
if (tag & (Invisible | Deleted) == (Invisble | Deleted))
完整代码:
const uint Invisible = 1 << 0;
const uint Deleted = 1 << 1;
const uint Selected = 1 << 2;
struct Tag
{
uint tag;
};
RWStructuredBuffer<uint> IndexBuffer;
StructuredBuffer<float3> PositionBuffer;
StructuredBuffer<float> ScaleBuffer;
RWStructuredBuffer<Tag> TagsBuffer;
AppendStructuredBuffer<uint> SelectedItems;
AppendStructuredBuffer<uint> SelectedIndex;
int Length;
float3 RayOrigin;
float3 RayDirection;
float ScaleFactor;
uint SetFlag(uint data, uint flag) { return data | flag; }
uint UnsetFlag(uint data, uint flag) { return data & (~flag); }
uint FlipFlag(uint data, uint flag) { return data ^ flag; }
bool HasFlag(uint data, uint flag) { return (data & flag) == flag; } //<-- problem func
#pragma kernel PointSelect
[numthreads(64, 1, 1)]
void PointSelect(uint3 id : SV_DispatchThreadID)
{
if (id.x < Length)
{
uint tag = TagsBuffer[id.x].tag;
if (HasFlag(tag, Invisible | Deleted)) //<--- always passes (tag == 0)
{
float3 pos = PositionBuffer[id.x];
float3 spos = pos - RayOrigin;
float scale = ScaleBuffer[id.x] * 0.2f * ScaleFactor;
float dist = sqrt(spos.x*spos.x + spos.y*spos.y + spos.z*spos.z);
float3 rayPos = RayOrigin + dist*RayDirection;
float3 srPos = rayPos - pos;
if (srPos.x*srPos.x + srPos.y*srPos.y + srPos.z*srPos.z <= scale * scale)
{
TagsBuffer[id.x].tag = tag | Selected;
SelectedItems.Append(IndexBuffer[id.x]);
SelectedIndex.Append(id.x);
}
}
}
}
提前谢谢你。 附言谷歌翻译
编辑 1:我注意到在我的示例中,括号的排列方式不同,并决定检查运算符的优先级 (https://en.cppreference.com/w/c/language/operator_precedence)。因此,== 优先于 &。结果,“正确执行的变体”看起来像:date & (flag == flag)。为什么它有效 - 我无法想象。我会去想办法的。
编辑 2:这些函数在 CPU 上正常工作,但在 GPU 上总是由于某种未知原因返回 true:
inline bool AllFlags(uint data, uint flags) { return (data & flags) == flags; }
inline bool AnyFlags(uint data, uint flags) { return (data & flags) > 0; }
inline bool NoneFlags(uint data, uint flags) { return (data & flags) == 0; }
编辑 3:当我在调用函数时使用数字而不是常量时,一切正常。错误在于常量的定义。
【问题讨论】: