MCPcopy Create free account
hub / github.com/RPCSX/rpcsx / analyse_vertex_program

Method analyse_vertex_program

rpcs3/Emu/RSX/Program/ProgramStateCache.cpp:135–422  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

133}
134
135vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vertex_program(const u32* data, u32 entry, RSXVertexProgram& dst_prog)
136{
137 vertex_program_utils::vertex_program_metadata result{};
138 // u32 last_instruction_address = 0;
139 // u32 first_instruction_address = entry;
140
141 std::bitset<rsx::max_vertex_program_instructions> instructions_to_patch;
142 std::pair<u32, u32> instruction_range{umax, 0};
143 bool has_branch_instruction = false;
144 std::stack<u32> call_stack;
145
146 D3 d3{};
147 D2 d2{};
148 D1 d1{};
149 D0 d0{};
150
151 std::function<void(u32, bool)> walk_function = [&](u32 start, bool fast_exit)
152 {
153 u32 current_instruction = start;
154 std::set<u32> conditional_targets;
155
156 while (true)
157 {
158 ensure(current_instruction < rsx::max_vertex_program_instructions);
159
160 if (result.instruction_mask[current_instruction])
161 {
162 if (!fast_exit)
163 {
164 // This can be harmless if a dangling RET was encountered before.
165 // This can also be legal in case of BRB...BRI loops since BRIs are conditional. Might just be a loop with exit cond.
166 rsx_log.warning("vp_analyser: Possible infinite loop detected");
167 }
168
169 // There is never any reason to continue scanning after self-intersecting on the control-flow tree.
170 break;
171 }
172
173 const auto instruction = v128::loadu(&data[current_instruction * 4]);
174 d1.HEX = instruction._u32[1];
175 d2.HEX = instruction._u32[2];
176 d3.HEX = instruction._u32[3];
177
178 // Touch current instruction
179 result.instruction_mask[current_instruction] = true;
180 instruction_range.first = std::min(current_instruction, instruction_range.first);
181 instruction_range.second = std::max(current_instruction, instruction_range.second);
182
183 // Whether to check if the current instruction references an input stream
184 auto input_attribute_ref = [&]()
185 {
186 if (!d1.input_src)
187 {
188 // It is possible to reference ATTR0, but this is mandatory anyway. No need to explicitly test for it
189 return;
190 }
191
192 const auto ref_mask = (1u << d1.input_src);

Callers

nothing calls this directly

Calls 15

loaduFunction · 0.85
maxFunction · 0.85
get_cache_dirFunction · 0.85
storeuFunction · 0.85
errorMethod · 0.80
ensureFunction · 0.50
pushMethod · 0.45
emplaceMethod · 0.45
emptyMethod · 0.45
popMethod · 0.45
writeMethod · 0.45
closeMethod · 0.45

Tested by

no test coverage detected