|
@@ -20,7 +20,6 @@ using Tegra::Shader::OpCode;
|
|
|
using Tegra::Shader::Register;
|
|
using Tegra::Shader::Register;
|
|
|
using Tegra::Shader::Sampler;
|
|
using Tegra::Shader::Sampler;
|
|
|
using Tegra::Shader::SubOp;
|
|
using Tegra::Shader::SubOp;
|
|
|
-using Tegra::Shader::Uniform;
|
|
|
|
|
|
|
|
|
|
constexpr u32 PROGRAM_END = MAX_PROGRAM_CODE_LENGTH;
|
|
constexpr u32 PROGRAM_END = MAX_PROGRAM_CODE_LENGTH;
|
|
|
|
|
|
|
@@ -365,11 +364,9 @@ 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(const Uniform& uniform, GLSLRegister::Type type) {
|
|
|
|
|
- declr_const_buffers[uniform.index].MarkAsUsed(static_cast<unsigned>(uniform.index),
|
|
|
|
|
- static_cast<unsigned>(uniform.offset), stage);
|
|
|
|
|
- std::string value =
|
|
|
|
|
- 'c' + std::to_string(uniform.index) + '[' + std::to_string(uniform.offset) + ']';
|
|
|
|
|
|
|
+ std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) {
|
|
|
|
|
+ declr_const_buffers[index].MarkAsUsed(index, offset, stage);
|
|
|
|
|
+ std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset) + ']';
|
|
|
|
|
|
|
|
if (type == GLSLRegister::Type::Float) {
|
|
if (type == GLSLRegister::Type::Float) {
|
|
|
return value;
|
|
return value;
|
|
@@ -380,10 +377,19 @@ public:
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /// Generates code representing a uniform (C buffer) register, interpreted as the type of the
|
|
|
|
|
- /// destination register.
|
|
|
|
|
- std::string GetUniform(const Uniform& uniform, const Register& dest_reg) {
|
|
|
|
|
- return GetUniform(uniform, regs[dest_reg].GetActiveType());
|
|
|
|
|
|
|
+ std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg,
|
|
|
|
|
+ GLSLRegister::Type type) {
|
|
|
|
|
+ declr_const_buffers[index].MarkAsUsedIndirect(index, stage);
|
|
|
|
|
+ std::string value = 'c' + std::to_string(index) + "[(floatBitsToInt(" +
|
|
|
|
|
+ GetRegister(index_reg, 0) + ") + " + std::to_string(offset) + ") / 4]";
|
|
|
|
|
+
|
|
|
|
|
+ if (type == GLSLRegister::Type::Float) {
|
|
|
|
|
+ return value;
|
|
|
|
|
+ } else if (type == GLSLRegister::Type::Integer) {
|
|
|
|
|
+ return "floatBitsToInt(" + value + ')';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ UNREACHABLE();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Add declarations for registers
|
|
/// Add declarations for registers
|
|
@@ -747,7 +753,8 @@ private:
|
|
|
if (instr.is_b_gpr) {
|
|
if (instr.is_b_gpr) {
|
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr20);
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr20);
|
|
|
} else {
|
|
} else {
|
|
|
- op_b += regs.GetUniform(instr.uniform, instr.gpr0);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -904,7 +911,8 @@ private:
|
|
|
if (instr.is_b_gpr) {
|
|
if (instr.is_b_gpr) {
|
|
|
op_b += regs.GetRegisterAsInteger(instr.gpr20);
|
|
op_b += regs.GetRegisterAsInteger(instr.gpr20);
|
|
|
} else {
|
|
} else {
|
|
|
- op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Integer);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -936,7 +944,8 @@ private:
|
|
|
if (instr.is_b_gpr) {
|
|
if (instr.is_b_gpr) {
|
|
|
op_b += regs.GetRegisterAsInteger(instr.gpr20);
|
|
op_b += regs.GetRegisterAsInteger(instr.gpr20);
|
|
|
} else {
|
|
} else {
|
|
|
- op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Integer);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -953,7 +962,8 @@ private:
|
|
|
|
|
|
|
|
switch (opcode->GetId()) {
|
|
switch (opcode->GetId()) {
|
|
|
case OpCode::Id::FFMA_CR: {
|
|
case OpCode::Id::FFMA_CR: {
|
|
|
- op_b += regs.GetUniform(instr.uniform, instr.gpr0);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
op_c += regs.GetRegisterAsFloat(instr.gpr39);
|
|
op_c += regs.GetRegisterAsFloat(instr.gpr39);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -964,7 +974,8 @@ private:
|
|
|
}
|
|
}
|
|
|
case OpCode::Id::FFMA_RC: {
|
|
case OpCode::Id::FFMA_RC: {
|
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr39);
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr39);
|
|
|
- op_c += regs.GetUniform(instr.uniform, instr.gpr0);
|
|
|
|
|
|
|
+ op_c += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
case OpCode::Id::FFMA_IMM: {
|
|
case OpCode::Id::FFMA_IMM: {
|
|
@@ -1079,6 +1090,33 @@ private:
|
|
|
attribute);
|
|
attribute);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+ case OpCode::Id::LD_C: {
|
|
|
|
|
+ ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented");
|
|
|
|
|
+
|
|
|
|
|
+ std::string op_a =
|
|
|
|
|
+ regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, instr.gpr8,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
|
|
+ std::string op_b =
|
|
|
|
|
+ regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, instr.gpr8,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
|
|
+
|
|
|
|
|
+ switch (instr.ld_c.type.Value()) {
|
|
|
|
|
+ case Tegra::Shader::UniformType::Single:
|
|
|
|
|
+ regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case Tegra::Shader::UniformType::Double:
|
|
|
|
|
+ regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
|
|
|
|
|
+ regs.SetRegisterToFloat(instr.gpr0.Value() + 1, 0, op_b, 1, 1);
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ default:
|
|
|
|
|
+ NGLOG_CRITICAL(HW_GPU, "Unhandled type: {}",
|
|
|
|
|
+ static_cast<unsigned>(instr.ld_c.type.Value()));
|
|
|
|
|
+ UNREACHABLE();
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
case OpCode::Id::ST_A: {
|
|
case OpCode::Id::ST_A: {
|
|
|
ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested");
|
|
ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested");
|
|
|
regs.SetOutputAttributeToRegister(attribute, instr.attribute.fmt20.element,
|
|
regs.SetOutputAttributeToRegister(attribute, instr.attribute.fmt20.element,
|
|
@@ -1175,7 +1213,8 @@ private:
|
|
|
if (instr.is_b_gpr) {
|
|
if (instr.is_b_gpr) {
|
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr20);
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr20);
|
|
|
} else {
|
|
} else {
|
|
|
- op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Float);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1216,7 +1255,8 @@ private:
|
|
|
if (instr.is_b_gpr) {
|
|
if (instr.is_b_gpr) {
|
|
|
op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.isetp.is_signed);
|
|
op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.isetp.is_signed);
|
|
|
} else {
|
|
} else {
|
|
|
- op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Integer);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
using Tegra::Shader::Pred;
|
|
using Tegra::Shader::Pred;
|
|
@@ -1262,7 +1302,8 @@ private:
|
|
|
if (instr.is_b_gpr) {
|
|
if (instr.is_b_gpr) {
|
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr20);
|
|
op_b += regs.GetRegisterAsFloat(instr.gpr20);
|
|
|
} else {
|
|
} else {
|
|
|
- op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Float);
|
|
|
|
|
|
|
+ op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
|
|
|
|
|
+ GLSLRegister::Type::Float);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|