Files
eden/src/shader_recompiler/frontend/ir/opcodes.h
T
CamilleLaVey 50cb8fd1c9 [vulkan] Implementation for VK_EXT_shader_quad_control (#4168)
An experimental approach to introduce an smarter way to use and access QUAD's capabilities on shaders, suggested by @gidoly some months ago, finally came into something usable; current implementation checks GLASM, GLSL and Vulkan on their own way, stablishes proper emitters and receivers for Quads inside our recompiler, which are the introductions for future changes; checks for support and actual feature bit, OpCodes and mask were added within this PR. Meanwhile the expected behavior was to reduce graphical issues (on games with Quad shaders reliant), we encountered a very slight performance increase depending on what game and shader are actually compiled.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4168
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Samuel <lizzie@eden-emu.dev>
2026-08-28 01:21:22 +02:00

98 lines
2.9 KiB
C++

// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <algorithm>
#include <array>
#include <fmt/ranges.h>
#include <ranges>
#include "shader_recompiler/frontend/ir/type.h"
namespace Shader::IR {
enum class Opcode {
#define OPCODE(name, ...) name,
#include "opcodes.inc"
#undef OPCODE
};
namespace Detail {
struct OpcodeMeta {
std::string_view name;
Type type;
std::array<Type, 5> arg_types;
};
// using enum Type;
static constexpr Type Void{Type::Void};
static constexpr Type Opaque{Type::Opaque};
static constexpr Type Reg{Type::Reg};
static constexpr Type Pred{Type::Pred};
static constexpr Type Attribute{Type::Attribute};
static constexpr Type Patch{Type::Patch};
static constexpr Type U1{Type::U1};
static constexpr Type U8{Type::U8};
static constexpr Type U16{Type::U16};
static constexpr Type U32{Type::U32};
static constexpr Type U64{Type::U64};
static constexpr Type F16{Type::F16};
static constexpr Type F32{Type::F32};
static constexpr Type F64{Type::F64};
static constexpr Type U32x2{Type::U32x2};
static constexpr Type U32x3{Type::U32x3};
static constexpr Type U32x4{Type::U32x4};
static constexpr Type F16x2{Type::F16x2};
static constexpr Type F16x3{Type::F16x3};
static constexpr Type F16x4{Type::F16x4};
static constexpr Type F32x2{Type::F32x2};
static constexpr Type F32x3{Type::F32x3};
static constexpr Type F32x4{Type::F32x4};
static constexpr Type F64x2{Type::F64x2};
static constexpr Type F64x3{Type::F64x3};
static constexpr Type F64x4{Type::F64x4};
extern OpcodeMeta META_TABLE[534];
constexpr size_t CalculateNumArgsOf(Opcode op) noexcept {
const auto& arg_types = META_TABLE[size_t(op)].arg_types;
return size_t(std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void)));
}
extern u8 NUM_ARGS[534];
} // namespace Detail
/// Get return type of an opcode
[[nodiscard]] inline Type TypeOf(Opcode op) noexcept {
return Detail::META_TABLE[size_t(op)].type;
}
/// Get the number of arguments an opcode accepts
[[nodiscard]] inline size_t NumArgsOf(Opcode op) noexcept {
return size_t(Detail::NUM_ARGS[size_t(op)]);
}
/// Get the required type of an argument of an opcode
[[nodiscard]] inline Type ArgTypeOf(Opcode op, size_t arg_index) noexcept {
return Detail::META_TABLE[size_t(op)].arg_types[arg_index];
}
/// Get the name of an opcode
[[nodiscard]] std::string_view NameOf(Opcode op);
} // namespace Shader::IR
template <>
struct fmt::formatter<Shader::IR::Opcode> {
constexpr auto parse(format_parse_context& ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const Shader::IR::Opcode& op, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(op));
}
};