Skip to content

Commit

Permalink
video_core/shader: Refactor JIT-Engines into JitEngine type (#7210)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wunkolo authored Nov 26, 2023
1 parent db7b929 commit 83b329f
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 165 deletions.
2 changes: 1 addition & 1 deletion src/common/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static inline u64 ComputeStructHash64(const T& data) noexcept {
* Combines the seed parameter with the provided hash, producing a new unique hash
* Implementation from: http://boost.sourceforge.net/doc/html/boost/hash_combine.html
*/
inline u64 HashCombine(std::size_t seed, const u64 hash) {
inline u64 HashCombine(const u64 seed, const u64 hash) {
return seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}

Expand Down
6 changes: 2 additions & 4 deletions src/video_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,11 @@ add_library(video_core STATIC
shader/shader.h
shader/shader_interpreter.cpp
shader/shader_interpreter.h
shader/shader_jit_a64.cpp
shader/shader_jit.cpp
shader/shader_jit.h
shader/shader_jit_a64_compiler.cpp
shader/shader_jit_a64.h
shader/shader_jit_a64_compiler.h
shader/shader_jit_x64.cpp
shader/shader_jit_x64_compiler.cpp
shader/shader_jit_x64.h
shader/shader_jit_x64_compiler.h
texture/etc1.cpp
texture/etc1.h
Expand Down
32 changes: 14 additions & 18 deletions src/video_core/shader/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,15 @@
#include "video_core/regs_shader.h"
#include "video_core/shader/shader.h"
#include "video_core/shader/shader_interpreter.h"
#if CITRA_ARCH(x86_64)
#include "video_core/shader/shader_jit_x64.h"
#elif CITRA_ARCH(arm64)
#include "video_core/shader/shader_jit_a64.h"
#endif
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
#include "video_core/shader/shader_jit.h"
#endif // CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
#include "video_core/video_core.h"

namespace Pica::Shader {

void OutputVertex::ValidateSemantics(const RasterizerRegs& regs) {
unsigned int num_attributes = regs.vs_output_total;
u32 num_attributes = regs.vs_output_total;
ASSERT(num_attributes <= 7);
for (std::size_t attrib = 0; attrib < num_attributes; ++attrib) {
u32 output_register_map = regs.vs_output_attributes[attrib].raw;
Expand Down Expand Up @@ -54,7 +52,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs,
static_assert(sizeof(std::array<f24, 24>) == sizeof(ret),
"Struct and array have different sizes.");

unsigned int num_attributes = regs.vs_output_total & 7;
u32 num_attributes = regs.vs_output_total & 7;
for (std::size_t attrib = 0; attrib < num_attributes; ++attrib) {
const auto output_register_map = regs.vs_output_attributes[attrib];
vertex_slots_overflow[output_register_map.map_x] = input.attr[attrib][0];
Expand All @@ -65,7 +63,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs,

// The hardware takes the absolute and saturates vertex colors like this, *before* doing
// interpolation
for (unsigned i = 0; i < 4; ++i) {
for (u32 i = 0; i < 4; ++i) {
float c = std::fabs(ret.color[i].ToFloat32());
ret.color[i] = f24::FromFloat32(c < 1.0f ? c : 1.0f);
}
Expand All @@ -84,10 +82,10 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs,
}

void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input) {
const unsigned max_attribute = config.max_input_attribute_index;
const u32 max_attribute = config.max_input_attribute_index;

for (unsigned attr = 0; attr <= max_attribute; ++attr) {
unsigned reg = config.GetRegisterForAttribute(attr);
for (u32 attr = 0; attr <= max_attribute; ++attr) {
u32 reg = config.GetRegisterForAttribute(attr);
registers.input[reg] = input.attr[attr];
}
}
Expand Down Expand Up @@ -141,19 +139,17 @@ void GSUnitState::ConfigOutput(const ShaderRegs& config) {

MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240));

#if CITRA_ARCH(x86_64)
static std::unique_ptr<JitX64Engine> jit_engine;
#elif CITRA_ARCH(arm64)
static std::unique_ptr<JitA64Engine> jit_engine;
#endif
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
static std::unique_ptr<JitEngine> jit_engine;
#endif // CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
static InterpreterEngine interpreter_engine;

ShaderEngine* GetEngine() {
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
// TODO(yuriks): Re-initialize on each change rather than being persistent
if (VideoCore::g_shader_jit_enabled) {
if (jit_engine == nullptr) {
jit_engine = std::make_unique<decltype(jit_engine)::element_type>();
jit_engine = std::make_unique<JitEngine>();
}
return jit_engine.get();
}
Expand All @@ -164,7 +160,7 @@ ShaderEngine* GetEngine() {

void Shutdown() {
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
jit_engine = nullptr;
jit_engine.reset();
#endif // CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
}

Expand Down
36 changes: 18 additions & 18 deletions src/video_core/shader/shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

namespace Pica::Shader {

constexpr unsigned MAX_PROGRAM_CODE_LENGTH = 4096;
constexpr unsigned MAX_SWIZZLE_DATA_LENGTH = 4096;
constexpr u32 MAX_PROGRAM_CODE_LENGTH = 4096;
constexpr u32 MAX_SWIZZLE_DATA_LENGTH = 4096;
using ProgramCode = std::array<u32, MAX_PROGRAM_CODE_LENGTH>;
using SwizzleData = std::array<u32, MAX_SWIZZLE_DATA_LENGTH>;

Expand All @@ -33,7 +33,7 @@ struct AttributeBuffer {
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& attr;
}
};
Expand Down Expand Up @@ -62,7 +62,7 @@ struct OutputVertex {

private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
void serialize(Archive& ar, const u32) {
ar& pos;
ar& quat;
ar& color;
Expand Down Expand Up @@ -113,7 +113,7 @@ struct GSEmitter {
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& buffer;
ar& vertex_id;
ar& prim_emit;
Expand Down Expand Up @@ -142,7 +142,7 @@ struct UnitState {
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& input;
ar& temporary;
ar& output;
Expand All @@ -158,15 +158,15 @@ struct UnitState {

GSEmitter* emitter_ptr;

static std::size_t InputOffset(int register_index) {
static std::size_t InputOffset(s32 register_index) {
return offsetof(UnitState, registers.input) + register_index * sizeof(Common::Vec4<f24>);
}

static std::size_t OutputOffset(int register_index) {
static std::size_t OutputOffset(s32 register_index) {
return offsetof(UnitState, registers.output) + register_index * sizeof(Common::Vec4<f24>);
}

static std::size_t TemporaryOffset(int register_index) {
static std::size_t TemporaryOffset(s32 register_index) {
return offsetof(UnitState, registers.temporary) +
register_index * sizeof(Common::Vec4<f24>);
}
Expand All @@ -184,7 +184,7 @@ struct UnitState {
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& registers;
ar& conditional_code;
ar& address_registers;
Expand All @@ -207,7 +207,7 @@ struct GSUnitState : public UnitState {
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& boost::serialization::base_object<UnitState>(*this);
ar& emitter;
}
Expand All @@ -221,22 +221,22 @@ struct Uniforms {
std::array<bool, 16> b;
std::array<Common::Vec4<u8>, 4> i;

static std::size_t GetFloatUniformOffset(unsigned index) {
static std::size_t GetFloatUniformOffset(u32 index) {
return offsetof(Uniforms, f) + index * sizeof(Common::Vec4<f24>);
}

static std::size_t GetBoolUniformOffset(unsigned index) {
static std::size_t GetBoolUniformOffset(u32 index) {
return offsetof(Uniforms, b) + index * sizeof(bool);
}

static std::size_t GetIntUniformOffset(unsigned index) {
static std::size_t GetIntUniformOffset(u32 index) {
return offsetof(Uniforms, i) + index * sizeof(Common::Vec4<u8>);
}

private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& f;
ar& b;
ar& i;
Expand All @@ -251,7 +251,7 @@ struct ShaderSetup {

/// Data private to ShaderEngines
struct EngineData {
unsigned int entry_point;
u32 entry_point;
/// Used by the JIT, points to a compiled shader object.
const void* cached_shader = nullptr;
} engine_data;
Expand Down Expand Up @@ -288,7 +288,7 @@ struct ShaderSetup {

friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {
void serialize(Archive& ar, const u32 file_version) {
ar& uniforms;
ar& program_code;
ar& swizzle_data;
Expand All @@ -307,7 +307,7 @@ class ShaderEngine {
* Performs any shader unit setup that only needs to happen once per shader (as opposed to once
* per vertex, which would happen within the `Run` function).
*/
virtual void SetupBatch(ShaderSetup& setup, unsigned int entry_point) = 0;
virtual void SetupBatch(ShaderSetup& setup, u32 entry_point) = 0;

/**
* Runs the currently setup shader.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@
// Refer to the license.txt file included.

#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)

#include "common/assert.h"
#include "common/microprofile.h"
#include "video_core/shader/shader.h"
#include "video_core/shader/shader_jit_x64.h"
#include "video_core/shader/shader_jit.h"
#if CITRA_ARCH(arm64)
#include "video_core/shader/shader_jit_a64_compiler.h"
#endif
#if CITRA_ARCH(x86_64)
#include "video_core/shader/shader_jit_x64_compiler.h"
#endif

namespace Pica::Shader {

JitX64Engine::JitX64Engine() = default;
JitX64Engine::~JitX64Engine() = default;
JitEngine::JitEngine() = default;
JitEngine::~JitEngine() = default;

void JitX64Engine::SetupBatch(ShaderSetup& setup, unsigned int entry_point) {
void JitEngine::SetupBatch(ShaderSetup& setup, u32 entry_point) {
ASSERT(entry_point < MAX_PROGRAM_CODE_LENGTH);
setup.engine_data.entry_point = entry_point;

u64 code_hash = setup.GetProgramCodeHash();
u64 swizzle_hash = setup.GetSwizzleDataHash();
const u64 code_hash = setup.GetProgramCodeHash();
const u64 swizzle_hash = setup.GetSwizzleDataHash();

u64 cache_key = code_hash ^ swizzle_hash;
const u64 cache_key = Common::HashCombine(code_hash, swizzle_hash);
auto iter = cache.find(cache_key);
if (iter != cache.end()) {
setup.engine_data.cached_shader = iter->second.get();
Expand All @@ -37,7 +42,7 @@ void JitX64Engine::SetupBatch(ShaderSetup& setup, unsigned int entry_point) {

MICROPROFILE_DECLARE(GPU_Shader);

void JitX64Engine::Run(const ShaderSetup& setup, UnitState& state) const {
void JitEngine::Run(const ShaderSetup& setup, UnitState& state) const {
ASSERT(setup.engine_data.cached_shader != nullptr);

MICROPROFILE_SCOPE(GPU_Shader);
Expand All @@ -48,4 +53,4 @@ void JitX64Engine::Run(const ShaderSetup& setup, UnitState& state) const {

} // namespace Pica::Shader

#endif // CITRA_ARCH(x86_64)
#endif // CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#pragma once

#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)

#include <memory>
#include <unordered_map>
Expand All @@ -16,12 +16,12 @@ namespace Pica::Shader {

class JitShader;

class JitX64Engine final : public ShaderEngine {
class JitEngine final : public ShaderEngine {
public:
JitX64Engine();
~JitX64Engine() override;
JitEngine();
~JitEngine() override;

void SetupBatch(ShaderSetup& setup, unsigned int entry_point) override;
void SetupBatch(ShaderSetup& setup, u32 entry_point) override;
void Run(const ShaderSetup& setup, UnitState& state) const override;

private:
Expand All @@ -30,4 +30,4 @@ class JitX64Engine final : public ShaderEngine {

} // namespace Pica::Shader

#endif // CITRA_ARCH(x86_64)
#endif // CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
51 changes: 0 additions & 51 deletions src/video_core/shader/shader_jit_a64.cpp

This file was deleted.

Loading

0 comments on commit 83b329f

Please sign in to comment.