yuzu-emu
/
yuzu
Archived
1
0
Fork 0

Merge pull request #1083 from Subv/conv_neg

Shaders: Implemented I2F_C and F2I_C, along with the negation bits of the conversion instructions.
This commit is contained in:
bunnei 2018-08-15 18:24:47 -04:00 committed by GitHub
commit a2fa37b499
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 56 additions and 16 deletions

View File

@ -367,20 +367,23 @@ public:
} }
/// Generates code representing a uniform (C buffer) register, interpreted as the input type. /// Generates code representing a uniform (C buffer) register, interpreted as the input type.
std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type,
Register::Size size = Register::Size::Word) {
declr_const_buffers[index].MarkAsUsed(index, offset, stage); declr_const_buffers[index].MarkAsUsed(index, offset, stage);
std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" +
std::to_string(offset % 4) + ']'; std::to_string(offset % 4) + ']';
if (type == GLSLRegister::Type::Float) { if (type == GLSLRegister::Type::Float) {
return value; // Do nothing, default
} else if (type == GLSLRegister::Type::Integer) { } else if (type == GLSLRegister::Type::Integer) {
return "floatBitsToInt(" + value + ')'; value = "floatBitsToInt(" + value + ')';
} else if (type == GLSLRegister::Type::UnsignedInteger) { } else if (type == GLSLRegister::Type::UnsignedInteger) {
return "floatBitsToUint(" + value + ')'; value = "floatBitsToUint(" + value + ')';
} else { } else {
UNREACHABLE(); UNREACHABLE();
} }
return ConvertIntegerSize(value, size);
} }
std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str, std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str,
@ -1247,20 +1250,41 @@ private:
op_a = "abs(" + op_a + ')'; op_a = "abs(" + op_a + ')';
} }
if (instr.conversion.negate_a) {
op_a = "-(" + op_a + ')';
}
regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
1, instr.alu.saturate_d, 0, instr.conversion.dest_size); 1, instr.alu.saturate_d, 0, instr.conversion.dest_size);
break; break;
} }
case OpCode::Id::I2F_R: { case OpCode::Id::I2F_R:
case OpCode::Id::I2F_C: {
ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented");
ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); ASSERT_MSG(!instr.conversion.selector, "Unimplemented");
std::string op_a = regs.GetRegisterAsInteger(
instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size); std::string op_a{};
if (instr.is_b_gpr) {
op_a =
regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed,
instr.conversion.src_size);
} else {
op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
instr.conversion.is_input_signed
? GLSLRegister::Type::Integer
: GLSLRegister::Type::UnsignedInteger,
instr.conversion.src_size);
}
if (instr.conversion.abs_a) { if (instr.conversion.abs_a) {
op_a = "abs(" + op_a + ')'; op_a = "abs(" + op_a + ')';
} }
if (instr.conversion.negate_a) {
op_a = "-(" + op_a + ')';
}
regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
break; break;
} }
@ -1269,6 +1293,14 @@ private:
ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented");
std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
if (instr.conversion.abs_a) {
op_a = "abs(" + op_a + ')';
}
if (instr.conversion.negate_a) {
op_a = "-(" + op_a + ')';
}
switch (instr.conversion.f2f.rounding) { switch (instr.conversion.f2f.rounding) {
case Tegra::Shader::F2fRoundingOp::None: case Tegra::Shader::F2fRoundingOp::None:
break; break;
@ -1291,19 +1323,27 @@ private:
break; break;
} }
regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d);
break;
}
case OpCode::Id::F2I_R:
case OpCode::Id::F2I_C: {
ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented");
std::string op_a{};
if (instr.is_b_gpr) {
op_a = regs.GetRegisterAsFloat(instr.gpr20);
} else {
op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
GLSLRegister::Type::Float);
}
if (instr.conversion.abs_a) { if (instr.conversion.abs_a) {
op_a = "abs(" + op_a + ')'; op_a = "abs(" + op_a + ')';
} }
regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); if (instr.conversion.negate_a) {
break; op_a = "-(" + op_a + ')';
}
case OpCode::Id::F2I_R: {
ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented");
std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
if (instr.conversion.abs_a) {
op_a = "abs(" + op_a + ')';
} }
switch (instr.conversion.f2i.rounding) { switch (instr.conversion.f2i.rounding) {