diff options
| author | 2018-04-20 09:16:55 -0500 | |
|---|---|---|
| committer | 2018-04-20 21:09:33 -0500 | |
| commit | c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009 (patch) | |
| tree | 5b23e8812808e3b3f87a874b0d4e5a418675ea85 /src | |
| parent | ShaderGen: Implemented the fsetp instruction. (diff) | |
| download | yuzu-c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009.tar.gz yuzu-c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009.tar.xz yuzu-c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009.zip | |
ShaderGen: Implemented predicated instruction execution.
Each predicated instruction will be wrapped in an `if (predicate) { instruction_body; }` in the GLSL, where `predicate` is one of the predicate boolean variables previously set by fsetp.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 35 |
2 files changed, 40 insertions, 1 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index fb639a417..e6c2fd367 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -331,7 +331,11 @@ union Instruction { | |||
| 331 | OpCode opcode; | 331 | OpCode opcode; |
| 332 | BitField<0, 8, Register> gpr0; | 332 | BitField<0, 8, Register> gpr0; |
| 333 | BitField<8, 8, Register> gpr8; | 333 | BitField<8, 8, Register> gpr8; |
| 334 | BitField<16, 4, Pred> pred; | 334 | union { |
| 335 | BitField<16, 4, Pred> full_pred; | ||
| 336 | BitField<16, 3, u64> pred_index; | ||
| 337 | } pred; | ||
| 338 | BitField<19, 1, u64> negate_pred; | ||
| 335 | BitField<20, 8, Register> gpr20; | 339 | BitField<20, 8, Register> gpr20; |
| 336 | BitField<20, 7, SubOp> sub_op; | 340 | BitField<20, 7, SubOp> sub_op; |
| 337 | BitField<28, 8, Register> gpr28; | 341 | BitField<28, 8, Register> gpr28; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 2e0203a68..7aaee9464 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -294,6 +294,25 @@ private: | |||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | /* | 296 | /* |
| 297 | * Returns the condition to use in the 'if' for a predicated instruction. | ||
| 298 | * @param instr Instruction to generate the if condition for. | ||
| 299 | * @returns string containing the predicate condition. | ||
| 300 | */ | ||
| 301 | std::string GetPredicateCondition(Instruction instr) const { | ||
| 302 | using Tegra::Shader::Pred; | ||
| 303 | ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)); | ||
| 304 | |||
| 305 | std::string variable = | ||
| 306 | 'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value())); | ||
| 307 | |||
| 308 | if (instr.negate_pred) { | ||
| 309 | return "!(" + variable + ')'; | ||
| 310 | } | ||
| 311 | |||
| 312 | return variable; | ||
| 313 | } | ||
| 314 | |||
| 315 | /* | ||
| 297 | * Returns whether the instruction at the specified offset is a 'sched' instruction. | 316 | * Returns whether the instruction at the specified offset is a 'sched' instruction. |
| 298 | * Sched instructions always appear before a sequence of 3 instructions. | 317 | * Sched instructions always appear before a sequence of 3 instructions. |
| 299 | */ | 318 | */ |
| @@ -320,6 +339,16 @@ private: | |||
| 320 | 339 | ||
| 321 | shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name); | 340 | shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name); |
| 322 | 341 | ||
| 342 | using Tegra::Shader::Pred; | ||
| 343 | ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, | ||
| 344 | "NeverExecute predicate not implemented"); | ||
| 345 | |||
| 346 | if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { | ||
| 347 | shader.AddLine("if (" + GetPredicateCondition(instr) + ')'); | ||
| 348 | shader.AddLine('{'); | ||
| 349 | ++shader.scope; | ||
| 350 | } | ||
| 351 | |||
| 323 | switch (OpCode::GetInfo(instr.opcode).type) { | 352 | switch (OpCode::GetInfo(instr.opcode).type) { |
| 324 | case OpCode::Type::Arithmetic: { | 353 | case OpCode::Type::Arithmetic: { |
| 325 | std::string dest = GetRegister(instr.gpr0); | 354 | std::string dest = GetRegister(instr.gpr0); |
| @@ -559,6 +588,12 @@ private: | |||
| 559 | } | 588 | } |
| 560 | } | 589 | } |
| 561 | 590 | ||
| 591 | // Close the predicate condition scope. | ||
| 592 | if (instr.pred != Pred::UnusedIndex) { | ||
| 593 | --shader.scope; | ||
| 594 | shader.AddLine('}'); | ||
| 595 | } | ||
| 596 | |||
| 562 | return offset + 1; | 597 | return offset + 1; |
| 563 | } | 598 | } |
| 564 | 599 | ||