@ -132,20 +132,16 @@ public:
branch_labels . push_back ( label ) ;
}
// TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely
// that shaders will use 20 nested SSYs and PBKs.
constexpr u32 FLOW_STACK_SIZE = 20 ;
const Id flow_stack_type = TypeArray ( t_uint , Constant ( t_uint , FLOW_STACK_SIZE ) ) ;
jmp_to = Emit ( OpVariable ( TypePointer ( spv : : StorageClass : : Function , t_uint ) ,
spv : : StorageClass : : Function , Constant ( t_uint , first_address ) ) ) ;
flow_stack = Emit ( OpVariable ( TypePointer ( spv : : StorageClass : : Function , flow_stack_type ) ,
spv : : StorageClass : : Function , ConstantNull ( flow_stack_type ) ) ) ;
flow_stack_top =
Emit ( OpVariable ( t_func_uint , spv : : StorageClass : : Function , Constant ( t_uint , 0 ) ) ) ;
std : : tie ( ssy_flow_stack , ssy_flow_stack_top ) = CreateFlowStack ( ) ;
std : : tie ( pbk_flow_stack , pbk_flow_stack_top ) = CreateFlowStack ( ) ;
Name ( jmp_to , " jmp_to " ) ;
Name ( flow_stack , " flow_stack " ) ;
Name ( flow_stack_top , " flow_stack_top " ) ;
Name ( ssy_flow_stack , " ssy_flow_stack " ) ;
Name ( ssy_flow_stack_top , " ssy_flow_stack_top " ) ;
Name ( pbk_flow_stack , " pbk_flow_stack " ) ;
Name ( pbk_flow_stack_top , " pbk_flow_stack_top " ) ;
Emit ( OpBranch ( loop_label ) ) ;
Emit ( loop_label ) ;
@ -952,6 +948,7 @@ private:
const auto target = std : : get_if < ImmediateNode > ( & * operation [ 0 ] ) ;
ASSERT ( target ) ;
const auto [ flow_stack , flow_stack_top ] = GetFlowStack ( operation ) ;
const Id current = Emit ( OpLoad ( t_uint , flow_stack_top ) ) ;
const Id next = Emit ( OpIAdd ( t_uint , current , Constant ( t_uint , 1 ) ) ) ;
const Id access = Emit ( OpAccessChain ( t_func_uint , flow_stack , current ) ) ;
@ -962,6 +959,7 @@ private:
}
Id PopFlowStack ( Operation operation ) {
const auto [ flow_stack , flow_stack_top ] = GetFlowStack ( operation ) ;
const Id current = Emit ( OpLoad ( t_uint , flow_stack_top ) ) ;
const Id previous = Emit ( OpISub ( t_uint , current , Constant ( t_uint , 1 ) ) ) ;
const Id access = Emit ( OpAccessChain ( t_func_uint , flow_stack , previous ) ) ;
@ -1172,6 +1170,31 @@ private:
Emit ( skip_label ) ;
}
std : : tuple < Id , Id > CreateFlowStack ( ) {
// TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely
// that shaders will use 20 nested SSYs and PBKs.
constexpr u32 FLOW_STACK_SIZE = 20 ;
constexpr auto storage_class = spv : : StorageClass : : Function ;
const Id flow_stack_type = TypeArray ( t_uint , Constant ( t_uint , FLOW_STACK_SIZE ) ) ;
const Id stack = Emit ( OpVariable ( TypePointer ( storage_class , flow_stack_type ) , storage_class ,
ConstantNull ( flow_stack_type ) ) ) ;
const Id top = Emit ( OpVariable ( t_func_uint , storage_class , Constant ( t_uint , 0 ) ) ) ;
return std : : tie ( stack , top ) ;
}
std : : pair < Id , Id > GetFlowStack ( Operation operation ) {
const auto stack_class = std : : get < MetaStackClass > ( operation . GetMeta ( ) ) ;
switch ( stack_class ) {
case MetaStackClass : : Ssy :
return { ssy_flow_stack , ssy_flow_stack_top } ;
case MetaStackClass : : Pbk :
return { pbk_flow_stack , pbk_flow_stack_top } ;
}
UNREACHABLE ( ) ;
return { } ;
}
static constexpr OperationDecompilersArray operation_decompilers = {
& SPIRVDecompiler : : Assign ,
@ -1414,8 +1437,10 @@ private:
Id execute_function { } ;
Id jmp_to { } ;
Id flow_stack_top { } ;
Id flow_stack { } ;
Id ssy_flow_stack_top { } ;
Id pbk_flow_stack_top { } ;
Id ssy_flow_stack { } ;
Id pbk_flow_stack { } ;
Id continue_label { } ;
std : : map < u32 , Id > labels ;
} ;