mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #1527 from FernandoS27/assert-flow
Assert Control Flow Instructions using Control Codes
This commit is contained in:
		
						commit
						9afcbba8e4
					
				@ -1235,6 +1235,7 @@ union Instruction {
 | 
				
			|||||||
    BitField<60, 1, u64> is_b_gpr;
 | 
					    BitField<60, 1, u64> is_b_gpr;
 | 
				
			||||||
    BitField<59, 1, u64> is_c_gpr;
 | 
					    BitField<59, 1, u64> is_c_gpr;
 | 
				
			||||||
    BitField<20, 24, s64> smem_imm;
 | 
					    BitField<20, 24, s64> smem_imm;
 | 
				
			||||||
 | 
					    BitField<0, 5, ControlCode> flow_control_code;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Attribute attribute;
 | 
					    Attribute attribute;
 | 
				
			||||||
    Sampler sampler;
 | 
					    Sampler sampler;
 | 
				
			||||||
 | 
				
			|||||||
@ -3474,6 +3474,12 @@ private:
 | 
				
			|||||||
                    EmitFragmentOutputsWrite();
 | 
					                    EmitFragmentOutputsWrite();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const Tegra::Shader::ControlCode cc = instr.flow_control_code;
 | 
				
			||||||
 | 
					                if (cc != Tegra::Shader::ControlCode::T) {
 | 
				
			||||||
 | 
					                    LOG_CRITICAL(HW_GPU, "EXIT Control Code used: {}", static_cast<u32>(cc));
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                switch (instr.flow.cond) {
 | 
					                switch (instr.flow.cond) {
 | 
				
			||||||
                case Tegra::Shader::FlowCondition::Always:
 | 
					                case Tegra::Shader::FlowCondition::Always:
 | 
				
			||||||
                    shader.AddLine("return true;");
 | 
					                    shader.AddLine("return true;");
 | 
				
			||||||
@ -3503,6 +3509,11 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // Enclose "discard" in a conditional, so that GLSL compilation does not complain
 | 
					                // Enclose "discard" in a conditional, so that GLSL compilation does not complain
 | 
				
			||||||
                // about unexecuted instructions that may follow this.
 | 
					                // about unexecuted instructions that may follow this.
 | 
				
			||||||
 | 
					                const Tegra::Shader::ControlCode cc = instr.flow_control_code;
 | 
				
			||||||
 | 
					                if (cc != Tegra::Shader::ControlCode::T) {
 | 
				
			||||||
 | 
					                    LOG_CRITICAL(HW_GPU, "KIL Control Code used: {}", static_cast<u32>(cc));
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                shader.AddLine("if (true) {");
 | 
					                shader.AddLine("if (true) {");
 | 
				
			||||||
                ++shader.scope;
 | 
					                ++shader.scope;
 | 
				
			||||||
                shader.AddLine("discard;");
 | 
					                shader.AddLine("discard;");
 | 
				
			||||||
@ -3560,6 +3571,11 @@ private:
 | 
				
			|||||||
            case OpCode::Id::BRA: {
 | 
					            case OpCode::Id::BRA: {
 | 
				
			||||||
                ASSERT_MSG(instr.bra.constant_buffer == 0,
 | 
					                ASSERT_MSG(instr.bra.constant_buffer == 0,
 | 
				
			||||||
                           "BRA with constant buffers are not implemented");
 | 
					                           "BRA with constant buffers are not implemented");
 | 
				
			||||||
 | 
					                const Tegra::Shader::ControlCode cc = instr.flow_control_code;
 | 
				
			||||||
 | 
					                if (cc != Tegra::Shader::ControlCode::T) {
 | 
				
			||||||
 | 
					                    LOG_CRITICAL(HW_GPU, "BRA Control Code used: {}", static_cast<u32>(cc));
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                const u32 target = offset + instr.bra.GetBranchTarget();
 | 
					                const u32 target = offset + instr.bra.GetBranchTarget();
 | 
				
			||||||
                shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
 | 
					                shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
@ -3600,13 +3616,21 @@ private:
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            case OpCode::Id::SYNC: {
 | 
					            case OpCode::Id::SYNC: {
 | 
				
			||||||
                // The SYNC opcode jumps to the address previously set by the SSY opcode
 | 
					                // The SYNC opcode jumps to the address previously set by the SSY opcode
 | 
				
			||||||
                ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
 | 
					                const Tegra::Shader::ControlCode cc = instr.flow_control_code;
 | 
				
			||||||
 | 
					                if (cc != Tegra::Shader::ControlCode::T) {
 | 
				
			||||||
 | 
					                    LOG_CRITICAL(HW_GPU, "SYNC Control Code used: {}", static_cast<u32>(cc));
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                EmitPopFromFlowStack();
 | 
					                EmitPopFromFlowStack();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case OpCode::Id::BRK: {
 | 
					            case OpCode::Id::BRK: {
 | 
				
			||||||
                // The BRK opcode jumps to the address previously set by the PBK opcode
 | 
					                // The BRK opcode jumps to the address previously set by the PBK opcode
 | 
				
			||||||
                ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
 | 
					                const Tegra::Shader::ControlCode cc = instr.flow_control_code;
 | 
				
			||||||
 | 
					                if (cc != Tegra::Shader::ControlCode::T) {
 | 
				
			||||||
 | 
					                    LOG_CRITICAL(HW_GPU, "BRK Control Code used: {}", static_cast<u32>(cc));
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                EmitPopFromFlowStack();
 | 
					                EmitPopFromFlowStack();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user