diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/ast.cpp | 85 | ||||
| -rw-r--r-- | src/video_core/shader/ast.h | 6 |
2 files changed, 51 insertions, 40 deletions
diff --git a/src/video_core/shader/ast.cpp b/src/video_core/shader/ast.cpp index 436d45f4b..e43aecc18 100644 --- a/src/video_core/shader/ast.cpp +++ b/src/video_core/shader/ast.cpp | |||
| @@ -3,6 +3,9 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string> | 5 | #include <string> |
| 6 | #include <string_view> | ||
| 7 | |||
| 8 | #include <fmt/format.h> | ||
| 6 | 9 | ||
| 7 | #include "common/assert.h" | 10 | #include "common/assert.h" |
| 8 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| @@ -229,7 +232,8 @@ public: | |||
| 229 | return inner; | 232 | return inner; |
| 230 | } | 233 | } |
| 231 | 234 | ||
| 232 | std::string inner{}; | 235 | private: |
| 236 | std::string inner; | ||
| 233 | }; | 237 | }; |
| 234 | 238 | ||
| 235 | class ASTPrinter { | 239 | class ASTPrinter { |
| @@ -249,7 +253,7 @@ public: | |||
| 249 | void operator()(const ASTIfThen& ast) { | 253 | void operator()(const ASTIfThen& ast) { |
| 250 | ExprPrinter expr_parser{}; | 254 | ExprPrinter expr_parser{}; |
| 251 | std::visit(expr_parser, *ast.condition); | 255 | std::visit(expr_parser, *ast.condition); |
| 252 | inner += Ident() + "if (" + expr_parser.GetResult() + ") {\n"; | 256 | inner += fmt::format("{}if ({}) {{\n", Indent(), expr_parser.GetResult()); |
| 253 | scope++; | 257 | scope++; |
| 254 | ASTNode current = ast.nodes.GetFirst(); | 258 | ASTNode current = ast.nodes.GetFirst(); |
| 255 | while (current) { | 259 | while (current) { |
| @@ -257,11 +261,13 @@ public: | |||
| 257 | current = current->GetNext(); | 261 | current = current->GetNext(); |
| 258 | } | 262 | } |
| 259 | scope--; | 263 | scope--; |
| 260 | inner += Ident() + "}\n"; | 264 | inner += fmt::format("{}}}\n", Indent()); |
| 261 | } | 265 | } |
| 262 | 266 | ||
| 263 | void operator()(const ASTIfElse& ast) { | 267 | void operator()(const ASTIfElse& ast) { |
| 264 | inner += Ident() + "else {\n"; | 268 | inner += Indent(); |
| 269 | inner += "else {\n"; | ||
| 270 | |||
| 265 | scope++; | 271 | scope++; |
| 266 | ASTNode current = ast.nodes.GetFirst(); | 272 | ASTNode current = ast.nodes.GetFirst(); |
| 267 | while (current) { | 273 | while (current) { |
| @@ -269,40 +275,41 @@ public: | |||
| 269 | current = current->GetNext(); | 275 | current = current->GetNext(); |
| 270 | } | 276 | } |
| 271 | scope--; | 277 | scope--; |
| 272 | inner += Ident() + "}\n"; | 278 | |
| 279 | inner += Indent(); | ||
| 280 | inner += "}\n"; | ||
| 273 | } | 281 | } |
| 274 | 282 | ||
| 275 | void operator()(const ASTBlockEncoded& ast) { | 283 | void operator()(const ASTBlockEncoded& ast) { |
| 276 | inner += Ident() + "Block(" + std::to_string(ast.start) + ", " + std::to_string(ast.end) + | 284 | inner += fmt::format("{}Block({}, {});\n", Indent(), ast.start, ast.end); |
| 277 | ");\n"; | ||
| 278 | } | 285 | } |
| 279 | 286 | ||
| 280 | void operator()(const ASTBlockDecoded& ast) { | 287 | void operator()([[maybe_unused]] const ASTBlockDecoded& ast) { |
| 281 | inner += Ident() + "Block;\n"; | 288 | inner += Indent(); |
| 289 | inner += "Block;\n"; | ||
| 282 | } | 290 | } |
| 283 | 291 | ||
| 284 | void operator()(const ASTVarSet& ast) { | 292 | void operator()(const ASTVarSet& ast) { |
| 285 | ExprPrinter expr_parser{}; | 293 | ExprPrinter expr_parser{}; |
| 286 | std::visit(expr_parser, *ast.condition); | 294 | std::visit(expr_parser, *ast.condition); |
| 287 | inner += | 295 | inner += fmt::format("{}V{} := {};\n", Indent(), ast.index, expr_parser.GetResult()); |
| 288 | Ident() + "V" + std::to_string(ast.index) + " := " + expr_parser.GetResult() + ";\n"; | ||
| 289 | } | 296 | } |
| 290 | 297 | ||
| 291 | void operator()(const ASTLabel& ast) { | 298 | void operator()(const ASTLabel& ast) { |
| 292 | inner += "Label_" + std::to_string(ast.index) + ":\n"; | 299 | inner += fmt::format("Label_{}:\n", ast.index); |
| 293 | } | 300 | } |
| 294 | 301 | ||
| 295 | void operator()(const ASTGoto& ast) { | 302 | void operator()(const ASTGoto& ast) { |
| 296 | ExprPrinter expr_parser{}; | 303 | ExprPrinter expr_parser{}; |
| 297 | std::visit(expr_parser, *ast.condition); | 304 | std::visit(expr_parser, *ast.condition); |
| 298 | inner += Ident() + "(" + expr_parser.GetResult() + ") -> goto Label_" + | 305 | inner += |
| 299 | std::to_string(ast.label) + ";\n"; | 306 | fmt::format("{}({}) -> goto Label_{};\n", Indent(), expr_parser.GetResult(), ast.label); |
| 300 | } | 307 | } |
| 301 | 308 | ||
| 302 | void operator()(const ASTDoWhile& ast) { | 309 | void operator()(const ASTDoWhile& ast) { |
| 303 | ExprPrinter expr_parser{}; | 310 | ExprPrinter expr_parser{}; |
| 304 | std::visit(expr_parser, *ast.condition); | 311 | std::visit(expr_parser, *ast.condition); |
| 305 | inner += Ident() + "do {\n"; | 312 | inner += fmt::format("{}do {{\n", Indent()); |
| 306 | scope++; | 313 | scope++; |
| 307 | ASTNode current = ast.nodes.GetFirst(); | 314 | ASTNode current = ast.nodes.GetFirst(); |
| 308 | while (current) { | 315 | while (current) { |
| @@ -310,32 +317,23 @@ public: | |||
| 310 | current = current->GetNext(); | 317 | current = current->GetNext(); |
| 311 | } | 318 | } |
| 312 | scope--; | 319 | scope--; |
| 313 | inner += Ident() + "} while (" + expr_parser.GetResult() + ");\n"; | 320 | inner += fmt::format("{}}} while ({});\n", Indent(), expr_parser.GetResult()); |
| 314 | } | 321 | } |
| 315 | 322 | ||
| 316 | void operator()(const ASTReturn& ast) { | 323 | void operator()(const ASTReturn& ast) { |
| 317 | ExprPrinter expr_parser{}; | 324 | ExprPrinter expr_parser{}; |
| 318 | std::visit(expr_parser, *ast.condition); | 325 | std::visit(expr_parser, *ast.condition); |
| 319 | inner += Ident() + "(" + expr_parser.GetResult() + ") -> " + | 326 | inner += fmt::format("{}({}) -> {};\n", Indent(), expr_parser.GetResult(), |
| 320 | (ast.kills ? "discard" : "exit") + ";\n"; | 327 | ast.kills ? "discard" : "exit"); |
| 321 | } | 328 | } |
| 322 | 329 | ||
| 323 | void operator()(const ASTBreak& ast) { | 330 | void operator()(const ASTBreak& ast) { |
| 324 | ExprPrinter expr_parser{}; | 331 | ExprPrinter expr_parser{}; |
| 325 | std::visit(expr_parser, *ast.condition); | 332 | std::visit(expr_parser, *ast.condition); |
| 326 | inner += Ident() + "(" + expr_parser.GetResult() + ") -> break;\n"; | 333 | inner += fmt::format("{}({}) -> break;\n", Indent(), expr_parser.GetResult()); |
| 327 | } | 334 | } |
| 328 | 335 | ||
| 329 | std::string& Ident() { | 336 | void Visit(const ASTNode& node) { |
| 330 | if (memo_scope == scope) { | ||
| 331 | return tabs_memo; | ||
| 332 | } | ||
| 333 | tabs_memo = tabs.substr(0, scope * 2); | ||
| 334 | memo_scope = scope; | ||
| 335 | return tabs_memo; | ||
| 336 | } | ||
| 337 | |||
| 338 | void Visit(ASTNode& node) { | ||
| 339 | std::visit(*this, *node->GetInnerData()); | 337 | std::visit(*this, *node->GetInnerData()); |
| 340 | } | 338 | } |
| 341 | 339 | ||
| @@ -344,16 +342,29 @@ public: | |||
| 344 | } | 342 | } |
| 345 | 343 | ||
| 346 | private: | 344 | private: |
| 345 | std::string_view Indent() { | ||
| 346 | if (space_segment_scope == scope) { | ||
| 347 | return space_segment; | ||
| 348 | } | ||
| 349 | |||
| 350 | // Ensure that we don't exceed our view. | ||
| 351 | ASSERT(scope * 2 < spaces.size()); | ||
| 352 | |||
| 353 | space_segment = spaces.substr(0, scope * 2); | ||
| 354 | space_segment_scope = scope; | ||
| 355 | return space_segment; | ||
| 356 | } | ||
| 357 | |||
| 347 | std::string inner{}; | 358 | std::string inner{}; |
| 348 | u32 scope{}; | 359 | std::string_view space_segment; |
| 349 | 360 | ||
| 350 | std::string tabs_memo{}; | 361 | u32 scope{}; |
| 351 | u32 memo_scope{}; | 362 | u32 space_segment_scope{}; |
| 352 | 363 | ||
| 353 | static constexpr std::string_view tabs{" "}; | 364 | static constexpr std::string_view spaces{" "}; |
| 354 | }; | 365 | }; |
| 355 | 366 | ||
| 356 | std::string ASTManager::Print() { | 367 | std::string ASTManager::Print() const { |
| 357 | ASTPrinter printer{}; | 368 | ASTPrinter printer{}; |
| 358 | printer.Visit(main_node); | 369 | printer.Visit(main_node); |
| 359 | return printer.GetResult(); | 370 | return printer.GetResult(); |
| @@ -549,13 +560,13 @@ bool ASTManager::DirectlyRelated(const ASTNode& first, const ASTNode& second) co | |||
| 549 | return min->GetParent() == max->GetParent(); | 560 | return min->GetParent() == max->GetParent(); |
| 550 | } | 561 | } |
| 551 | 562 | ||
| 552 | void ASTManager::ShowCurrentState(std::string_view state) { | 563 | void ASTManager::ShowCurrentState(std::string_view state) const { |
| 553 | LOG_CRITICAL(HW_GPU, "\nState {}:\n\n{}\n", state, Print()); | 564 | LOG_CRITICAL(HW_GPU, "\nState {}:\n\n{}\n", state, Print()); |
| 554 | SanityCheck(); | 565 | SanityCheck(); |
| 555 | } | 566 | } |
| 556 | 567 | ||
| 557 | void ASTManager::SanityCheck() { | 568 | void ASTManager::SanityCheck() const { |
| 558 | for (auto& label : labels) { | 569 | for (const auto& label : labels) { |
| 559 | if (!label->GetParent()) { | 570 | if (!label->GetParent()) { |
| 560 | LOG_CRITICAL(HW_GPU, "Sanity Check Failed"); | 571 | LOG_CRITICAL(HW_GPU, "Sanity Check Failed"); |
| 561 | } | 572 | } |
diff --git a/src/video_core/shader/ast.h b/src/video_core/shader/ast.h index d7bf11821..a2f0044ba 100644 --- a/src/video_core/shader/ast.h +++ b/src/video_core/shader/ast.h | |||
| @@ -328,13 +328,13 @@ public: | |||
| 328 | 328 | ||
| 329 | void InsertReturn(Expr condition, bool kills); | 329 | void InsertReturn(Expr condition, bool kills); |
| 330 | 330 | ||
| 331 | std::string Print(); | 331 | std::string Print() const; |
| 332 | 332 | ||
| 333 | void Decompile(); | 333 | void Decompile(); |
| 334 | 334 | ||
| 335 | void ShowCurrentState(std::string_view state); | 335 | void ShowCurrentState(std::string_view state) const; |
| 336 | 336 | ||
| 337 | void SanityCheck(); | 337 | void SanityCheck() const; |
| 338 | 338 | ||
| 339 | void Clear(); | 339 | void Clear(); |
| 340 | 340 | ||