Merge pull request #1101 from Subv/ssy_stack
Shaders: Implemented a stack for the SSY/SYNC instructions.
This commit is contained in:
		
						commit
						85da529f15
					
				@ -842,6 +842,33 @@ private:
 | 
			
		||||
        shader.AddLine('}');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Emits code to push the input target address to the SSY address stack, incrementing the stack
 | 
			
		||||
     * top.
 | 
			
		||||
     */
 | 
			
		||||
    void EmitPushToSSYStack(u32 target) {
 | 
			
		||||
        shader.AddLine('{');
 | 
			
		||||
        ++shader.scope;
 | 
			
		||||
        shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;");
 | 
			
		||||
        shader.AddLine("ssy_stack_top++;");
 | 
			
		||||
        --shader.scope;
 | 
			
		||||
        shader.AddLine('}');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Emits code to pop an address from the SSY address stack, setting the jump address to the
 | 
			
		||||
     * popped address and decrementing the stack top.
 | 
			
		||||
     */
 | 
			
		||||
    void EmitPopFromSSYStack() {
 | 
			
		||||
        shader.AddLine('{');
 | 
			
		||||
        ++shader.scope;
 | 
			
		||||
        shader.AddLine("ssy_stack_top--;");
 | 
			
		||||
        shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];");
 | 
			
		||||
        shader.AddLine("break;");
 | 
			
		||||
        --shader.scope;
 | 
			
		||||
        shader.AddLine('}');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Compiles a single instruction from Tegra to GLSL.
 | 
			
		||||
     * @param offset the offset of the Tegra shader instruction.
 | 
			
		||||
@ -1870,13 +1897,13 @@ private:
 | 
			
		||||
                ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported");
 | 
			
		||||
 | 
			
		||||
                u32 target = offset + instr.bra.GetBranchTarget();
 | 
			
		||||
                shader.AddLine("ssy_target = " + std::to_string(target) + "u;");
 | 
			
		||||
                EmitPushToSSYStack(target);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case OpCode::Id::SYNC: {
 | 
			
		||||
                // The SYNC opcode jumps to the address previously set by the SSY opcode
 | 
			
		||||
                ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
 | 
			
		||||
                shader.AddLine("{ jmp_to = ssy_target; break; }");
 | 
			
		||||
                EmitPopFromSSYStack();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case OpCode::Id::DEPBAR: {
 | 
			
		||||
@ -1947,7 +1974,13 @@ private:
 | 
			
		||||
            } else {
 | 
			
		||||
                labels.insert(subroutine.begin);
 | 
			
		||||
                shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;");
 | 
			
		||||
                shader.AddLine("uint ssy_target = 0u;");
 | 
			
		||||
 | 
			
		||||
                // TODO(Subv): Figure out the actual depth of the SSY stack, for now it seems
 | 
			
		||||
                // unlikely that shaders will use 20 nested SSYs.
 | 
			
		||||
                constexpr u32 SSY_STACK_SIZE = 20;
 | 
			
		||||
                shader.AddLine("uint ssy_stack[" + std::to_string(SSY_STACK_SIZE) + "];");
 | 
			
		||||
                shader.AddLine("uint ssy_stack_top = 0u;");
 | 
			
		||||
 | 
			
		||||
                shader.AddLine("while (true) {");
 | 
			
		||||
                ++shader.scope;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user