early-access version 2208
This commit is contained in:
parent
cdf43a0828
commit
6f086e813b
13 changed files with 122 additions and 16 deletions
|
@ -166,7 +166,7 @@ macro(yuzu_find_packages)
|
||||||
# Capitalization matters here. We need the naming to match the generated paths from Conan
|
# Capitalization matters here. We need the naming to match the generated paths from Conan
|
||||||
set(REQUIRED_LIBS
|
set(REQUIRED_LIBS
|
||||||
# Cmake Pkg Prefix Version Conan Pkg
|
# Cmake Pkg Prefix Version Conan Pkg
|
||||||
"Catch2 2.13 catch2/2.13.0"
|
"Catch2 2.13.7 catch2/2.13.7"
|
||||||
"fmt 8.0 fmt/8.0.0"
|
"fmt 8.0 fmt/8.0.0"
|
||||||
"lz4 1.8 lz4/1.9.2"
|
"lz4 1.8 lz4/1.9.2"
|
||||||
"nlohmann_json 3.8 nlohmann_json/3.8.0"
|
"nlohmann_json 3.8 nlohmann_json/3.8.0"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2204.
|
This is the source code for early-access 2208.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,14 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) {
|
void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) {
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
auto duration = now.time_since_epoch();
|
||||||
|
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||||
|
|
||||||
|
if (nanoseconds > expected_cb_time) {
|
||||||
|
ns_late = nanoseconds - expected_cb_time;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsPlaying()) {
|
if (!IsPlaying()) {
|
||||||
// Ensure we are in playing state before playing the next buffer
|
// Ensure we are in playing state before playing the next buffer
|
||||||
sink_stream.Flush();
|
sink_stream.Flush();
|
||||||
|
@ -121,6 +129,7 @@ void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) {
|
||||||
ns_late = {};
|
ns_late = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expected_cb_time = nanoseconds + (buffer_release_ns - ns_late);
|
||||||
core_timing.ScheduleEvent(buffer_release_ns - ns_late, release_event, {});
|
core_timing.ScheduleEvent(buffer_release_ns - ns_late, release_event, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ private:
|
||||||
SinkStream& sink_stream; ///< Output sink for the stream
|
SinkStream& sink_stream; ///< Output sink for the stream
|
||||||
Core::Timing::CoreTiming& core_timing; ///< Core timing instance.
|
Core::Timing::CoreTiming& core_timing; ///< Core timing instance.
|
||||||
std::string name; ///< Name of the stream, must be unique
|
std::string name; ///< Name of the stream, must be unique
|
||||||
|
std::chrono::nanoseconds expected_cb_time = {}; ///< Estimated time of next callback
|
||||||
};
|
};
|
||||||
|
|
||||||
using StreamPtr = std::shared_ptr<Stream>;
|
using StreamPtr = std::shared_ptr<Stream>;
|
||||||
|
|
|
@ -596,6 +596,7 @@ struct Values {
|
||||||
BasicSetting<std::string> program_args{std::string(), "program_args"};
|
BasicSetting<std::string> program_args{std::string(), "program_args"};
|
||||||
BasicSetting<bool> dump_exefs{false, "dump_exefs"};
|
BasicSetting<bool> dump_exefs{false, "dump_exefs"};
|
||||||
BasicSetting<bool> dump_nso{false, "dump_nso"};
|
BasicSetting<bool> dump_nso{false, "dump_nso"};
|
||||||
|
BasicSetting<bool> dump_shaders{false, "dump_shaders"};
|
||||||
BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"};
|
BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"};
|
||||||
BasicSetting<bool> reporting_services{false, "reporting_services"};
|
BasicSetting<bool> reporting_services{false, "reporting_services"};
|
||||||
BasicSetting<bool> quest_flag{false, "quest_flag"};
|
BasicSetting<bool> quest_flag{false, "quest_flag"};
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] virtual std::array<u32, 3> WorkgroupSize() const = 0;
|
[[nodiscard]] virtual std::array<u32, 3> WorkgroupSize() const = 0;
|
||||||
|
|
||||||
|
virtual void Dump(u64 hash) = 0;
|
||||||
|
|
||||||
[[nodiscard]] const ProgramHeader& SPH() const noexcept {
|
[[nodiscard]] const ProgramHeader& SPH() const noexcept {
|
||||||
return sph;
|
return sph;
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,6 +422,11 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||||
|
|
||||||
const u32 cfg_offset{static_cast<u32>(env.StartAddress() + sizeof(Shader::ProgramHeader))};
|
const u32 cfg_offset{static_cast<u32>(env.StartAddress() + sizeof(Shader::ProgramHeader))};
|
||||||
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
||||||
|
|
||||||
|
if (Settings::values.dump_shaders) {
|
||||||
|
env.Dump(key.unique_hashes[index]);
|
||||||
|
}
|
||||||
|
|
||||||
if (!uses_vertex_a || index != 1) {
|
if (!uses_vertex_a || index != 1) {
|
||||||
// Normal path
|
// Normal path
|
||||||
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
|
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
|
||||||
|
@ -506,8 +511,12 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
||||||
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
|
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
|
||||||
|
|
||||||
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
||||||
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
|
||||||
|
|
||||||
|
if (Settings::values.dump_shaders) {
|
||||||
|
env.Dump(key.Hash());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
||||||
const u32 num_storage_buffers{Shader::NumDescriptors(program.info.storage_buffers_descriptors)};
|
const u32 num_storage_buffers{Shader::NumDescriptors(program.info.storage_buffers_descriptors)};
|
||||||
Shader::RuntimeInfo info;
|
Shader::RuntimeInfo info;
|
||||||
info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
|
info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
|
||||||
|
|
|
@ -516,6 +516,9 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||||
|
|
||||||
const u32 cfg_offset{static_cast<u32>(env.StartAddress() + sizeof(Shader::ProgramHeader))};
|
const u32 cfg_offset{static_cast<u32>(env.StartAddress() + sizeof(Shader::ProgramHeader))};
|
||||||
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
||||||
|
if (Settings::values.dump_shaders) {
|
||||||
|
env.Dump(key.unique_hashes[index]);
|
||||||
|
}
|
||||||
if (!uses_vertex_a || index != 1) {
|
if (!uses_vertex_a || index != 1) {
|
||||||
// Normal path
|
// Normal path
|
||||||
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
|
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
|
||||||
|
@ -611,6 +614,12 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||||
LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash());
|
LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash());
|
||||||
|
|
||||||
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
||||||
|
|
||||||
|
// Dump it before error.
|
||||||
|
if (Settings::values.dump_shaders) {
|
||||||
|
env.Dump(key.Hash());
|
||||||
|
}
|
||||||
|
|
||||||
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
||||||
const std::vector<u32> code{EmitSPIRV(profile, program)};
|
const std::vector<u32> code{EmitSPIRV(profile, program)};
|
||||||
device.SaveShader(code);
|
device.SaveShader(code);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/div_ceil.h"
|
#include "common/div_ceil.h"
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
|
#include "common/fs/path_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "shader_recompiler/environment.h"
|
#include "shader_recompiler/environment.h"
|
||||||
#include "video_core/engines/kepler_compute.h"
|
#include "video_core/engines/kepler_compute.h"
|
||||||
|
@ -57,6 +59,47 @@ static Shader::TextureType ConvertType(const Tegra::Texture::TICEntry& entry) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string_view StageToPreffix(Shader::Stage stage) {
|
||||||
|
switch (stage) {
|
||||||
|
case Shader::Stage::VertexB:
|
||||||
|
return "VB";
|
||||||
|
case Shader::Stage::TessellationControl:
|
||||||
|
return "TC";
|
||||||
|
case Shader::Stage::TessellationEval:
|
||||||
|
return "TE";
|
||||||
|
case Shader::Stage::Geometry:
|
||||||
|
return "GS";
|
||||||
|
case Shader::Stage::Fragment:
|
||||||
|
return "FS";
|
||||||
|
case Shader::Stage::Compute:
|
||||||
|
return "CS";
|
||||||
|
case Shader::Stage::VertexA:
|
||||||
|
return "VA";
|
||||||
|
default:
|
||||||
|
return "UK";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DumpImpl(u64 hash, const u64* code, u32 read_highest, u32 read_lowest,
|
||||||
|
u32 initial_offset, Shader::Stage stage) {
|
||||||
|
const auto shader_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)};
|
||||||
|
const auto base_dir{shader_dir / fmt::format("shaders")};
|
||||||
|
if (!Common::FS::CreateDir(shader_dir) || !Common::FS::CreateDir(base_dir)) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Failed to create shader dump directories");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto prefix = StageToPreffix(stage);
|
||||||
|
const auto name{base_dir / fmt::format("{}{:016x}.ash", prefix, hash)};
|
||||||
|
const size_t real_size = read_highest - read_lowest + initial_offset;
|
||||||
|
const size_t padding_needed = ((32 - (real_size % 32)) % 32);
|
||||||
|
std::fstream shader_file(name, std::ios::out | std::ios::binary);
|
||||||
|
const size_t jump_index = initial_offset / sizeof(u64);
|
||||||
|
shader_file.write(reinterpret_cast<const char*>(code + jump_index), real_size);
|
||||||
|
for (size_t i = 0; i < padding_needed; i++) {
|
||||||
|
shader_file.put(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GenericEnvironment::GenericEnvironment(Tegra::MemoryManager& gpu_memory_, GPUVAddr program_base_,
|
GenericEnvironment::GenericEnvironment(Tegra::MemoryManager& gpu_memory_, GPUVAddr program_base_,
|
||||||
u32 start_address_)
|
u32 start_address_)
|
||||||
: gpu_memory{&gpu_memory_}, program_base{program_base_} {
|
: gpu_memory{&gpu_memory_}, program_base{program_base_} {
|
||||||
|
@ -128,6 +171,10 @@ u64 GenericEnvironment::CalculateHash() const {
|
||||||
return Common::CityHash64(data.get(), size);
|
return Common::CityHash64(data.get(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenericEnvironment::Dump(u64 hash) {
|
||||||
|
DumpImpl(hash, code.data(), read_highest, read_lowest, initial_offset, stage);
|
||||||
|
}
|
||||||
|
|
||||||
void GenericEnvironment::Serialize(std::ofstream& file) const {
|
void GenericEnvironment::Serialize(std::ofstream& file) const {
|
||||||
const u64 code_size{static_cast<u64>(CachedSize())};
|
const u64 code_size{static_cast<u64>(CachedSize())};
|
||||||
const u64 num_texture_types{static_cast<u64>(texture_types.size())};
|
const u64 num_texture_types{static_cast<u64>(texture_types.size())};
|
||||||
|
@ -207,6 +254,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
|
||||||
u32 start_address_)
|
u32 start_address_)
|
||||||
: GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} {
|
: GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} {
|
||||||
gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph));
|
gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph));
|
||||||
|
initial_offset = sizeof(sph);
|
||||||
gp_passthrough_mask = maxwell3d->regs.gp_passthrough_mask;
|
gp_passthrough_mask = maxwell3d->regs.gp_passthrough_mask;
|
||||||
switch (program) {
|
switch (program) {
|
||||||
case Maxwell::ShaderProgram::VertexA:
|
case Maxwell::ShaderProgram::VertexA:
|
||||||
|
@ -323,14 +371,20 @@ void FileEnvironment::Deserialize(std::ifstream& file) {
|
||||||
if (stage == Shader::Stage::Compute) {
|
if (stage == Shader::Stage::Compute) {
|
||||||
file.read(reinterpret_cast<char*>(&workgroup_size), sizeof(workgroup_size))
|
file.read(reinterpret_cast<char*>(&workgroup_size), sizeof(workgroup_size))
|
||||||
.read(reinterpret_cast<char*>(&shared_memory_size), sizeof(shared_memory_size));
|
.read(reinterpret_cast<char*>(&shared_memory_size), sizeof(shared_memory_size));
|
||||||
|
initial_offset = 0;
|
||||||
} else {
|
} else {
|
||||||
file.read(reinterpret_cast<char*>(&sph), sizeof(sph));
|
file.read(reinterpret_cast<char*>(&sph), sizeof(sph));
|
||||||
|
initial_offset = sizeof(sph);
|
||||||
if (stage == Shader::Stage::Geometry) {
|
if (stage == Shader::Stage::Geometry) {
|
||||||
file.read(reinterpret_cast<char*>(&gp_passthrough_mask), sizeof(gp_passthrough_mask));
|
file.read(reinterpret_cast<char*>(&gp_passthrough_mask), sizeof(gp_passthrough_mask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileEnvironment::Dump(u64 [[maybe_unused]] hash) {
|
||||||
|
DumpImpl(hash, code.get(), read_highest, read_lowest, initial_offset, stage);
|
||||||
|
}
|
||||||
|
|
||||||
u64 FileEnvironment::ReadInstruction(u32 address) {
|
u64 FileEnvironment::ReadInstruction(u32 address) {
|
||||||
if (address < read_lowest || address > read_highest) {
|
if (address < read_lowest || address > read_highest) {
|
||||||
throw Shader::LogicError("Out of bounds address {}", address);
|
throw Shader::LogicError("Out of bounds address {}", address);
|
||||||
|
|
|
@ -57,6 +57,8 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] u64 CalculateHash() const;
|
[[nodiscard]] u64 CalculateHash() const;
|
||||||
|
|
||||||
|
void Dump(u64 hash);
|
||||||
|
|
||||||
void Serialize(std::ofstream& file) const;
|
void Serialize(std::ofstream& file) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -82,6 +84,7 @@ protected:
|
||||||
|
|
||||||
u32 cached_lowest = std::numeric_limits<u32>::max();
|
u32 cached_lowest = std::numeric_limits<u32>::max();
|
||||||
u32 cached_highest = 0;
|
u32 cached_highest = 0;
|
||||||
|
u32 initial_offset = 0;
|
||||||
|
|
||||||
bool has_unbound_instructions = false;
|
bool has_unbound_instructions = false;
|
||||||
};
|
};
|
||||||
|
@ -149,6 +152,8 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] std::array<u32, 3> WorkgroupSize() const override;
|
[[nodiscard]] std::array<u32, 3> WorkgroupSize() const override;
|
||||||
|
|
||||||
|
void Dump(u64 hash);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<u64[]> code;
|
std::unique_ptr<u64[]> code;
|
||||||
std::unordered_map<u32, Shader::TextureType> texture_types;
|
std::unordered_map<u32, Shader::TextureType> texture_types;
|
||||||
|
@ -159,6 +164,7 @@ private:
|
||||||
u32 texture_bound{};
|
u32 texture_bound{};
|
||||||
u32 read_lowest{};
|
u32 read_lowest{};
|
||||||
u32 read_highest{};
|
u32 read_highest{};
|
||||||
|
u32 initial_offset{};
|
||||||
};
|
};
|
||||||
|
|
||||||
void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs,
|
void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs,
|
||||||
|
|
|
@ -66,15 +66,14 @@ float TSCEntry::MaxAnisotropy() const noexcept {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue();
|
const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue();
|
||||||
u32 new_max_anisotropic{};
|
u32 added_anisotropic{};
|
||||||
if (anisotropic_settings == 0) {
|
if (anisotropic_settings == 0) {
|
||||||
const auto anisotropic_based_onscale = Settings::values.resolution_info.up_scale >>
|
added_anisotropic = Settings::values.resolution_info.up_scale >>
|
||||||
Settings::values.resolution_info.down_shift;
|
Settings::values.resolution_info.down_shift;
|
||||||
new_max_anisotropic = std::max(anisotropic_based_onscale + 1U, 1U);
|
|
||||||
} else {
|
} else {
|
||||||
new_max_anisotropic = Settings::values.max_anisotropy.GetValue();
|
added_anisotropic = Settings::values.max_anisotropy.GetValue() - 1U;
|
||||||
}
|
}
|
||||||
return static_cast<float>(1U << std::min(max_anisotropy + anisotropic_settings - 1, 31U));
|
return static_cast<float>(1U << (max_anisotropy + added_anisotropic));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Tegra::Texture
|
} // namespace Tegra::Texture
|
||||||
|
|
|
@ -50,6 +50,8 @@ void ConfigureDebug::SetConfiguration() {
|
||||||
ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue());
|
ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue());
|
||||||
ui->enable_nsight_aftermath->setEnabled(runtime_lock);
|
ui->enable_nsight_aftermath->setEnabled(runtime_lock);
|
||||||
ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue());
|
ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue());
|
||||||
|
ui->dump_shaders->setEnabled(runtime_lock);
|
||||||
|
ui->dump_shaders->setChecked(Settings::values.dump_shaders.GetValue());
|
||||||
ui->disable_macro_jit->setEnabled(runtime_lock);
|
ui->disable_macro_jit->setEnabled(runtime_lock);
|
||||||
ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue());
|
ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue());
|
||||||
ui->disable_loop_safety_checks->setEnabled(runtime_lock);
|
ui->disable_loop_safety_checks->setEnabled(runtime_lock);
|
||||||
|
@ -71,6 +73,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||||
Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked();
|
Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked();
|
||||||
Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
|
Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
|
||||||
Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked();
|
Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked();
|
||||||
|
Settings::values.dump_shaders = ui->dump_shaders->isChecked();
|
||||||
Settings::values.disable_shader_loop_safety_checks =
|
Settings::values.disable_shader_loop_safety_checks =
|
||||||
ui->disable_loop_safety_checks->isChecked();
|
ui->disable_loop_safety_checks->isChecked();
|
||||||
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
|
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
|
||||||
|
|
|
@ -105,6 +105,19 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QCheckBox" name="dump_shaders">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Dump Game Shaders</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QCheckBox" name="disable_macro_jit">
|
<widget class="QCheckBox" name="disable_macro_jit">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
|
|
Loading…
Reference in a new issue