diff --git a/src/video_core/pica/shader_unit.cpp b/src/video_core/pica/shader_unit.cpp index 5d81f857a..725dd9ebb 100644 --- a/src/video_core/pica/shader_unit.cpp +++ b/src/video_core/pica/shader_unit.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -29,15 +29,15 @@ void ShaderUnit::WriteOutput(const ShaderRegs& config, AttributeBuffer& buffer) } void GeometryEmitter::Emit(std::span, 16> output_regs) { - ASSERT(vertex_id < 3); + ASSERT(emit_state.vertex_id < 3); u32 output_index{}; for (u32 reg : Common::BitSet(output_mask)) { - buffer[vertex_id][output_index++] = output_regs[reg]; + buffer[emit_state.vertex_id][output_index++] = output_regs[reg]; } - if (prim_emit) { - if (winding) { + if (emit_state.prim_emit) { + if (emit_state.winding) { handlers->winding_setter(); } for (std::size_t i = 0; i < buffer.size(); ++i) { diff --git a/src/video_core/pica/shader_unit.h b/src/video_core/pica/shader_unit.h index 2f9c1843f..80eea8d23 100644 --- a/src/video_core/pica/shader_unit.h +++ b/src/video_core/pica/shader_unit.h @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -75,11 +75,18 @@ struct GeometryEmitter { void Emit(std::span, 16> output_regs); public: - std::array buffer; - u8 vertex_id; - bool prim_emit; - bool winding; + union EmitState { + struct { + bool winding : 1; + bool prim_emit : 1; + u8 vertex_id : 2; + }; + u8 raw; + } emit_state; + static_assert(sizeof(emit_state) == 1); + u32 output_mask; + std::array buffer; Handlers* handlers; private: @@ -87,9 +94,7 @@ private: template void serialize(Archive& ar, const u32 file_version) { ar & buffer; - ar & vertex_id; - ar & prim_emit; - ar & winding; + ar & emit_state.raw; ar & output_mask; } }; diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp index cb06a62bc..6d373e28f 100644 --- a/src/video_core/shader/shader_interpreter.cpp +++ b/src/video_core/shader/shader_interpreter.cpp @@ -671,9 +671,9 @@ static void RunInterpreter(const ShaderSetup& setup, ShaderUnit& state, case OpCode::Id::SETEMIT: { auto* emitter = state.emitter_ptr; ASSERT_MSG(emitter, "Execute SETEMIT on VS"); - emitter->vertex_id = instr.setemit.vertex_id; - emitter->prim_emit = instr.setemit.prim_emit != 0; - emitter->winding = instr.setemit.winding != 0; + emitter->emit_state.vertex_id = instr.setemit.vertex_id; + emitter->emit_state.prim_emit = instr.setemit.prim_emit != 0; + emitter->emit_state.winding = instr.setemit.winding != 0; break; } diff --git a/src/video_core/shader/shader_jit_a64_compiler.cpp b/src/video_core/shader/shader_jit_a64_compiler.cpp index 636d9cb57..90c8425bc 100644 --- a/src/video_core/shader/shader_jit_a64_compiler.cpp +++ b/src/video_core/shader/shader_jit_a64_compiler.cpp @@ -865,12 +865,13 @@ void JitShader::Compile_SETE(Instruction instr) { l(have_emitter); - MOV(XSCRATCH1.toW(), instr.setemit.vertex_id); - STRB(XSCRATCH1.toW(), XSCRATCH0, u32(offsetof(GeometryEmitter, vertex_id))); - MOV(XSCRATCH1.toW(), instr.setemit.prim_emit); - STRB(XSCRATCH1.toW(), XSCRATCH0, u32(offsetof(GeometryEmitter, prim_emit))); - MOV(XSCRATCH1.toW(), instr.setemit.winding); - STRB(XSCRATCH1.toW(), XSCRATCH0, u32(offsetof(GeometryEmitter, winding))); + const GeometryEmitter::EmitState new_state{ + .winding = instr.setemit.winding != 0, + .prim_emit = instr.setemit.prim_emit != 0, + .vertex_id = static_cast(instr.setemit.vertex_id), + }; + MOV(XSCRATCH1.toW(), new_state.raw); + STRB(XSCRATCH1.toW(), XSCRATCH0, u32(offsetof(GeometryEmitter, emit_state))); l(end); } diff --git a/src/video_core/shader/shader_jit_x64_compiler.cpp b/src/video_core/shader/shader_jit_x64_compiler.cpp index 84cdc09bc..1c1ff92b2 100644 --- a/src/video_core/shader/shader_jit_x64_compiler.cpp +++ b/src/video_core/shader/shader_jit_x64_compiler.cpp @@ -905,9 +905,12 @@ void JitShader::Compile_SETE(Instruction instr) { jmp(end); L(have_emitter); - mov(byte[rax + offsetof(GeometryEmitter, vertex_id)], instr.setemit.vertex_id); - mov(byte[rax + offsetof(GeometryEmitter, prim_emit)], instr.setemit.prim_emit); - mov(byte[rax + offsetof(GeometryEmitter, winding)], instr.setemit.winding); + const GeometryEmitter::EmitState new_state{ + .winding = instr.setemit.winding != 0, + .prim_emit = instr.setemit.prim_emit != 0, + .vertex_id = static_cast(instr.setemit.vertex_id), + }; + mov(byte[rax + offsetof(GeometryEmitter, emit_state)], new_state.raw); L(end); }