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

gpuav: Do GPU-AV Post Processing with uint32_t only #9390

Conversation

spencer-lunarg
Copy link
Contributor

@arno-lunarg found #9381 was not good enough and we need to not use spirv::Instruction at all and resort to doing old-fashion vector<uint32_t> parsing

Added some helpers and I think it is tolerable (as parsing SPIR-V can be)

@spencer-lunarg spencer-lunarg requested a review from a team as a code owner February 4, 2025 21:29
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 364659.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from 1aab813 to 168f29b Compare February 4, 2025 21:30
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 364675.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18992 running.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18992 failed.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from 168f29b to b82ce46 Compare February 5, 2025 02:12
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 364950.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18994 running.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from b82ce46 to 1aff6e2 Compare February 5, 2025 02:27
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 364968.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18995 running.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18995 passed.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from 1aff6e2 to 86e7a43 Compare February 5, 2025 04:47
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 365055.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18996 running.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 18996 passed.

const auto &insn = instructions[i];
if ((insn.Opcode() != spv::OpSource) || (insn.Length() < 5) || (insn.Word(3) != reported_file_id)) {
uint32_t offset = kModuleStartingOffset;
while (offset < instructions.size()) {
Copy link
Contributor

@arno-lunarg arno-lunarg Feb 5, 2025

Choose a reason for hiding this comment

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

We can do better than this while loop, this old style is error prone: you have to think about updating length, updating offset every time you have a continue or at loop end, you have to update the correct length/offset, etc ...
Use a full fledged Instruction iterator class, that would benefit for this very cool Instruction class, and come up with something that does this for instance:

for (const Instruction& instruction : InstructionsSpan(instructions.data(), instructions.size()))

More work, but easier to use, way less error prone, and a good reason for you to explore C++ iterators further!

Or if you want to go fast with something not as elegant, at least go for that instead of the while loops:

    for ( size_t offset = kModuleStartingOffset, length = Length(instruction[offset]); offset < instructions.size(); (offset += length, length = Length(instruction[offset])) ) 

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. I moved all the SPIR-V uint32_t parsing inside spirv_logging.cpp
  2. I cleaned up the aweful nested while loops

Then I tried to do this iterator suggestions above (both the C++ and C style), I found adding it made things harder to read and while doing it, I had bug and it was not even obvious what was going on, so I reverted that part of the change

Every while (offset < instruction.size()) loop is 15 to 20 lines, with mainly a single offset += length and feel it's simplicity (and consistency) is good enough here

You might disagree, but I am satisfied with how the change is now and have no plan to update things, not "just" because this PR gets the job done, but because anyone who edits this can easily understand what is going on, it is the only file that does this, no one is going to honestly editing these isolated small functions (they been untouched forever since i added them). If this logic was actually doing more complex things (like the other parts of our SPIR-V code using the Instruction class, I would probably reconsider, but they literally just need to loop and pick out a single instruction, spirv-tool, spirv-reflect, spirv-cross, etc do the exact same thing here... its just the nature of parsing a IR

Copy link
Contributor

Choose a reason for hiding this comment

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

Then at least move to the for loop I described. It is just safer, and moves the iteration logic where it should be

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried, it gets nasty for the double loops with SourceContinued as I need to still go

offset += length; // get next instructions
break;

it is still the same problem, we just moved it to a more inconvenient location

Copy link
Contributor

Choose a reason for hiding this comment

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

Mmmmh you mean you can't go:

// first loop
    for ( size_t offset = kModuleStartingOffset, length = Length(instruction[offset]); offset < instructions.size(); (offset += length, length = Length(instruction[offset])) ) 

// second loop
    for ( ; offset < instructions.size(); (offset += length, length = Length(instruction[offset])) ) 

Looking at the code, I bet you 5$ you can

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel this is harder to grasp, trying to shove all this stuff in the for loop header, but honestly sure, will just do it at this point because I need this PR in to move forward to add more Shader DebugInfo support

Copy link
Contributor

Choose a reason for hiding this comment

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

The while loop with manual increment is just copium, for loop where created to handle those kind of "oh but here I need to continue; so need to think about incrementing" problems

Copy link
Contributor

Choose a reason for hiding this comment

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

And looking through our code we definitely have existing bad while loop usage where a for loop would be better

Copy link
Contributor Author

@spencer-lunarg spencer-lunarg Feb 6, 2025

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

This review keeps changing out from under me. But I like the while version better the for version because of the excessive comma operators required. KISS.

Copy link
Contributor

@arno-lunarg arno-lunarg left a comment

Choose a reason for hiding this comment

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

.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from 86e7a43 to d943a71 Compare February 6, 2025 04:42
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 365988.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19005 running.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19005 passed.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from d943a71 to 4eb750c Compare February 6, 2025 05:21
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 366012.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19006 running.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19006 passed.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 366516.

while (std::getline(in_stream, current_line)) {
out_source_lines.emplace_back(current_line);
}
next_offset = offset + length; // point to next instruction after OpSource
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ugh, now this is a subtle bug, we need to nest these for loops else we need to track the next instruction here

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19015 running.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from 8aac0c2 to 3f2b707 Compare February 6, 2025 14:58
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build queued with queue ID 366547.

@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19017 running.

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch from 3f2b707 to 4eb750c Compare February 6, 2025 15:08
@ci-tester-lunarg
Copy link
Collaborator

CI Vulkan-ValidationLayers build # 19006 passed.

jeremyg-lunarg
jeremyg-lunarg previously approved these changes Feb 6, 2025
Copy link
Contributor

@jeremyg-lunarg jeremyg-lunarg left a comment

Choose a reason for hiding this comment

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

SPIRV parsing is such a PITA

if ((insn.Opcode() != spv::OpSource) || (insn.Length() < 5) || (insn.Word(3) != reported_file_id)) {
uint32_t next_offset = 0;
for (uint32_t offset = kModuleStartingOffset, length = Length(instructions[offset]); offset < instructions.size();
(offset += length, length = Length(instructions[offset]))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

it is a bit confusing on how the various length statements end up executing. Both here and on line 75. IMO it would be clearer if length was managed by standalone statements rather than torturing us with the comma operator

if (insn.Length() < 7) {
return; // Optional source Text not provided
// We have now found the proper OpExtInst DebugSource
out_file_string_id = instructions[offset + 5];
Copy link
Contributor

Choose a reason for hiding this comment

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

what do 4, 5 and 7 mean here? It might be helpful to comment something about how the instruction works so that it easier to see what is happening.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nate always complained about this, basically it become a reality that if you are editing this code, you need the spec out for the IR instruciton

image

then you see that 5 here is <id> File

so I "could" make this instruction[offset + DebugSourceFileOperand] but this is constant issue we have everywhere and just never got around to code gen these operand names

const auto &insn = instructions[i];
if ((insn.Opcode() != spv::OpSource) || (insn.Length() < 5) || (insn.Word(3) != reported_file_id)) {
uint32_t offset = kModuleStartingOffset;
while (offset < instructions.size()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This review keeps changing out from under me. But I like the while version better the for version because of the excessive comma operators required. KISS.

@jeremyg-lunarg jeremyg-lunarg self-requested a review February 6, 2025 15:23
@jeremyg-lunarg jeremyg-lunarg dismissed their stale review February 6, 2025 15:25

will re-review when this thing is rebased and settled down

@spencer-lunarg spencer-lunarg merged commit b7d489b into KhronosGroup:main Feb 6, 2025
40 checks passed
@spencer-lunarg spencer-lunarg deleted the spencer-lunarg-doing-spirv-bare-with-no-class-is-no-fun branch February 6, 2025 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants