summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-06-02 18:52:07 -0300
committerGravatar ReinUsesLisp2019-06-07 02:18:27 -0300
commitfe8e6618f2907a9262d69232ef0e2d5d58cbc6e0 (patch)
tree308d278996e18558ab049daa01b4873b08b799e8 /src/video_core/renderer_vulkan
parentMerge pull request #2558 from ReinUsesLisp/shader-nodes (diff)
downloadyuzu-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.cpp49
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};