mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 08:13:05 +00:00
* shader: emit float min/max as host instructions on AMD GPUs V_MIN_F32, V_MAX_F32, V_MIN3_F32 and V_MAX3_F32 were emulated with a classify-and-select sequence of about a dozen instructions each, to give the guest's NaN and signed-zero results on any host. AMD GPUs execute GLSL.std.450 NMin/NMax with those same rules, so emit them directly when the device is AMD and supports VK_KHR_shader_float_controls2. Each instruction is decorated FPFastMathMode None, since SignedZeroInfNanPreserve does not cover extended instructions. MED3 keeps its exact emulation. KYTY_EMULATED_FLOAT_MIN_MAX=1 keeps the emulation. In SAROS the two heaviest compute shaders get 37% and 59% faster on an RX 9070 XT (RADV), about 4 ms of GPU time per frame. Adds VectorMinMaxF32RuntimeEdges (runtime operands, so nothing is folded) and a --float-min-max-only mode that runs it and VectorMinMaxF32NanAndSignedZeroEdges with the emulation and, where supported, with host instructions. Developed with AI assistance (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * shader: gate host float min/max on RADV and check the emitted instructions * shader: drop float controls 2 from host float min/max * shader: drop the float min/max env override and atomic flag * shader: pass host capabilities to the SPIR-V emitter as a profile built once per device * shader: enable host float min/max on AMD GPUs --------- Co-authored-by: arda <ardaeska@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: nmzik <Nmzik@mail.ru>
88 lines
3.2 KiB
C++
88 lines
3.2 KiB
C++
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SHADERRECOMPILER_H_
|
|
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SHADERRECOMPILER_H_
|
|
|
|
#include "common/common.h"
|
|
#include "common/stringUtils.h"
|
|
#include "graphics/shader/recompiler/backend/spirv/SpirvEmitter.h"
|
|
#include "graphics/shader/recompiler/ir/passes/ResourceMaterialization.h"
|
|
#include "graphics/shader/recompiler/frontend/decode/ShaderDecoder.h"
|
|
#include "graphics/shader/shader.h"
|
|
|
|
#include <array>
|
|
#include <bitset>
|
|
#include <optional>
|
|
#include <span>
|
|
#include <vector>
|
|
|
|
namespace Libs::Graphics::ShaderRecompiler {
|
|
|
|
struct CompileOptions {
|
|
ShaderType stage = ShaderType::Compute;
|
|
uint32_t wave_size = 64;
|
|
uint32_t user_data_base = 0;
|
|
uint64_t shader_hash = 0;
|
|
bool dump_ir = true;
|
|
bool early_dump = false;
|
|
bool emit_debug_info = false;
|
|
const Spirv::Profile* profile = &Spirv::DefaultProfile;
|
|
const char* dump_label = nullptr;
|
|
std::span<const uint32_t> user_data;
|
|
std::span<const uint32_t> back_code;
|
|
ShaderStageInputInfo input_info;
|
|
};
|
|
|
|
struct TranslateResult {
|
|
IR::Program program;
|
|
std::string decoded_dump;
|
|
std::string cfg_dump;
|
|
};
|
|
|
|
struct CompileResult {
|
|
std::vector<uint32_t> spirv;
|
|
std::string decoded_dump;
|
|
std::string ir_dump;
|
|
IR::Program program;
|
|
};
|
|
|
|
// Decoded source and typed scalar call queries are retained once per cache source.
|
|
struct ShaderSource {
|
|
struct Call {
|
|
uint32_t instruction;
|
|
std::array<IR::Value, 2> target;
|
|
std::bitset<128> preserved_registers;
|
|
uint64_t address = 0;
|
|
};
|
|
struct Linked {
|
|
struct Function { uint32_t offset; uint32_t size; };
|
|
std::vector<uint32_t> code;
|
|
Decoder::Program decoded;
|
|
std::vector<Function> functions;
|
|
std::vector<uint32_t> observed_function;
|
|
};
|
|
std::vector<uint32_t> code;
|
|
Decoder::Program decoded;
|
|
IR::ResourcePlan call_targets;
|
|
std::vector<Call> calls;
|
|
uint32_t unsupported_call_pc = UINT32_MAX;
|
|
std::optional<Linked> linked;
|
|
uint64_t revision = 0;
|
|
std::vector<std::pair<uint64_t, uint64_t>> reads;
|
|
};
|
|
|
|
[[nodiscard]] ShaderSource PrepareShaderSource(std::span<const uint32_t> code,
|
|
const CompileOptions& options);
|
|
const Decoder::Program& RefreshShaderSource(ShaderSource& source, const IR::SrtRuntime& runtime);
|
|
[[nodiscard]] TranslateResult TranslateProgram(const Decoder::Program& decoded,
|
|
const CompileOptions& options);
|
|
|
|
[[nodiscard]] TranslateResult TranslateProgram(std::span<const uint32_t> code,
|
|
const CompileOptions& options);
|
|
[[nodiscard]] CompileResult CompileProgram(TranslateResult translated,
|
|
const CompileOptions& options,
|
|
const IR::ResourceSpecialization& specialization,
|
|
uint32_t push_data_start_dword = 0);
|
|
|
|
} // namespace Libs::Graphics::ShaderRecompiler
|
|
|
|
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SHADERRECOMPILER_H_ */
|