vertex_shader.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <stack>
  5. #include <boost/range/algorithm.hpp>
  6. #include <common/file_util.h>
  7. #include <core/mem_map.h>
  8. #include <nihstro/shader_bytecode.h>
  9. #include "pica.h"
  10. #include "vertex_shader.h"
  11. #include "debug_utils/debug_utils.h"
  12. using nihstro::Instruction;
  13. using nihstro::RegisterType;
  14. using nihstro::SourceRegister;
  15. using nihstro::SwizzlePattern;
  16. namespace Pica {
  17. namespace VertexShader {
  18. static struct {
  19. Math::Vec4<float24> f[96];
  20. std::array<bool,16> b;
  21. } shader_uniforms;
  22. // TODO: Not sure where the shader binary and swizzle patterns are supposed to be loaded to!
  23. // For now, we just keep these local arrays around.
  24. static std::array<u32, 1024> shader_memory;
  25. static std::array<u32, 1024> swizzle_data;
  26. void SubmitShaderMemoryChange(u32 addr, u32 value)
  27. {
  28. shader_memory[addr] = value;
  29. }
  30. void SubmitSwizzleDataChange(u32 addr, u32 value)
  31. {
  32. swizzle_data[addr] = value;
  33. }
  34. Math::Vec4<float24>& GetFloatUniform(u32 index)
  35. {
  36. return shader_uniforms.f[index];
  37. }
  38. bool& GetBoolUniform(u32 index)
  39. {
  40. return shader_uniforms.b[index];
  41. }
  42. const std::array<u32, 1024>& GetShaderBinary()
  43. {
  44. return shader_memory;
  45. }
  46. const std::array<u32, 1024>& GetSwizzlePatterns()
  47. {
  48. return swizzle_data;
  49. }
  50. struct VertexShaderState {
  51. u32* program_counter;
  52. const float24* input_register_table[16];
  53. float24* output_register_table[7*4];
  54. Math::Vec4<float24> temporary_registers[16];
  55. bool conditional_code[2];
  56. // Two Address registers and one loop counter
  57. // TODO: How many bits do these actually have?
  58. s32 address_registers[3];
  59. enum {
  60. INVALID_ADDRESS = 0xFFFFFFFF
  61. };
  62. struct CallStackElement {
  63. u32 final_address;
  64. u32 return_address;
  65. };
  66. // TODO: Is there a maximal size for this?
  67. std::stack<CallStackElement> call_stack;
  68. struct {
  69. u32 max_offset; // maximum program counter ever reached
  70. u32 max_opdesc_id; // maximum swizzle pattern index ever used
  71. } debug;
  72. };
  73. static void ProcessShaderCode(VertexShaderState& state) {
  74. // Placeholder for invalid inputs
  75. static float24 dummy_vec4_float24[4];
  76. while (true) {
  77. if (!state.call_stack.empty()) {
  78. if (state.program_counter - shader_memory.data() == state.call_stack.top().final_address) {
  79. state.program_counter = &shader_memory[state.call_stack.top().return_address];
  80. state.call_stack.pop();
  81. // TODO: Is "trying again" accurate to hardware?
  82. continue;
  83. }
  84. }
  85. bool exit_loop = false;
  86. const Instruction& instr = *(const Instruction*)state.program_counter;
  87. const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.common.operand_desc_id];
  88. auto call = [&](VertexShaderState& state, u32 offset, u32 num_instructions, u32 return_offset) {
  89. state.program_counter = &shader_memory[offset] - 1; // -1 to make sure when incrementing the PC we end up at the correct offset
  90. state.call_stack.push({ offset + num_instructions, return_offset });
  91. };
  92. u32 binary_offset = state.program_counter - shader_memory.data();
  93. state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + binary_offset);
  94. auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* {
  95. switch (source_reg.GetRegisterType()) {
  96. case RegisterType::Input:
  97. return state.input_register_table[source_reg.GetIndex()];
  98. case RegisterType::Temporary:
  99. return &state.temporary_registers[source_reg.GetIndex()].x;
  100. case RegisterType::FloatUniform:
  101. return &shader_uniforms.f[source_reg.GetIndex()].x;
  102. default:
  103. return dummy_vec4_float24;
  104. }
  105. };
  106. switch (instr.opcode.GetInfo().type) {
  107. case Instruction::OpCodeType::Arithmetic:
  108. {
  109. bool is_inverted = 0 != (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::SrcInversed);
  110. if (is_inverted) {
  111. // TODO: We don't really support this properly: For instance, the address register
  112. // offset needs to be applied to SRC2 instead, etc.
  113. // For now, we just abort in this situation.
  114. LOG_CRITICAL(HW_GPU, "Bad condition...");
  115. exit(0);
  116. }
  117. const int address_offset = (instr.common.address_register_index == 0)
  118. ? 0 : state.address_registers[instr.common.address_register_index - 1];
  119. const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + address_offset);
  120. const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted));
  121. const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
  122. const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
  123. float24 src1[4] = {
  124. src1_[(int)swizzle.GetSelectorSrc1(0)],
  125. src1_[(int)swizzle.GetSelectorSrc1(1)],
  126. src1_[(int)swizzle.GetSelectorSrc1(2)],
  127. src1_[(int)swizzle.GetSelectorSrc1(3)],
  128. };
  129. if (negate_src1) {
  130. src1[0] = src1[0] * float24::FromFloat32(-1);
  131. src1[1] = src1[1] * float24::FromFloat32(-1);
  132. src1[2] = src1[2] * float24::FromFloat32(-1);
  133. src1[3] = src1[3] * float24::FromFloat32(-1);
  134. }
  135. float24 src2[4] = {
  136. src2_[(int)swizzle.GetSelectorSrc2(0)],
  137. src2_[(int)swizzle.GetSelectorSrc2(1)],
  138. src2_[(int)swizzle.GetSelectorSrc2(2)],
  139. src2_[(int)swizzle.GetSelectorSrc2(3)],
  140. };
  141. if (negate_src2) {
  142. src2[0] = src2[0] * float24::FromFloat32(-1);
  143. src2[1] = src2[1] * float24::FromFloat32(-1);
  144. src2[2] = src2[2] * float24::FromFloat32(-1);
  145. src2[3] = src2[3] * float24::FromFloat32(-1);
  146. }
  147. float24* dest = (instr.common.dest < 0x08) ? state.output_register_table[4*instr.common.dest.GetIndex()]
  148. : (instr.common.dest < 0x10) ? dummy_vec4_float24
  149. : (instr.common.dest < 0x20) ? &state.temporary_registers[instr.common.dest.GetIndex()][0]
  150. : dummy_vec4_float24;
  151. state.debug.max_opdesc_id = std::max<u32>(state.debug.max_opdesc_id, 1+instr.common.operand_desc_id);
  152. switch (instr.opcode.EffectiveOpCode()) {
  153. case Instruction::OpCode::ADD:
  154. {
  155. for (int i = 0; i < 4; ++i) {
  156. if (!swizzle.DestComponentEnabled(i))
  157. continue;
  158. dest[i] = src1[i] + src2[i];
  159. }
  160. break;
  161. }
  162. case Instruction::OpCode::MUL:
  163. {
  164. for (int i = 0; i < 4; ++i) {
  165. if (!swizzle.DestComponentEnabled(i))
  166. continue;
  167. dest[i] = src1[i] * src2[i];
  168. }
  169. break;
  170. }
  171. case Instruction::OpCode::MAX:
  172. for (int i = 0; i < 4; ++i) {
  173. if (!swizzle.DestComponentEnabled(i))
  174. continue;
  175. dest[i] = std::max(src1[i], src2[i]);
  176. }
  177. break;
  178. case Instruction::OpCode::DP3:
  179. case Instruction::OpCode::DP4:
  180. {
  181. float24 dot = float24::FromFloat32(0.f);
  182. int num_components = (instr.opcode == Instruction::OpCode::DP3) ? 3 : 4;
  183. for (int i = 0; i < num_components; ++i)
  184. dot = dot + src1[i] * src2[i];
  185. for (int i = 0; i < num_components; ++i) {
  186. if (!swizzle.DestComponentEnabled(i))
  187. continue;
  188. dest[i] = dot;
  189. }
  190. break;
  191. }
  192. // Reciprocal
  193. case Instruction::OpCode::RCP:
  194. {
  195. for (int i = 0; i < 4; ++i) {
  196. if (!swizzle.DestComponentEnabled(i))
  197. continue;
  198. // TODO: Be stable against division by zero!
  199. // TODO: I think this might be wrong... we should only use one component here
  200. dest[i] = float24::FromFloat32(1.0 / src1[i].ToFloat32());
  201. }
  202. break;
  203. }
  204. // Reciprocal Square Root
  205. case Instruction::OpCode::RSQ:
  206. {
  207. for (int i = 0; i < 4; ++i) {
  208. if (!swizzle.DestComponentEnabled(i))
  209. continue;
  210. // TODO: Be stable against division by zero!
  211. // TODO: I think this might be wrong... we should only use one component here
  212. dest[i] = float24::FromFloat32(1.0 / sqrt(src1[i].ToFloat32()));
  213. }
  214. break;
  215. }
  216. case Instruction::OpCode::MOVA:
  217. {
  218. for (int i = 0; i < 2; ++i) {
  219. if (!swizzle.DestComponentEnabled(i))
  220. continue;
  221. // TODO: Figure out how the rounding is done on hardware
  222. state.address_registers[i] = static_cast<s32>(src1[i].ToFloat32());
  223. }
  224. break;
  225. }
  226. case Instruction::OpCode::MOV:
  227. {
  228. for (int i = 0; i < 4; ++i) {
  229. if (!swizzle.DestComponentEnabled(i))
  230. continue;
  231. dest[i] = src1[i];
  232. }
  233. break;
  234. }
  235. case Instruction::OpCode::CMP:
  236. for (int i = 0; i < 2; ++i) {
  237. // TODO: Can you restrict to one compare via dest masking?
  238. auto compare_op = instr.common.compare_op;
  239. auto op = (i == 0) ? compare_op.x.Value() : compare_op.y.Value();
  240. switch (op) {
  241. case compare_op.Equal:
  242. state.conditional_code[i] = (src1[i] == src2[i]);
  243. break;
  244. case compare_op.NotEqual:
  245. state.conditional_code[i] = (src1[i] != src2[i]);
  246. break;
  247. case compare_op.LessThan:
  248. state.conditional_code[i] = (src1[i] < src2[i]);
  249. break;
  250. case compare_op.LessEqual:
  251. state.conditional_code[i] = (src1[i] <= src2[i]);
  252. break;
  253. case compare_op.GreaterThan:
  254. state.conditional_code[i] = (src1[i] > src2[i]);
  255. break;
  256. case compare_op.GreaterEqual:
  257. state.conditional_code[i] = (src1[i] >= src2[i]);
  258. break;
  259. default:
  260. LOG_ERROR(HW_GPU, "Unknown compare mode %x", static_cast<int>(op));
  261. break;
  262. }
  263. }
  264. break;
  265. default:
  266. LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x",
  267. (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex);
  268. _dbg_assert_(HW_GPU, 0);
  269. break;
  270. }
  271. break;
  272. }
  273. default:
  274. // Handle each instruction on its own
  275. switch (instr.opcode) {
  276. case Instruction::OpCode::END:
  277. exit_loop = true;
  278. break;
  279. case Instruction::OpCode::CALL:
  280. call(state,
  281. instr.flow_control.dest_offset,
  282. instr.flow_control.num_instructions,
  283. binary_offset + 1);
  284. break;
  285. case Instruction::OpCode::NOP:
  286. break;
  287. case Instruction::OpCode::IFU:
  288. if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) {
  289. call(state,
  290. binary_offset + 1,
  291. instr.flow_control.dest_offset - binary_offset - 1,
  292. instr.flow_control.dest_offset + instr.flow_control.num_instructions);
  293. } else {
  294. call(state,
  295. instr.flow_control.dest_offset,
  296. instr.flow_control.num_instructions,
  297. instr.flow_control.dest_offset + instr.flow_control.num_instructions);
  298. }
  299. break;
  300. case Instruction::OpCode::IFC:
  301. {
  302. // TODO: Do we need to consider swizzlers here?
  303. auto flow_control = instr.flow_control;
  304. bool results[3] = { (bool)flow_control.refx == state.conditional_code[0],
  305. (bool)flow_control.refy == state.conditional_code[1] };
  306. switch (flow_control.op) {
  307. case flow_control.Or:
  308. results[2] = results[0] || results[1];
  309. break;
  310. case flow_control.And:
  311. results[2] = results[0] && results[1];
  312. break;
  313. case flow_control.JustX:
  314. results[2] = results[0];
  315. break;
  316. case flow_control.JustY:
  317. results[2] = results[1];
  318. break;
  319. }
  320. if (results[2]) {
  321. call(state,
  322. binary_offset + 1,
  323. instr.flow_control.dest_offset - binary_offset - 1,
  324. instr.flow_control.dest_offset + instr.flow_control.num_instructions);
  325. } else {
  326. call(state,
  327. instr.flow_control.dest_offset,
  328. instr.flow_control.num_instructions,
  329. instr.flow_control.dest_offset + instr.flow_control.num_instructions);
  330. }
  331. break;
  332. }
  333. default:
  334. LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x",
  335. (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex);
  336. break;
  337. }
  338. break;
  339. }
  340. ++state.program_counter;
  341. if (exit_loop)
  342. break;
  343. }
  344. }
  345. OutputVertex RunShader(const InputVertex& input, int num_attributes)
  346. {
  347. VertexShaderState state;
  348. const u32* main = &shader_memory[registers.vs_main_offset];
  349. state.program_counter = (u32*)main;
  350. state.debug.max_offset = 0;
  351. state.debug.max_opdesc_id = 0;
  352. // Setup input register table
  353. const auto& attribute_register_map = registers.vs_input_register_map;
  354. float24 dummy_register;
  355. boost::fill(state.input_register_table, &dummy_register);
  356. if(num_attributes > 0) state.input_register_table[attribute_register_map.attribute0_register] = &input.attr[0].x;
  357. if(num_attributes > 1) state.input_register_table[attribute_register_map.attribute1_register] = &input.attr[1].x;
  358. if(num_attributes > 2) state.input_register_table[attribute_register_map.attribute2_register] = &input.attr[2].x;
  359. if(num_attributes > 3) state.input_register_table[attribute_register_map.attribute3_register] = &input.attr[3].x;
  360. if(num_attributes > 4) state.input_register_table[attribute_register_map.attribute4_register] = &input.attr[4].x;
  361. if(num_attributes > 5) state.input_register_table[attribute_register_map.attribute5_register] = &input.attr[5].x;
  362. if(num_attributes > 6) state.input_register_table[attribute_register_map.attribute6_register] = &input.attr[6].x;
  363. if(num_attributes > 7) state.input_register_table[attribute_register_map.attribute7_register] = &input.attr[7].x;
  364. if(num_attributes > 8) state.input_register_table[attribute_register_map.attribute8_register] = &input.attr[8].x;
  365. if(num_attributes > 9) state.input_register_table[attribute_register_map.attribute9_register] = &input.attr[9].x;
  366. if(num_attributes > 10) state.input_register_table[attribute_register_map.attribute10_register] = &input.attr[10].x;
  367. if(num_attributes > 11) state.input_register_table[attribute_register_map.attribute11_register] = &input.attr[11].x;
  368. if(num_attributes > 12) state.input_register_table[attribute_register_map.attribute12_register] = &input.attr[12].x;
  369. if(num_attributes > 13) state.input_register_table[attribute_register_map.attribute13_register] = &input.attr[13].x;
  370. if(num_attributes > 14) state.input_register_table[attribute_register_map.attribute14_register] = &input.attr[14].x;
  371. if(num_attributes > 15) state.input_register_table[attribute_register_map.attribute15_register] = &input.attr[15].x;
  372. // Setup output register table
  373. OutputVertex ret;
  374. // Zero output so that attributes which aren't output won't have denormals in them, which will
  375. // slow us down later.
  376. memset(&ret, 0, sizeof(ret));
  377. for (int i = 0; i < 7; ++i) {
  378. const auto& output_register_map = registers.vs_output_attributes[i];
  379. u32 semantics[4] = {
  380. output_register_map.map_x, output_register_map.map_y,
  381. output_register_map.map_z, output_register_map.map_w
  382. };
  383. for (int comp = 0; comp < 4; ++comp)
  384. state.output_register_table[4*i+comp] = ((float24*)&ret) + semantics[comp];
  385. }
  386. state.conditional_code[0] = false;
  387. state.conditional_code[1] = false;
  388. ProcessShaderCode(state);
  389. DebugUtils::DumpShader(shader_memory.data(), state.debug.max_offset, swizzle_data.data(),
  390. state.debug.max_opdesc_id, registers.vs_main_offset,
  391. registers.vs_output_attributes);
  392. LOG_TRACE(Render_Software, "Output vertex: pos (%.2f, %.2f, %.2f, %.2f), col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f)",
  393. ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(),
  394. ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(),
  395. ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32());
  396. return ret;
  397. }
  398. } // namespace
  399. } // namespace