mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 11:00:05 +00:00
shader_jit: change passing ShaderSetup to passing uniforms struct into the program
We are going to add private memebers to ShaderSetup, which forbids the usage of offsetof. The JIT program only use the uniform part of the setup, so we can just isolate it.
This commit is contained in:
parent
cb36f9fad2
commit
3cc460ab34
@ -173,27 +173,29 @@ struct GSUnitState : public UnitState {
|
||||
GSEmitter emitter;
|
||||
};
|
||||
|
||||
struct ShaderSetup {
|
||||
struct {
|
||||
// The float uniforms are accessed by the shader JIT using SSE instructions, and are
|
||||
// therefore required to be 16-byte aligned.
|
||||
alignas(16) Math::Vec4<float24> f[96];
|
||||
struct Uniforms {
|
||||
// The float uniforms are accessed by the shader JIT using SSE instructions, and are
|
||||
// therefore required to be 16-byte aligned.
|
||||
alignas(16) Math::Vec4<float24> f[96];
|
||||
|
||||
std::array<bool, 16> b;
|
||||
std::array<Math::Vec4<u8>, 4> i;
|
||||
} uniforms;
|
||||
std::array<bool, 16> b;
|
||||
std::array<Math::Vec4<u8>, 4> i;
|
||||
|
||||
static size_t GetFloatUniformOffset(unsigned index) {
|
||||
return offsetof(ShaderSetup, uniforms.f) + index * sizeof(Math::Vec4<float24>);
|
||||
return offsetof(Uniforms, f) + index * sizeof(Math::Vec4<float24>);
|
||||
}
|
||||
|
||||
static size_t GetBoolUniformOffset(unsigned index) {
|
||||
return offsetof(ShaderSetup, uniforms.b) + index * sizeof(bool);
|
||||
return offsetof(Uniforms, b) + index * sizeof(bool);
|
||||
}
|
||||
|
||||
static size_t GetIntUniformOffset(unsigned index) {
|
||||
return offsetof(ShaderSetup, uniforms.i) + index * sizeof(Math::Vec4<u8>);
|
||||
return offsetof(Uniforms, i) + index * sizeof(Math::Vec4<u8>);
|
||||
}
|
||||
};
|
||||
|
||||
struct ShaderSetup {
|
||||
Uniforms uniforms;
|
||||
|
||||
std::array<u32, MAX_PROGRAM_CODE_LENGTH> program_code;
|
||||
std::array<u32, MAX_SWIZZLE_DATA_LENGTH> swizzle_data;
|
||||
|
@ -104,7 +104,7 @@ const JitFunction instr_table[64] = {
|
||||
// purposes, as documented below:
|
||||
|
||||
/// Pointer to the uniform memory
|
||||
static const Reg64 SETUP = r9;
|
||||
static const Reg64 UNIFORMS = r9;
|
||||
/// The two 32-bit VS address offset registers set by the MOVA instruction
|
||||
static const Reg64 ADDROFFS_REG_0 = r10;
|
||||
static const Reg64 ADDROFFS_REG_1 = r11;
|
||||
@ -139,7 +139,7 @@ static const Xmm NEGBIT = xmm15;
|
||||
// Scratch registers, e.g., SRC1 and SCRATCH, have to be saved on the side if needed
|
||||
static const BitSet32 persistent_regs = BuildRegSet({
|
||||
// Pointers to register blocks
|
||||
SETUP,
|
||||
UNIFORMS,
|
||||
STATE,
|
||||
// Cached registers
|
||||
ADDROFFS_REG_0,
|
||||
@ -184,8 +184,8 @@ void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRe
|
||||
size_t src_offset;
|
||||
|
||||
if (src_reg.GetRegisterType() == RegisterType::FloatUniform) {
|
||||
src_ptr = SETUP;
|
||||
src_offset = ShaderSetup::GetFloatUniformOffset(src_reg.GetIndex());
|
||||
src_ptr = UNIFORMS;
|
||||
src_offset = Uniforms::GetFloatUniformOffset(src_reg.GetIndex());
|
||||
} else {
|
||||
src_ptr = STATE;
|
||||
src_offset = UnitState::InputOffset(src_reg);
|
||||
@ -354,8 +354,8 @@ void JitShader::Compile_EvaluateCondition(Instruction instr) {
|
||||
}
|
||||
|
||||
void JitShader::Compile_UniformCondition(Instruction instr) {
|
||||
size_t offset = ShaderSetup::GetBoolUniformOffset(instr.flow_control.bool_uniform_id);
|
||||
cmp(byte[SETUP + offset], 0);
|
||||
size_t offset = Uniforms::GetBoolUniformOffset(instr.flow_control.bool_uniform_id);
|
||||
cmp(byte[UNIFORMS + offset], 0);
|
||||
}
|
||||
|
||||
BitSet32 JitShader::PersistentCallerSavedRegs() {
|
||||
@ -713,8 +713,8 @@ void JitShader::Compile_LOOP(Instruction instr) {
|
||||
// This decodes the fields from the integer uniform at index instr.flow_control.int_uniform_id.
|
||||
// The Y (LOOPCOUNT_REG) and Z (LOOPINC) component are kept multiplied by 16 (Left shifted by
|
||||
// 4 bits) to be used as an offset into the 16-byte vector registers later
|
||||
size_t offset = ShaderSetup::GetIntUniformOffset(instr.flow_control.int_uniform_id);
|
||||
mov(LOOPCOUNT, dword[SETUP + offset]);
|
||||
size_t offset = Uniforms::GetIntUniformOffset(instr.flow_control.int_uniform_id);
|
||||
mov(LOOPCOUNT, dword[UNIFORMS + offset]);
|
||||
mov(LOOPCOUNT_REG, LOOPCOUNT);
|
||||
shr(LOOPCOUNT_REG, 4);
|
||||
and_(LOOPCOUNT_REG, 0xFF0); // Y-component is the start
|
||||
@ -882,7 +882,7 @@ void JitShader::Compile(const std::array<u32, MAX_PROGRAM_CODE_LENGTH>* program_
|
||||
ABI_PushRegistersAndAdjustStack(*this, ABI_ALL_CALLEE_SAVED, 8, 16);
|
||||
mov(qword[rsp + 8], 0xFFFFFFFFFFFFFFFFULL);
|
||||
|
||||
mov(SETUP, ABI_PARAM1);
|
||||
mov(UNIFORMS, ABI_PARAM1);
|
||||
mov(STATE, ABI_PARAM2);
|
||||
|
||||
// Zero address/loop registers
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
JitShader();
|
||||
|
||||
void Run(const ShaderSetup& setup, UnitState& state, unsigned offset) const {
|
||||
program(&setup, &state, instruction_labels[offset].getAddress());
|
||||
program(&setup.uniforms, &state, instruction_labels[offset].getAddress());
|
||||
}
|
||||
|
||||
void Compile(const std::array<u32, MAX_PROGRAM_CODE_LENGTH>* program_code,
|
||||
|
Loading…
Reference in New Issue
Block a user