diff options
| author | 2019-06-02 18:52:07 -0300 | |
|---|---|---|
| committer | 2019-06-07 02:18:27 -0300 | |
| commit | fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0 (patch) | |
| tree | 308d278996e18558ab049daa01b4873b08b799e8 /src/video_core/renderer_vulkan | |
| parent | Merge pull request #2558 from ReinUsesLisp/shader-nodes (diff) | |
| download | yuzu-fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0.tar.gz yuzu-fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0.tar.xz yuzu-fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0.zip | |
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;
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 547883425..33ad9764a 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -132,20 +132,16 @@ public: | |||
| 132 | branch_labels.push_back(label); | 132 | branch_labels.push_back(label); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | // TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely | ||
| 136 | // that shaders will use 20 nested SSYs and PBKs. | ||
| 137 | constexpr u32 FLOW_STACK_SIZE = 20; | ||
| 138 | const Id flow_stack_type = TypeArray(t_uint, Constant(t_uint, FLOW_STACK_SIZE)); | ||
| 139 | jmp_to = Emit(OpVariable(TypePointer(spv::StorageClass::Function, t_uint), | 135 | jmp_to = Emit(OpVariable(TypePointer(spv::StorageClass::Function, t_uint), |
| 140 | spv::StorageClass::Function, Constant(t_uint, first_address))); | 136 | spv::StorageClass::Function, Constant(t_uint, first_address))); |
| 141 | flow_stack = Emit(OpVariable(TypePointer(spv::StorageClass::Function, flow_stack_type), | 137 | std::tie(ssy_flow_stack, ssy_flow_stack_top) = CreateFlowStack(); |
| 142 | spv::StorageClass::Function, ConstantNull(flow_stack_type))); | 138 | std::tie(pbk_flow_stack, pbk_flow_stack_top) = CreateFlowStack(); |
| 143 | flow_stack_top = | ||
| 144 | Emit(OpVariable(t_func_uint, spv::StorageClass::Function, Constant(t_uint, 0))); | ||
| 145 | 139 | ||
| 146 | Name(jmp_to, "jmp_to"); | 140 | Name(jmp_to, "jmp_to"); |
| 147 | Name(flow_stack, "flow_stack"); | 141 | Name(ssy_flow_stack, "ssy_flow_stack"); |
| 148 | Name(flow_stack_top, "flow_stack_top"); | 142 | Name(ssy_flow_stack_top, "ssy_flow_stack_top"); |
| 143 | Name(pbk_flow_stack, "pbk_flow_stack"); | ||
| 144 | Name(pbk_flow_stack_top, "pbk_flow_stack_top"); | ||
| 149 | 145 | ||
| 150 | Emit(OpBranch(loop_label)); | 146 | Emit(OpBranch(loop_label)); |
| 151 | Emit(loop_label); | 147 | Emit(loop_label); |
| @@ -952,6 +948,7 @@ private: | |||
| 952 | const auto target = std::get_if<ImmediateNode>(&*operation[0]); | 948 | const auto target = std::get_if<ImmediateNode>(&*operation[0]); |
| 953 | ASSERT(target); | 949 | ASSERT(target); |
| 954 | 950 | ||
| 951 | const auto [flow_stack, flow_stack_top] = GetFlowStack(operation); | ||
| 955 | const Id current = Emit(OpLoad(t_uint, flow_stack_top)); | 952 | const Id current = Emit(OpLoad(t_uint, flow_stack_top)); |
| 956 | const Id next = Emit(OpIAdd(t_uint, current, Constant(t_uint, 1))); | 953 | const Id next = Emit(OpIAdd(t_uint, current, Constant(t_uint, 1))); |
| 957 | const Id access = Emit(OpAccessChain(t_func_uint, flow_stack, current)); | 954 | const Id access = Emit(OpAccessChain(t_func_uint, flow_stack, current)); |
| @@ -962,6 +959,7 @@ private: | |||
| 962 | } | 959 | } |
| 963 | 960 | ||
| 964 | Id PopFlowStack(Operation operation) { | 961 | Id PopFlowStack(Operation operation) { |
| 962 | const auto [flow_stack, flow_stack_top] = GetFlowStack(operation); | ||
| 965 | const Id current = Emit(OpLoad(t_uint, flow_stack_top)); | 963 | const Id current = Emit(OpLoad(t_uint, flow_stack_top)); |
| 966 | const Id previous = Emit(OpISub(t_uint, current, Constant(t_uint, 1))); | 964 | const Id previous = Emit(OpISub(t_uint, current, Constant(t_uint, 1))); |
| 967 | const Id access = Emit(OpAccessChain(t_func_uint, flow_stack, previous)); | 965 | const Id access = Emit(OpAccessChain(t_func_uint, flow_stack, previous)); |
| @@ -1172,6 +1170,31 @@ private: | |||
| 1172 | Emit(skip_label); | 1170 | Emit(skip_label); |
| 1173 | } | 1171 | } |
| 1174 | 1172 | ||
| 1173 | std::tuple<Id, Id> CreateFlowStack() { | ||
| 1174 | // TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely | ||
| 1175 | // that shaders will use 20 nested SSYs and PBKs. | ||
| 1176 | constexpr u32 FLOW_STACK_SIZE = 20; | ||
| 1177 | constexpr auto storage_class = spv::StorageClass::Function; | ||
| 1178 | |||
| 1179 | const Id flow_stack_type = TypeArray(t_uint, Constant(t_uint, FLOW_STACK_SIZE)); | ||
| 1180 | const Id stack = Emit(OpVariable(TypePointer(storage_class, flow_stack_type), storage_class, | ||
| 1181 | ConstantNull(flow_stack_type))); | ||
| 1182 | const Id top = Emit(OpVariable(t_func_uint, storage_class, Constant(t_uint, 0))); | ||
| 1183 | return std::tie(stack, top); | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | std::pair<Id, Id> GetFlowStack(Operation operation) { | ||
| 1187 | const auto stack_class = std::get<MetaStackClass>(operation.GetMeta()); | ||
| 1188 | switch (stack_class) { | ||
| 1189 | case MetaStackClass::Ssy: | ||
| 1190 | return {ssy_flow_stack, ssy_flow_stack_top}; | ||
| 1191 | case MetaStackClass::Pbk: | ||
| 1192 | return {pbk_flow_stack, pbk_flow_stack_top}; | ||
| 1193 | } | ||
| 1194 | UNREACHABLE(); | ||
| 1195 | return {}; | ||
| 1196 | } | ||
| 1197 | |||
| 1175 | static constexpr OperationDecompilersArray operation_decompilers = { | 1198 | static constexpr OperationDecompilersArray operation_decompilers = { |
| 1176 | &SPIRVDecompiler::Assign, | 1199 | &SPIRVDecompiler::Assign, |
| 1177 | 1200 | ||
| @@ -1414,8 +1437,10 @@ private: | |||
| 1414 | 1437 | ||
| 1415 | Id execute_function{}; | 1438 | Id execute_function{}; |
| 1416 | Id jmp_to{}; | 1439 | Id jmp_to{}; |
| 1417 | Id flow_stack_top{}; | 1440 | Id ssy_flow_stack_top{}; |
| 1418 | Id flow_stack{}; | 1441 | Id pbk_flow_stack_top{}; |
| 1442 | Id ssy_flow_stack{}; | ||
| 1443 | Id pbk_flow_stack{}; | ||
| 1419 | Id continue_label{}; | 1444 | Id continue_label{}; |
| 1420 | std::map<u32, Id> labels; | 1445 | std::map<u32, Id> labels; |
| 1421 | }; | 1446 | }; |