|
|
@ -73,19 +73,13 @@ struct OutputVertex {
|
|
|
|
ret.Lerp(factor, v1);
|
|
|
|
ret.Lerp(factor, v1);
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static OutputVertex FromRegisters(Math::Vec4<float24> output_regs[16], const Regs& regs,
|
|
|
|
|
|
|
|
u32 output_mask);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");
|
|
|
|
static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");
|
|
|
|
static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size");
|
|
|
|
static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size");
|
|
|
|
|
|
|
|
|
|
|
|
struct OutputRegisters {
|
|
|
|
|
|
|
|
OutputRegisters() = default;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
alignas(16) Math::Vec4<float24> value[16];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OutputVertex ToVertex(const Regs::ShaderConfig& config) const;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
static_assert(std::is_pod<OutputRegisters>::value, "Structure is not POD");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* This structure contains the state information that needs to be unique for a shader unit. The 3DS
|
|
|
|
* This structure contains the state information that needs to be unique for a shader unit. The 3DS
|
|
|
|
* has four shader units that process shaders in parallel. At the present, Citra only implements a
|
|
|
|
* has four shader units that process shaders in parallel. At the present, Citra only implements a
|
|
|
@ -98,11 +92,10 @@ struct UnitState {
|
|
|
|
// required to be 16-byte aligned.
|
|
|
|
// required to be 16-byte aligned.
|
|
|
|
alignas(16) Math::Vec4<float24> input[16];
|
|
|
|
alignas(16) Math::Vec4<float24> input[16];
|
|
|
|
alignas(16) Math::Vec4<float24> temporary[16];
|
|
|
|
alignas(16) Math::Vec4<float24> temporary[16];
|
|
|
|
|
|
|
|
alignas(16) Math::Vec4<float24> output[16];
|
|
|
|
} registers;
|
|
|
|
} registers;
|
|
|
|
static_assert(std::is_pod<Registers>::value, "Structure is not POD");
|
|
|
|
static_assert(std::is_pod<Registers>::value, "Structure is not POD");
|
|
|
|
|
|
|
|
|
|
|
|
OutputRegisters output_registers;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool conditional_code[2];
|
|
|
|
bool conditional_code[2];
|
|
|
|
|
|
|
|
|
|
|
|
// Two Address registers and one loop counter
|
|
|
|
// Two Address registers and one loop counter
|
|
|
@ -128,7 +121,7 @@ struct UnitState {
|
|
|
|
static size_t OutputOffset(const DestRegister& reg) {
|
|
|
|
static size_t OutputOffset(const DestRegister& reg) {
|
|
|
|
switch (reg.GetRegisterType()) {
|
|
|
|
switch (reg.GetRegisterType()) {
|
|
|
|
case RegisterType::Output:
|
|
|
|
case RegisterType::Output:
|
|
|
|
return offsetof(UnitState, output_registers.value) +
|
|
|
|
return offsetof(UnitState, registers.output) +
|
|
|
|
reg.GetIndex() * sizeof(Math::Vec4<float24>);
|
|
|
|
reg.GetIndex() * sizeof(Math::Vec4<float24>);
|
|
|
|
|
|
|
|
|
|
|
|
case RegisterType::Temporary:
|
|
|
|
case RegisterType::Temporary:
|
|
|
|