-
Notifications
You must be signed in to change notification settings - Fork 778
[SPIRV] Implements vk::BufferPointer proposal #7163
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
Conversation
76c4743
to
0d60681
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
0d60681
to
78eb760
Compare
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 need to look more, early feedback
/// <summary>Adds a constructor declaration to the specified class | ||
/// record.</summary> <param name="context">ASTContext that owns | ||
/// declarations.</param> <param name="recordDecl">Record declaration in which | ||
/// to add constructor.</param> <param name="resultType">Result type for | ||
/// constructor.</param> <param name="paramTypes">Types for constructor | ||
/// parameters.</param> <param name="paramNames">Names for constructor | ||
/// parameters.</param> <param name="declarationName">Name for | ||
/// constructor.</param> <param name="isConst">Whether the constructor is a | ||
/// const function.</param> <returns>The method declaration for the | ||
/// constructor.</returns> |
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.
nit:
Is doxygen still generatable? (Couldn't make it work).
If no, might be more readable to have a normal comment.
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 know, but I did it that way for consistency with the rest of the file. Let me know if you still want it changed.
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 generally looks go. Thanks for getting this done. It is seems solidly implemented. I have a few concerns about the potential for future errors. With a few asserts we could address that.
I have not looked at the tests yet, nor have I tried running anything yet. I'll try to tomorrow.
75cd0be
to
2354f87
Compare
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 have a suggestion for a a few extra tests. Once they are in, I feel comfortable approving.
Can you also add a tests where an atomic operation is done? We want to be sure that works too.
Is the has_feature
uses anywhere? We should make sure that works.
tools/clang/test/CodeGenSPIRV/vk.buffer-pointer.linked-list.hlsl
Outdated
Show resolved
Hide resolved
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.
Thanks for the work!
Good improvements, but looks like there are still some failure cases:
Seems like I also reach an assert when this snippet:
// RUN: %dxc -E main -T cs_6_7 %s -spirv -E main | FileCheck %s
struct Content {
float a;
};
typedef vk::BufferPointer<Content> BufferContent;
typedef vk::BufferPointer<BufferContent> BufferBufferContent;
[[vk::push_constant]]
BufferContent buffer;
[numthreads(1, 1, 1)]
void main() {
float tmp = buffer.Get().a;
buffer.Get().a = tmp;
}
Also get an assert/validation errors with those 2 snippets: // RUN: %dxc -E main -T cs_6_7 %s -spirv -E main | FileCheck %s
struct Content {
uint a;
};
typedef vk::BufferPointer<uint> BufferContent;
[[vk::push_constant]]
BufferContent buffer;
[numthreads(1, 1, 1)]
void main() {
uint data = buffer.Get();
buffer.Get() = data;
}
Looks like removing optimizations or changing the snippet to this shows the validation error instead: // RUN: %dxc -E main -T cs_6_7 %s -spirv -E main | FileCheck %s
struct Content {
uint a;
};
typedef vk::BufferPointer<uint> BufferContent;
[[vk::push_constant]]
BufferContent buffer;
[numthreads(1, 1, 1)]
void main() {
buffer.Get() = 1;
} |
Found 2 other case: // RUN: %dxc -E main -T cs_6_7 %s -spirv -E main | FileCheck %s
struct Content {
int a;
};
typedef vk::BufferPointer<Content> BufferContent;
typedef vk::BufferPointer<BufferContent> BufferBuffer;
//[[vk::push_constant]]
//BufferContent buffer;
RWStructuredBuffer<BufferBuffer> rwbuf;
void foo(BufferContent bc) {
bc.Get().a = 1;
}
[numthreads(1, 1, 1)]
void main() {
foo(rwbuf[0].Get());
}
// RUN: %dxc -E main -T cs_6_7 %s -spirv -E main | FileCheck %s
struct Content {
int a;
};
typedef vk::BufferPointer<Content> BufferContent;
typedef vk::BufferPointer<BufferContent> BufferBuffer;
//[[vk::push_constant]]
//BufferContent buffer;
RWStructuredBuffer<BufferBuffer> rwbuf;
// Wrong type in the parameter.
void foo(BufferContent bc) {
bc.Get().a = 1;
}
[numthreads(1, 1, 1)]
void main() {
foo(rwbuf[0]);
}
|
Looks like casting would also need additional restrictions: // RUN: %dxc -E main -T cs_6_7 %s -spirv -E main | FileCheck %s
struct Content {
int a;
};
typedef vk::BufferPointer<Content> BufferContent;
typedef vk::BufferPointer<BufferContent> BufferBuffer;
RWStructuredBuffer<BufferContent> buf;
void foo(const BufferContent bc) {
bc.Get().a = 1;
}
[numthreads(1, 1, 1)]
void main() {
static BufferContent bcs = buf[0];
static BufferBuffer bbs = (BufferBuffer)bcs;
}
|
Should it actually be legal to have buffer pointer push constants? The front end rejects non-struct push constant declarations., and although values of type vk::BufferPointer are objects, they don't have data members and thus aren't treated as records. |
Mmmm, I don't think there is something that forbids it since we allow it for ConstantBuffers (at least we have one test checking this What frontend are you referring to? |
I believe the issue is that Vulkan requires that the type of a push constant must be a struct. That is enforced by the compiler: https://godbolt.org/z/8r38xss5o. Since the vk::BufferPointer is a pointer and not a struct, we should not allow it as a push constant unless it is contained in another struct. |
Ah that's right, |
I've ruled out buffer pointers as push constants, tightened up the typing/casting rules, and fixed the missing load alignment bug. |
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.
Hello! Thanks for the changes!
I'm fine moving forward with this PR so we can find more bugs with the first users, but I'd like for the fixed bugs to have test cases.
(I provided snippets/run lines, so making them into tests is mostly adding a 2>&1 | FileCheck
and CHECK: <expected-error>
)
I've pushed the requested tests. I've rebased on the most recent main and fixed the conflicts locally, but a recent (March 4) change to SPIRV-Tools causes non-termination on the linked list example. It appears that |
When a type was recursive (or for the matter any instruction ID usage), the DFSWhile implementation would loop indefinitely. Added a history map to keep track of the visited instructions. Required for microsoft/DirectXShaderCompiler#7163 Signed-off-by: Nathan Gauër <brioche@google.com>
When a type was recursive (or for the matter any instruction ID usage), the DFSWhile implementation would loop indefinitely. Added a history map to keep track of the visited instructions. Required for microsoft/DirectXShaderCompiler#7163 Signed-off-by: Nathan Gauër <brioche@google.com>
Ah right, thanks for finding, sent KhronosGroup/SPIRV-Tools#6070 to fix the issue. |
When a type was recursive (or for the matter any instruction ID usage), the DFSWhile implementation would loop indefinitely. Added a history map to keep track of the visited instructions. Required for microsoft/DirectXShaderCompiler#7163 Signed-off-by: Nathan Gauër <brioche@google.com>
Once #7269 is merged you'll be able to rebase 👍️ |
9581da6
to
0322faf
Compare
@@ -1232,6 +1237,9 @@ static const ArBasicKind g_AnyOutputRecordCT[] = { | |||
static const ArBasicKind g_DxHitObjectCT[] = {AR_OBJECT_HIT_OBJECT, | |||
AR_BASIC_UNKNOWN}; | |||
|
|||
static const ArBasicKind g_VKBufferPointerCT[] = {AR_OBJECT_VK_BUFFER_POINTER, |
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.
We're getting build breaks in Chromium where ENABLE_SPIRV_CODEGEN is not defined. I think this decl should be wrapped in #ifdef ENABLE_SPIRV_CODEGEN
?
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 working on a patch.
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 testing a fix now.
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.
Created pull request.
PR microsoft#7163 added support for vk::BufferPointer It did not build when building for non-SPIR-V scenarios. Bug: crbug.com/408215487
PR microsoft#7163 added support for vk::BufferPointer It did not build when building for non-SPIR-V scenarios. Bug: crbug.com/408215487
([SPIRV] Implements vk::BufferPointer proposal)
…fferPointer proposal) (#7306) #ifdef ENABLE_SPIRV_CODEGEN was omitted in several places.
Implements vk::BufferPointer proposal.
Closes #6489.