diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index dabf98b74..e0dfdbb9f 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -367,20 +367,23 @@ public: | |||
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | /// Generates code representing a uniform (C buffer) register, interpreted as the input type. | 369 | /// Generates code representing a uniform (C buffer) register, interpreted as the input type. |
| 370 | std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { | 370 | std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type, |
| 371 | Register::Size size = Register::Size::Word) { | ||
| 371 | declr_const_buffers[index].MarkAsUsed(index, offset, stage); | 372 | declr_const_buffers[index].MarkAsUsed(index, offset, stage); |
| 372 | std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + | 373 | std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + |
| 373 | std::to_string(offset % 4) + ']'; | 374 | std::to_string(offset % 4) + ']'; |
| 374 | 375 | ||
| 375 | if (type == GLSLRegister::Type::Float) { | 376 | if (type == GLSLRegister::Type::Float) { |
| 376 | return value; | 377 | // Do nothing, default |
| 377 | } else if (type == GLSLRegister::Type::Integer) { | 378 | } else if (type == GLSLRegister::Type::Integer) { |
| 378 | return "floatBitsToInt(" + value + ')'; | 379 | value = "floatBitsToInt(" + value + ')'; |
| 379 | } else if (type == GLSLRegister::Type::UnsignedInteger) { | 380 | } else if (type == GLSLRegister::Type::UnsignedInteger) { |
| 380 | return "floatBitsToUint(" + value + ')'; | 381 | value = "floatBitsToUint(" + value + ')'; |
| 381 | } else { | 382 | } else { |
| 382 | UNREACHABLE(); | 383 | UNREACHABLE(); |
| 383 | } | 384 | } |
| 385 | |||
| 386 | return ConvertIntegerSize(value, size); | ||
| 384 | } | 387 | } |
| 385 | 388 | ||
| 386 | std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str, | 389 | std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str, |
| @@ -1247,20 +1250,41 @@ private: | |||
| 1247 | op_a = "abs(" + op_a + ')'; | 1250 | op_a = "abs(" + op_a + ')'; |
| 1248 | } | 1251 | } |
| 1249 | 1252 | ||
| 1253 | if (instr.conversion.negate_a) { | ||
| 1254 | op_a = "-(" + op_a + ')'; | ||
| 1255 | } | ||
| 1256 | |||
| 1250 | regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, | 1257 | regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, |
| 1251 | 1, instr.alu.saturate_d, 0, instr.conversion.dest_size); | 1258 | 1, instr.alu.saturate_d, 0, instr.conversion.dest_size); |
| 1252 | break; | 1259 | break; |
| 1253 | } | 1260 | } |
| 1254 | case OpCode::Id::I2F_R: { | 1261 | case OpCode::Id::I2F_R: |
| 1262 | case OpCode::Id::I2F_C: { | ||
| 1255 | ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); | 1263 | ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); |
| 1256 | ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); | 1264 | ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); |
| 1257 | std::string op_a = regs.GetRegisterAsInteger( | 1265 | |
| 1258 | instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size); | 1266 | std::string op_a{}; |
| 1267 | |||
| 1268 | if (instr.is_b_gpr) { | ||
| 1269 | op_a = | ||
| 1270 | regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed, | ||
| 1271 | instr.conversion.src_size); | ||
| 1272 | } else { | ||
| 1273 | op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, | ||
| 1274 | instr.conversion.is_input_signed | ||
| 1275 | ? GLSLRegister::Type::Integer | ||
| 1276 | : GLSLRegister::Type::UnsignedInteger, | ||
| 1277 | instr.conversion.src_size); | ||
| 1278 | } | ||
| 1259 | 1279 | ||
| 1260 | if (instr.conversion.abs_a) { | 1280 | if (instr.conversion.abs_a) { |
| 1261 | op_a = "abs(" + op_a + ')'; | 1281 | op_a = "abs(" + op_a + ')'; |
| 1262 | } | 1282 | } |
| 1263 | 1283 | ||
| 1284 | if (instr.conversion.negate_a) { | ||
| 1285 | op_a = "-(" + op_a + ')'; | ||
| 1286 | } | ||
| 1287 | |||
| 1264 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | 1288 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |
| 1265 | break; | 1289 | break; |
| 1266 | } | 1290 | } |
| @@ -1269,6 +1293,14 @@ private: | |||
| 1269 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); | 1293 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); |
| 1270 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); | 1294 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); |
| 1271 | 1295 | ||
| 1296 | if (instr.conversion.abs_a) { | ||
| 1297 | op_a = "abs(" + op_a + ')'; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | if (instr.conversion.negate_a) { | ||
| 1301 | op_a = "-(" + op_a + ')'; | ||
| 1302 | } | ||
| 1303 | |||
| 1272 | switch (instr.conversion.f2f.rounding) { | 1304 | switch (instr.conversion.f2f.rounding) { |
| 1273 | case Tegra::Shader::F2fRoundingOp::None: | 1305 | case Tegra::Shader::F2fRoundingOp::None: |
| 1274 | break; | 1306 | break; |
| @@ -1291,21 +1323,29 @@ private: | |||
| 1291 | break; | 1323 | break; |
| 1292 | } | 1324 | } |
| 1293 | 1325 | ||
| 1294 | if (instr.conversion.abs_a) { | ||
| 1295 | op_a = "abs(" + op_a + ')'; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); | 1326 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); |
| 1299 | break; | 1327 | break; |
| 1300 | } | 1328 | } |
| 1301 | case OpCode::Id::F2I_R: { | 1329 | case OpCode::Id::F2I_R: |
| 1330 | case OpCode::Id::F2I_C: { | ||
| 1302 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); | 1331 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); |
| 1303 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); | 1332 | std::string op_a{}; |
| 1333 | |||
| 1334 | if (instr.is_b_gpr) { | ||
| 1335 | op_a = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 1336 | } else { | ||
| 1337 | op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, | ||
| 1338 | GLSLRegister::Type::Float); | ||
| 1339 | } | ||
| 1304 | 1340 | ||
| 1305 | if (instr.conversion.abs_a) { | 1341 | if (instr.conversion.abs_a) { |
| 1306 | op_a = "abs(" + op_a + ')'; | 1342 | op_a = "abs(" + op_a + ')'; |
| 1307 | } | 1343 | } |
| 1308 | 1344 | ||
| 1345 | if (instr.conversion.negate_a) { | ||
| 1346 | op_a = "-(" + op_a + ')'; | ||
| 1347 | } | ||
| 1348 | |||
| 1309 | switch (instr.conversion.f2i.rounding) { | 1349 | switch (instr.conversion.f2i.rounding) { |
| 1310 | case Tegra::Shader::F2iRoundingOp::None: | 1350 | case Tegra::Shader::F2iRoundingOp::None: |
| 1311 | break; | 1351 | break; |