diff --git a/README.md b/README.md index 01e40e77c..c13c754d6 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1360. +This is the source code for early-access 1365. ## Legal Notice diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9f2c7cada..848b7ca7c 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -402,8 +402,6 @@ add_library(core STATIC hle/service/ldr/ldr.h hle/service/lm/lm.cpp hle/service/lm/lm.h - hle/service/lm/manager.cpp - hle/service/lm/manager.h hle/service/mig/mig.cpp hle/service/mig/mig.h hle/service/mii/manager.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index bf7851438..30f5e1128 100755 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -36,7 +36,6 @@ #include "core/hle/service/apm/controller.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/glue/manager.h" -#include "core/hle/service/lm/manager.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/hle/service/time/time_manager.h" @@ -293,8 +292,6 @@ struct System::Impl { perf_stats->GetMeanFrametime()); } - lm_manager.Flush(); - is_powered_on = false; exit_lock = false; @@ -398,7 +395,6 @@ struct System::Impl { /// Service State Service::Glue::ARPManager arp_manager; - Service::LM::Manager lm_manager{reporter}; Service::Time::TimeManager time_manager; /// Service manager @@ -720,14 +716,6 @@ const Service::APM::Controller& System::GetAPMController() const { return impl->apm_controller; } -Service::LM::Manager& System::GetLogManager() { - return impl->lm_manager; -} - -const Service::LM::Manager& System::GetLogManager() const { - return impl->lm_manager; -} - Service::Time::TimeManager& System::GetTimeManager() { return impl->time_manager; } diff --git a/src/core/core.h b/src/core/core.h index 579a774e4..3a8e040c1 100755 --- a/src/core/core.h +++ b/src/core/core.h @@ -62,10 +62,6 @@ namespace Glue { class ARPManager; } -namespace LM { -class Manager; -} // namespace LM - namespace SM { class ServiceManager; } // namespace SM @@ -351,9 +347,6 @@ public: [[nodiscard]] Service::APM::Controller& GetAPMController(); [[nodiscard]] const Service::APM::Controller& GetAPMController() const; - [[nodiscard]] Service::LM::Manager& GetLogManager(); - [[nodiscard]] const Service::LM::Manager& GetLogManager() const; - [[nodiscard]] Service::Time::TimeManager& GetTimeManager(); [[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const; diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 8e49b068c..90e9e691a 100755 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -5,22 +5,71 @@ #include #include +#include +#include +#include #include "common/logging/log.h" #include "common/scope_exit.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/lm/lm.h" -#include "core/hle/service/lm/manager.h" #include "core/hle/service/service.h" #include "core/memory.h" namespace Service::LM { +enum class LogSeverity : u8 { + Trace = 0, + Info = 1, + Warning = 2, + Error = 3, + Fatal = 4, +}; + +// To keep flags out of hashing as well as the payload size +struct LogPacketHeaderEntry { + u64_le pid{}; + u64_le tid{}; + LogSeverity severity{}; + u8 verbosity{}; + + auto operator<=>(const LogPacketHeaderEntry&) const = default; +}; +} // namespace Service::LM + +namespace std { +template <> +struct hash { + std::size_t operator()(const Service::LM::LogPacketHeaderEntry& k) const noexcept { + std::size_t seed{}; + boost::hash_combine(seed, k.pid); + boost::hash_combine(seed, k.tid); + boost::hash_combine(seed, k.severity); + boost::hash_combine(seed, k.verbosity); + return seed; + }; +}; +} // namespace std + +namespace Service::LM { + +enum class LogDestination : u32 { + TargetManager = 1 << 0, + Uart = 1 << 1, + UartSleep = 1 << 2, + All = 0xffff, +}; +DECLARE_ENUM_FLAG_OPERATORS(LogDestination); + +enum class LogPacketFlags : u8 { + Head = 1 << 0, + Tail = 1 << 1, + LittleEndian = 1 << 2, +}; +DECLARE_ENUM_FLAG_OPERATORS(LogPacketFlags); class ILogger final : public ServiceFramework { public: - explicit ILogger(Core::System& system_) - : ServiceFramework{system_, "ILogger"}, manager{system_.GetLogManager()}, - memory{system_.Memory()} { + explicit ILogger(Core::System& system_) : ServiceFramework{system_, "ILogger"} { static const FunctionInfo functions[] = { {0, &ILogger::Log, "Log"}, {1, &ILogger::SetDestination, "SetDestination"}, @@ -30,54 +79,262 @@ public: private: void Log(Kernel::HLERequestContext& ctx) { + std::size_t offset{}; + const auto data = ctx.ReadBuffer(); + // This function only succeeds - Get that out of the way IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - // Read MessageHeader, despite not doing anything with it right now - MessageHeader header{}; - VAddr addr{ctx.BufferDescriptorX()[0].Address()}; - const VAddr end_addr{addr + ctx.BufferDescriptorX()[0].size}; - memory.ReadBlock(addr, &header, sizeof(MessageHeader)); - addr += sizeof(MessageHeader); - - FieldMap fields; - while (addr < end_addr) { - const auto field = static_cast(memory.Read8(addr++)); - const auto length = memory.Read8(addr++); - - if (static_cast(memory.Read8(addr)) == Field::Skip) { - ++addr; - } - - SCOPE_EXIT({ addr += length; }); - - if (field == Field::Skip) { - continue; - } - - std::vector data(length); - memory.ReadBlock(addr, data.data(), length); - fields.emplace(field, std::move(data)); + if (data.size() < sizeof(LogPacketHeader)) { + LOG_ERROR(Service_LM, "Data size is too small for header! size={}", data.size()); + return; } - manager.Log({header, std::move(fields)}); + LogPacketHeader header{}; + std::memcpy(&header, data.data(), sizeof(LogPacketHeader)); + offset += sizeof(LogPacketHeader); + + LogPacketHeaderEntry entry{ + .pid = header.pid, + .tid = header.tid, + .severity = header.severity, + .verbosity = header.verbosity, + }; + + if (True(header.flags & LogPacketFlags::Head)) { + std::vector tmp(data.size() - sizeof(LogPacketHeader)); + std::memcpy(tmp.data(), data.data() + offset, tmp.size()); + entries[entry] = std::move(tmp); + } else { + // Append to existing entry + if (!entries.contains(entry)) { + LOG_ERROR(Service_LM, "Log entry does not exist!"); + return; + } + std::vector tmp(data.size() - sizeof(LogPacketHeader)); + + auto& existing_entry = entries[entry]; + const auto base = existing_entry.size(); + existing_entry.resize(base + (data.size() - sizeof(LogPacketHeader))); + std::memcpy(existing_entry.data() + base, data.data() + offset, + (data.size() - sizeof(LogPacketHeader))); + } + + if (True(header.flags & LogPacketFlags::Tail)) { + auto it = entries.find(entry); + if (it == entries.end()) { + LOG_ERROR(Service_LM, "Log entry does not exist!"); + return; + } + ParseLog(it->first, it->second); + entries.erase(it); + } } void SetDestination(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto destination = rp.PopEnum(); + const auto log_destination = rp.PopEnum(); - LOG_DEBUG(Service_LM, "called, destination={:08X}", destination); - - manager.SetDestination(destination); + LOG_DEBUG(Service_LM, "called, destination={}", DestinationToString(log_destination)); + destination = log_destination; IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } - Manager& manager; - Core::Memory::Memory& memory; + u32 ReadLeb128(const std::vector& data, std::size_t& offset) { + u32 result{}; + u32 shift{}; + do { + result |= (data[offset] & 0x7f) << shift; + shift += 7; + offset++; + if (offset >= data.size()) { + break; + } + } while ((data[offset] & 0x80) != 0); + return result; + } + + std::optional ReadString(const std::vector& data, std::size_t& offset, + std::size_t length) { + if (length == 0) { + return std::nullopt; + } + const auto length_to_read = std::min(length, data.size() - offset); + + std::string output(length_to_read, '\0'); + std::memcpy(output.data(), data.data() + offset, length_to_read); + offset += length_to_read; + return output; + } + + u32_le ReadAsU32(const std::vector& data, std::size_t& offset, std::size_t length) { + ASSERT(length == sizeof(u32)); + u32_le output{}; + std::memcpy(&output, data.data() + offset, sizeof(u32)); + offset += length; + return output; + } + + u64_le ReadAsU64(const std::vector& data, std::size_t& offset, std::size_t length) { + ASSERT(length == sizeof(u64)); + u64_le output{}; + std::memcpy(&output, data.data() + offset, sizeof(u64)); + offset += length; + return output; + } + + void ParseLog(const LogPacketHeaderEntry entry, const std::vector& log_data) { + // Possible entries + std::optional text_log; + std::optional line_number; + std::optional file_name; + std::optional function_name; + std::optional module_name; + std::optional thread_name; + std::optional log_pack_drop_count; + std::optional user_system_clock; + std::optional process_name; + + std::size_t offset{}; + while (offset < log_data.size()) { + const auto key = static_cast(ReadLeb128(log_data, offset)); + const auto chunk_size = ReadLeb128(log_data, offset); + + switch (key) { + case LogDataChunkKey::LogSessionBegin: + case LogDataChunkKey::LogSessionEnd: + break; + case LogDataChunkKey::TextLog: + text_log = ReadString(log_data, offset, chunk_size); + break; + case LogDataChunkKey::LineNumber: + line_number = ReadAsU32(log_data, offset, chunk_size); + break; + case LogDataChunkKey::FileName: + file_name = ReadString(log_data, offset, chunk_size); + break; + case LogDataChunkKey::FunctionName: + function_name = ReadString(log_data, offset, chunk_size); + break; + case LogDataChunkKey::ModuleName: + module_name = ReadString(log_data, offset, chunk_size); + break; + case LogDataChunkKey::ThreadName: + thread_name = ReadString(log_data, offset, chunk_size); + break; + case LogDataChunkKey::LogPacketDropCount: + log_pack_drop_count = ReadAsU64(log_data, offset, chunk_size); + break; + case LogDataChunkKey::UserSystemClock: + user_system_clock = ReadAsU64(log_data, offset, chunk_size); + break; + case LogDataChunkKey::ProcessName: + process_name = ReadString(log_data, offset, chunk_size); + break; + } + } + + std::string output_log{}; + if (process_name) { + output_log += fmt::format("Process: {}\n", *process_name); + } + if (module_name) { + output_log += fmt::format("Module: {}\n", *module_name); + } + if (file_name) { + output_log += fmt::format("File: {}\n", *file_name); + } + if (function_name) { + output_log += fmt::format("Function: {}\n", *function_name); + } + if (line_number && *line_number != 0) { + output_log += fmt::format("Line: {}\n", *line_number); + } + output_log += fmt::format("ProcessID: {}\n", entry.pid); + output_log += fmt::format("ThreadID: {}\n", entry.tid); + + if (text_log) { + output_log += fmt::format("Log Text: {}\n", *text_log); + } + + switch (entry.severity) { + case LogSeverity::Trace: + LOG_DEBUG(Service_LM, "LogManager DEBUG ({}):\n{}", DestinationToString(destination), + output_log); + break; + case LogSeverity::Info: + LOG_INFO(Service_LM, "LogManager INFO ({}):\n{}", DestinationToString(destination), + output_log); + break; + case LogSeverity::Warning: + LOG_WARNING(Service_LM, "LogManager WARNING ({}):\n{}", + DestinationToString(destination), output_log); + break; + case LogSeverity::Error: + LOG_ERROR(Service_LM, "LogManager ERROR ({}):\n{}", DestinationToString(destination), + output_log); + break; + case LogSeverity::Fatal: + LOG_CRITICAL(Service_LM, "LogManager FATAL ({}):\n{}", DestinationToString(destination), + output_log); + break; + default: + LOG_CRITICAL(Service_LM, "LogManager UNKNOWN ({}):\n{}", + DestinationToString(destination), output_log); + break; + } + } + + static std::string DestinationToString(LogDestination destination) { + if (True(destination & LogDestination::All)) { + return "TargetManager | Uart | UartSleep"; + } + std::string output{}; + if (True(destination & LogDestination::TargetManager)) { + output += "| TargetManager"; + } + if (True(destination & LogDestination::Uart)) { + output += "| Uart"; + } + if (True(destination & LogDestination::UartSleep)) { + output += "| UartSleep"; + } + if (output.length() > 0) { + return output.substr(2); + } + return "No Destination"; + } + + enum class LogDataChunkKey : u32 { + LogSessionBegin = 0, + LogSessionEnd = 1, + TextLog = 2, + LineNumber = 3, + FileName = 4, + FunctionName = 5, + ModuleName = 6, + ThreadName = 7, + LogPacketDropCount = 8, + UserSystemClock = 9, + ProcessName = 10, + }; + + struct LogPacketHeader { + u64_le pid{}; + u64_le tid{}; + LogPacketFlags flags{}; + INSERT_PADDING_BYTES(1); + LogSeverity severity{}; + u8 verbosity{}; + u32_le payload_size{}; + }; + static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader is an invalid size"); + + std::unordered_map> entries{}; + LogDestination destination{LogDestination::All}; }; class LM final : public ServiceFramework { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index fea3b7b9f..060599bab 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -155,7 +155,13 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector& input, std::ve return NvResult::BadParameter; } if (events_interface.registered[event_id]) { - return NvResult::BadParameter; + const auto event_state = events_interface.status[event_id]; + if (event_state != EventState::Free) { + LOG_WARNING(Service_NVDRV, "Event already registered! Unregistering previous event"); + events_interface.UnregisterEvent(event_id); + } else { + return NvResult::BadParameter; + } } events_interface.RegisterEvent(event_id); return NvResult::Success; diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 0becdf642..f199c3362 100755 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -20,7 +20,6 @@ #include "core/hle/kernel/memory/page_table.h" #include "core/hle/kernel/process.h" #include "core/hle/result.h" -#include "core/hle/service/lm/manager.h" #include "core/memory.h" #include "core/reporter.h" #include "core/settings.h" @@ -360,55 +359,6 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result, SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp)); } -void Reporter::SaveLogReport(u32 destination, std::vector messages) const { - if (!IsReportingEnabled()) { - return; - } - - const auto timestamp = GetTimestamp(); - json out; - - out["yuzu_version"] = GetYuzuVersionData(); - out["report_common"] = - GetReportCommonData(system.CurrentProcess()->GetTitleID(), RESULT_SUCCESS, timestamp); - - out["log_destination"] = - fmt::format("{}", static_cast(destination)); - - auto json_messages = json::array(); - std::transform(messages.begin(), messages.end(), std::back_inserter(json_messages), - [](const Service::LM::LogMessage& message) { - json out; - out["is_head"] = fmt::format("{}", message.header.IsHeadLog()); - out["is_tail"] = fmt::format("{}", message.header.IsTailLog()); - out["pid"] = fmt::format("{:016X}", message.header.pid); - out["thread_context"] = - fmt::format("{:016X}", message.header.thread_context); - out["payload_size"] = fmt::format("{:016X}", message.header.payload_size); - out["flags"] = fmt::format("{:04X}", message.header.flags.Value()); - out["severity"] = fmt::format("{}", message.header.severity.Value()); - out["verbosity"] = fmt::format("{:02X}", message.header.verbosity); - - auto fields = json::array(); - std::transform(message.fields.begin(), message.fields.end(), - std::back_inserter(fields), [](const auto& kv) { - json out; - out["type"] = fmt::format("{}", kv.first); - out["data"] = - Service::LM::FormatField(kv.first, kv.second); - return out; - }); - - out["fields"] = std::move(fields); - return out; - }); - - out["log_messages"] = std::move(json_messages); - - SaveToFile(std::move(out), - GetPath("log_report", system.CurrentProcess()->GetTitleID(), timestamp)); -} - void Reporter::SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode, std::string log_message) const { if (!IsReportingEnabled()) diff --git a/src/core/reporter.h b/src/core/reporter.h index 86d760cf0..b2c2d9a2e 100755 --- a/src/core/reporter.h +++ b/src/core/reporter.h @@ -72,9 +72,6 @@ public: void SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode, std::string log_message) const; - // Used by lm services - void SaveLogReport(u32 destination, std::vector messages) const; - // Can be used anywhere to generate a backtrace and general info report at any point during // execution. Not intended to be used for anything other than debugging or testing. void SaveUserReport() const; diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index a87db6084..f67de37e3 100755 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -81,10 +81,14 @@ public: } bool RumblePlay(u16 amp_low, u16 amp_high) { + constexpr u32 rumble_max_duration_ms = 1000; + if (sdl_controller) { - return SDL_GameControllerRumble(sdl_controller.get(), amp_low, amp_high, 0) == 0; + return SDL_GameControllerRumble(sdl_controller.get(), amp_low, amp_high, + rumble_max_duration_ms) == 0; } else if (sdl_joystick) { - return SDL_JoystickRumble(sdl_joystick.get(), amp_low, amp_high, 0) == 0; + return SDL_JoystickRumble(sdl_joystick.get(), amp_low, amp_high, + rumble_max_duration_ms) == 0; } return false; diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 4ab20f20e..a3fc049c6 100755 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -284,10 +284,10 @@ target_link_libraries(video_core PRIVATE sirit) if (ENABLE_NSIGHT_AFTERMATH) if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK}) - message(ERROR "Environment variable NSIGHT_AFTERMATH_SDK has to be provided") + message(FATAL_ERROR "Environment variable NSIGHT_AFTERMATH_SDK has to be provided") endif() if (NOT WIN32) - message(ERROR "Nsight Aftermath doesn't support non-Windows platforms") + message(FATAL_ERROR "Nsight Aftermath doesn't support non-Windows platforms") endif() target_compile_definitions(video_core PRIVATE HAS_NSIGHT_AFTERMATH) target_include_directories(video_core PRIVATE "$ENV{NSIGHT_AFTERMATH_SDK}/include") diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 4f1e4ec28..8530ace62 100755 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -140,6 +140,7 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat u32 offset, [[maybe_unused]] u32 size) { VkIndexType vk_index_type = MaxwellToVK::IndexFormat(index_format); VkDeviceSize vk_offset = offset; + VkBuffer vk_buffer = buffer; if (topology == PrimitiveTopology::Quads) { vk_index_type = VK_INDEX_TYPE_UINT32; std::tie(buffer, vk_offset) = @@ -148,8 +149,13 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat vk_index_type = VK_INDEX_TYPE_UINT16; std::tie(buffer, vk_offset) = uint8_pass.Assemble(num_indices, buffer, offset); } - scheduler.Record([buffer, vk_offset, vk_index_type](vk::CommandBuffer cmdbuf) { - cmdbuf.BindIndexBuffer(buffer, vk_offset, vk_index_type); + if (vk_buffer == VK_NULL_HANDLE) { + // Vulkan doesn't support null index buffers. Replace it with our own null buffer. + ReserveNullIndexBuffer(); + vk_buffer = *null_index_buffer; + } + scheduler.Record([vk_buffer, vk_offset, vk_index_type](vk::CommandBuffer cmdbuf) { + cmdbuf.BindIndexBuffer(vk_buffer, vk_offset, vk_index_type); }); } @@ -276,4 +282,29 @@ void BufferCacheRuntime::ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle }); } +void BufferCacheRuntime::ReserveNullIndexBuffer() { + if (null_index_buffer) { + return; + } + null_index_buffer = device.GetLogical().CreateBuffer(VkBufferCreateInfo{ + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = 4, + .usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + }); + if (device.HasDebuggingToolAttached()) { + null_index_buffer.SetObjectNameEXT("Null index buffer"); + } + null_index_buffer_commit = memory_allocator.Commit(null_index_buffer, MemoryUsage::DeviceLocal); + + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.Record([buffer = *null_index_buffer](vk::CommandBuffer cmdbuf) { + cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0); + }); +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 7ff7e0d55..041e6515c 100755 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -90,6 +90,8 @@ private: void ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle); + void ReserveNullIndexBuffer(); + const Device& device; MemoryAllocator& memory_allocator; VKScheduler& scheduler; @@ -101,6 +103,9 @@ private: VkIndexType quad_array_lut_index_type{}; u32 current_num_indices = 0; + vk::Buffer null_index_buffer; + MemoryCommit null_index_buffer_commit; + Uint8Pass uint8_pass; QuadIndexedPass quad_index_pass; }; diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index caf5ff362..625a5eb46 100755 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -392,7 +392,7 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_ case 0: // Operation Node SearchOperands(bb, value); break; - case 2: // Genral Purpose Node + case 2: // General Purpose Node if (const auto* gpr = std::get_if(value.get())) { LOG_DEBUG(HW_GPU, "GprNode: index={}", gpr->GetIndex()); Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp index 8d10ac29e..7a9d00d4f 100755 --- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp +++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp @@ -12,21 +12,12 @@ #include -#define VK_NO_PROTOTYPES -#include - -#include -#include -#include -#include - #include "common/common_paths.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" #include "common/scope_exit.h" - -#include "video_core/renderer_vulkan/nsight_aftermath_tracker.h" +#include "video_core/vulkan_common/nsight_aftermath_tracker.h" namespace Vulkan { @@ -53,7 +44,7 @@ NsightAftermathTracker::NsightAftermathTracker() { !dl.GetSymbol("GFSDK_Aftermath_GpuCrashDump_GetJSON", &GFSDK_Aftermath_GpuCrashDump_GetJSON)) { LOG_ERROR(Render_Vulkan, "Failed to load Nsight Aftermath function pointers"); - return false; + return; } dump_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir) + "gpucrash"; diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.h b/src/video_core/vulkan_common/nsight_aftermath_tracker.h index 3e4fec4fb..1ce8d4e8e 100755 --- a/src/video_core/vulkan_common/nsight_aftermath_tracker.h +++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.h @@ -8,16 +8,16 @@ #include #include +#include "common/common_types.h" +#include "common/dynamic_library.h" +#include "video_core/vulkan_common/vulkan_wrapper.h" + #ifdef HAS_NSIGHT_AFTERMATH #include #include #include #endif -#include "common/common_types.h" -#include "common/dynamic_library.h" -#include "video_core/vulkan_common/vulkan_wrapper.h" - namespace Vulkan { class NsightAftermathTracker { diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9d5fdcadd..e473715d3 100755 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -444,6 +444,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR "Blacklisting AMD proprietary on RDNA devices from VK_EXT_extended_dynamic_state"); ext_extended_dynamic_state = false; } + if (is_float16_supported && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { + // Intel's compiler crashes when using fp16 on Astral Chain, disable it for the time being. + LOG_WARNING(Render_Vulkan, "Blacklisting Intel proprietary from float16 math"); + is_float16_supported = false; + } graphics_queue = logical.GetQueue(graphics_family); present_queue = logical.GetQueue(present_family);