shader: Split SSY and PBK stack
Hardware testing revealed that SSY and PBK push to a different stack, allowing code like this: SSY label1; PBK label2; SYNC; label1: PBK; label2: EXIT;
This commit is contained in:
parent
cd2d9628c9
commit
fe8e6618f2
4 changed files with 78 additions and 27 deletions
|
@ -109,22 +109,20 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
|
|||
UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
|
||||
"Constant buffer flow is not supported");
|
||||
|
||||
// The SSY opcode tells the GPU where to re-converge divergent execution paths, it sets the
|
||||
// target of the jump that the SYNC instruction will make. The SSY opcode has a similar
|
||||
// structure to the BRA opcode.
|
||||
// The SSY opcode tells the GPU where to re-converge divergent execution paths with SYNC.
|
||||
const u32 target = pc + instr.bra.GetBranchTarget();
|
||||
bb.push_back(Operation(OperationCode::PushFlowStack, Immediate(target)));
|
||||
bb.push_back(
|
||||
Operation(OperationCode::PushFlowStack, MetaStackClass::Ssy, Immediate(target)));
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::PBK: {
|
||||
UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
|
||||
"Constant buffer PBK is not supported");
|
||||
|
||||
// PBK pushes to a stack the address where BRK will jump to. This shares stack with SSY but
|
||||
// using SYNC on a PBK address will kill the shader execution. We don't emulate this because
|
||||
// it's very unlikely a driver will emit such invalid shader.
|
||||
// PBK pushes to a stack the address where BRK will jump to.
|
||||
const u32 target = pc + instr.bra.GetBranchTarget();
|
||||
bb.push_back(Operation(OperationCode::PushFlowStack, Immediate(target)));
|
||||
bb.push_back(
|
||||
Operation(OperationCode::PushFlowStack, MetaStackClass::Pbk, Immediate(target)));
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::SYNC: {
|
||||
|
@ -133,7 +131,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
|
|||
static_cast<u32>(cc));
|
||||
|
||||
// The SYNC opcode jumps to the address previously set by the SSY opcode
|
||||
bb.push_back(Operation(OperationCode::PopFlowStack));
|
||||
bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Ssy));
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::BRK: {
|
||||
|
@ -142,7 +140,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
|
|||
static_cast<u32>(cc));
|
||||
|
||||
// The BRK opcode jumps to the address previously set by the PBK opcode
|
||||
bb.push_back(Operation(OperationCode::PopFlowStack));
|
||||
bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Pbk));
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::IPA: {
|
||||
|
|
|
@ -174,6 +174,11 @@ enum class InternalFlag {
|
|||
Amount = 4,
|
||||
};
|
||||
|
||||
enum class MetaStackClass {
|
||||
Ssy,
|
||||
Pbk,
|
||||
};
|
||||
|
||||
class OperationNode;
|
||||
class ConditionalNode;
|
||||
class GprNode;
|
||||
|
@ -285,7 +290,7 @@ struct MetaTexture {
|
|||
};
|
||||
|
||||
/// Parameters that modify an operation but are not part of any particular operand
|
||||
using Meta = std::variant<MetaArithmetic, MetaTexture, Tegra::Shader::HalfType>;
|
||||
using Meta = std::variant<MetaArithmetic, MetaTexture, MetaStackClass, Tegra::Shader::HalfType>;
|
||||
|
||||
/// Holds any kind of operation that can be done in the IR
|
||||
class OperationNode final {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue