early-access version 3764

This commit is contained in:
pineappleEA
2023-07-20 19:02:37 +02:00
parent 30259960bd
commit bbf6b05a26
46 changed files with 3295 additions and 2352 deletions

View File

@@ -12,6 +12,7 @@ import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.CardHomeOptionBinding
import org.yuzu.yuzu_emu.fragments.MessageDialogFragment
import org.yuzu.yuzu_emu.model.HomeSetting
class HomeSettingAdapter(private val activity: AppCompatActivity, var options: List<HomeSetting>) :
@@ -34,7 +35,14 @@ class HomeSettingAdapter(private val activity: AppCompatActivity, var options: L
override fun onClick(view: View) {
val holder = view.tag as HomeOptionViewHolder
holder.option.onClick.invoke()
if (holder.option.isEnabled.invoke()) {
holder.option.onClick.invoke()
} else {
MessageDialogFragment.newInstance(
holder.option.disabledTitleId,
holder.option.disabledMessageId
).show(activity.supportFragmentManager, MessageDialogFragment.TAG)
}
}
inner class HomeOptionViewHolder(val binding: CardHomeOptionBinding) :
@@ -65,6 +73,12 @@ class HomeSettingAdapter(private val activity: AppCompatActivity, var options: L
R.drawable.premium_background
)
}
if (!option.isEnabled.invoke()) {
binding.optionTitle.alpha = 0.5f
binding.optionDescription.alpha = 0.5f
binding.optionIcon.alpha = 0.5f
}
}
}
}

View File

@@ -73,102 +73,113 @@ class HomeSettingsFragment : Fragment() {
HomeSetting(
R.string.advanced_settings,
R.string.settings_description,
R.drawable.ic_settings
) { SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "") }
R.drawable.ic_settings,
{ SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "") }
)
)
add(
HomeSetting(
R.string.open_user_folder,
R.string.open_user_folder_description,
R.drawable.ic_folder_open
) { openFileManager() }
R.drawable.ic_folder_open,
{ openFileManager() }
)
)
add(
HomeSetting(
R.string.preferences_theme,
R.string.theme_and_color_description,
R.drawable.ic_palette
) { SettingsActivity.launch(requireContext(), Settings.SECTION_THEME, "") }
)
if (GpuDriverHelper.supportsCustomDriverLoading()) {
add(
HomeSetting(
R.string.install_gpu_driver,
R.string.install_gpu_driver_description,
R.drawable.ic_exit
) { driverInstaller() }
R.drawable.ic_palette,
{ SettingsActivity.launch(requireContext(), Settings.SECTION_THEME, "") }
)
}
)
add(
HomeSetting(
R.string.install_gpu_driver,
R.string.install_gpu_driver_description,
R.drawable.ic_exit,
{ driverInstaller() },
{ GpuDriverHelper.supportsCustomDriverLoading() },
R.string.custom_driver_not_supported,
R.string.custom_driver_not_supported_description
)
)
add(
HomeSetting(
R.string.install_amiibo_keys,
R.string.install_amiibo_keys_description,
R.drawable.ic_nfc
) { mainActivity.getAmiiboKey.launch(arrayOf("*/*")) }
R.drawable.ic_nfc,
{ mainActivity.getAmiiboKey.launch(arrayOf("*/*")) }
)
)
add(
HomeSetting(
R.string.install_game_content,
R.string.install_game_content_description,
R.drawable.ic_system_update_alt
) { mainActivity.installGameUpdate.launch(arrayOf("*/*")) }
R.drawable.ic_system_update_alt,
{ mainActivity.installGameUpdate.launch(arrayOf("*/*")) }
)
)
add(
HomeSetting(
R.string.select_games_folder,
R.string.select_games_folder_description,
R.drawable.ic_add
) {
mainActivity.getGamesDirectory.launch(
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data
)
}
R.drawable.ic_add,
{
mainActivity.getGamesDirectory.launch(
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data
)
}
)
)
add(
HomeSetting(
R.string.manage_save_data,
R.string.import_export_saves_description,
R.drawable.ic_save
) {
ImportExportSavesFragment().show(
parentFragmentManager,
ImportExportSavesFragment.TAG
)
}
R.drawable.ic_save,
{
ImportExportSavesFragment().show(
parentFragmentManager,
ImportExportSavesFragment.TAG
)
}
)
)
add(
HomeSetting(
R.string.install_prod_keys,
R.string.install_prod_keys_description,
R.drawable.ic_unlock
) { mainActivity.getProdKey.launch(arrayOf("*/*")) }
R.drawable.ic_unlock,
{ mainActivity.getProdKey.launch(arrayOf("*/*")) }
)
)
add(
HomeSetting(
R.string.install_firmware,
R.string.install_firmware_description,
R.drawable.ic_firmware
) { mainActivity.getFirmware.launch(arrayOf("application/zip")) }
R.drawable.ic_firmware,
{ mainActivity.getFirmware.launch(arrayOf("application/zip")) }
)
)
add(
HomeSetting(
R.string.share_log,
R.string.share_log_description,
R.drawable.ic_log
) { shareLog() }
R.drawable.ic_log,
{ shareLog() }
)
)
add(
HomeSetting(
R.string.about,
R.string.about_description,
R.drawable.ic_info_outline
) {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
parentFragmentManager.primaryNavigationFragment?.findNavController()
?.navigate(R.id.action_homeSettingsFragment_to_aboutFragment)
}
R.drawable.ic_info_outline,
{
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
parentFragmentManager.primaryNavigationFragment?.findNavController()
?.navigate(R.id.action_homeSettingsFragment_to_aboutFragment)
}
)
)
}
@@ -178,12 +189,13 @@ class HomeSettingsFragment : Fragment() {
HomeSetting(
R.string.get_early_access,
R.string.get_early_access_description,
R.drawable.ic_diamond
) {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
parentFragmentManager.primaryNavigationFragment?.findNavController()
?.navigate(R.id.action_homeSettingsFragment_to_earlyAccessFragment)
}
R.drawable.ic_diamond,
{
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
parentFragmentManager.primaryNavigationFragment?.findNavController()
?.navigate(R.id.action_homeSettingsFragment_to_earlyAccessFragment)
}
)
)
}

View File

@@ -7,5 +7,8 @@ data class HomeSetting(
val titleId: Int,
val descriptionId: Int,
val iconId: Int,
val onClick: () -> Unit
val onClick: () -> Unit,
val isEnabled: () -> Boolean = { true },
val disabledTitleId: Int = 0,
val disabledMessageId: Int = 0
)

View File

@@ -113,6 +113,8 @@
<string name="install_game_content_success_install">%1$d installed successfully</string>
<string name="install_game_content_success_overwrite">%1$d overwritten successfully</string>
<string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
<string name="custom_driver_not_supported">Custom drivers not supported</string>
<string name="custom_driver_not_supported_description">Custom driver loading isn\'t currently supported for this device.\nCheck this option again in the future to see if support was added!</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia isn\'t real</string>
@@ -230,7 +232,7 @@
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Your ROM is encrypted</string>
<string name="loader_error_encrypted_roms_description"><![CDATA[Please follow the guides to redump your <a href="https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games">game cartidges</a> or <a href="https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop">installed titles</a>.]]></string>
<string name="loader_error_encrypted_roms_description"><![CDATA[Please follow the guides to redump your <a href="https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards">game cartidges</a> or <a href="https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop">installed titles</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Please ensure your <a href="https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys">prod.keys</a> file is installed so that games can be decrypted.]]></string>
<string name="loader_error_video_core">An error occurred initializing the video core</string>
<string name="loader_error_video_core_description">This is usually caused by an incompatible GPU driver. Installing a custom GPU driver may resolve this problem.</string>

View File

@@ -23,7 +23,7 @@ std::string DemangleSymbol(const std::string& mangled) {
SCOPE_EXIT({ std::free(demangled); });
if (is_itanium(mangled)) {
demangled = llvm::itaniumDemangle(mangled.c_str(), nullptr, nullptr, nullptr);
demangled = llvm::itaniumDemangle(mangled.c_str());
}
if (!demangled) {

View File

@@ -30,8 +30,8 @@ DetachedTasks::~DetachedTasks() {
void DetachedTasks::AddTask(std::function<void()> task) {
std::unique_lock lock{instance->mutex};
++instance->count;
std::thread([task{std::move(task)}]() {
task();
std::thread([task_{std::move(task)}]() {
task_();
std::unique_lock thread_lock{instance->mutex};
--instance->count;
std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock));

View File

@@ -3,9 +3,10 @@
#pragma once
#include "common/common_types.h"
#include <optional>
#include <string>
#include "common/common_types.h"
namespace Network {

View File

@@ -285,6 +285,7 @@ add_library(core STATIC
hle/kernel/kernel.cpp
hle/kernel/kernel.h
hle/kernel/memory_types.h
hle/kernel/message_buffer.h
hle/kernel/physical_core.cpp
hle/kernel/physical_core.h
hle/kernel/physical_memory.h
@@ -875,7 +876,7 @@ elseif (APPLE)
elseif (WIN32)
target_sources(core PRIVATE
hle/service/ssl/ssl_backend_schannel.cpp)
target_link_libraries(core PRIVATE secur32)
target_link_libraries(core PRIVATE crypt32 secur32)
else()
target_sources(core PRIVATE
hle/service/ssl/ssl_backend_none.cpp)

View File

@@ -20,12 +20,132 @@
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/message_buffer.h"
#include "core/hle/service/hle_ipc.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/memory.h"
namespace Kernel {
namespace {
template <bool MoveHandleAllowed>
Result ProcessMessageSpecialData(KProcess& dst_process, KProcess& src_process, KThread& src_thread,
MessageBuffer& dst_msg, const MessageBuffer& src_msg,
MessageBuffer::SpecialHeader& src_special_header) {
// Copy the special header to the destination.
s32 offset = dst_msg.Set(src_special_header);
// Copy the process ID.
if (src_special_header.GetHasProcessId()) {
offset = dst_msg.SetProcessId(offset, src_process.GetProcessId());
}
// Prepare to process handles.
auto& dst_handle_table = dst_process.GetHandleTable();
auto& src_handle_table = src_process.GetHandleTable();
Result result = ResultSuccess;
// Process copy handles.
for (auto i = 0; i < src_special_header.GetCopyHandleCount(); ++i) {
// Get the handles.
const Handle src_handle = src_msg.GetHandle(offset);
Handle dst_handle = Svc::InvalidHandle;
// If we're in a success state, try to move the handle to the new table.
if (R_SUCCEEDED(result) && src_handle != Svc::InvalidHandle) {
KScopedAutoObject obj =
src_handle_table.GetObjectForIpc(src_handle, std::addressof(src_thread));
if (obj.IsNotNull()) {
Result add_result =
dst_handle_table.Add(std::addressof(dst_handle), obj.GetPointerUnsafe());
if (R_FAILED(add_result)) {
result = add_result;
dst_handle = Svc::InvalidHandle;
}
} else {
result = ResultInvalidHandle;
}
}
// Set the handle.
offset = dst_msg.SetHandle(offset, dst_handle);
}
// Process move handles.
if constexpr (MoveHandleAllowed) {
for (auto i = 0; i < src_special_header.GetMoveHandleCount(); ++i) {
// Get the handles.
const Handle src_handle = src_msg.GetHandle(offset);
Handle dst_handle = Svc::InvalidHandle;
// Whether or not we've succeeded, we need to remove the handles from the source table.
if (src_handle != Svc::InvalidHandle) {
if (R_SUCCEEDED(result)) {
KScopedAutoObject obj =
src_handle_table.GetObjectForIpcWithoutPseudoHandle(src_handle);
if (obj.IsNotNull()) {
Result add_result = dst_handle_table.Add(std::addressof(dst_handle),
obj.GetPointerUnsafe());
src_handle_table.Remove(src_handle);
if (R_FAILED(add_result)) {
result = add_result;
dst_handle = Svc::InvalidHandle;
}
} else {
result = ResultInvalidHandle;
}
} else {
src_handle_table.Remove(src_handle);
}
}
// Set the handle.
offset = dst_msg.SetHandle(offset, dst_handle);
}
}
R_RETURN(result);
}
void CleanupSpecialData(KProcess& dst_process, u32* dst_msg_ptr, size_t dst_buffer_size) {
// Parse the message.
const MessageBuffer dst_msg(dst_msg_ptr, dst_buffer_size);
const MessageBuffer::MessageHeader dst_header(dst_msg);
const MessageBuffer::SpecialHeader dst_special_header(dst_msg, dst_header);
// Check that the size is big enough.
if (MessageBuffer::GetMessageBufferSize(dst_header, dst_special_header) > dst_buffer_size) {
return;
}
// Set the special header.
int offset = dst_msg.Set(dst_special_header);
// Clear the process id, if needed.
if (dst_special_header.GetHasProcessId()) {
offset = dst_msg.SetProcessId(offset, 0);
}
// Clear handles, as relevant.
auto& dst_handle_table = dst_process.GetHandleTable();
for (auto i = 0;
i < (dst_special_header.GetCopyHandleCount() + dst_special_header.GetMoveHandleCount());
++i) {
const Handle handle = dst_msg.GetHandle(offset);
if (handle != Svc::InvalidHandle) {
dst_handle_table.Remove(handle);
}
offset = dst_msg.SetHandle(offset, Svc::InvalidHandle);
}
}
} // namespace
using ThreadQueueImplForKServerSessionRequest = KThreadQueue;
KServerSession::KServerSession(KernelCore& kernel)
@@ -223,12 +343,27 @@ Result KServerSession::SendReply(bool is_hle) {
// the reply has already been written in this case.
} else {
Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()};
KThread* server_thread{GetCurrentThreadPointer(m_kernel)};
KThread* server_thread = GetCurrentThreadPointer(m_kernel);
KProcess& src_process = *client_thread->GetOwnerProcess();
KProcess& dst_process = *server_thread->GetOwnerProcess();
UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
auto* src_msg_buffer = memory.GetPointer(server_thread->GetTlsAddress());
auto* dst_msg_buffer = memory.GetPointer(client_message);
auto* src_msg_buffer = memory.GetPointer<u32>(server_thread->GetTlsAddress());
auto* dst_msg_buffer = memory.GetPointer<u32>(client_message);
std::memcpy(dst_msg_buffer, src_msg_buffer, client_buffer_size);
// Translate special header ad-hoc.
MessageBuffer src_msg(src_msg_buffer, client_buffer_size);
MessageBuffer::MessageHeader src_header(src_msg);
MessageBuffer::SpecialHeader src_special_header(src_msg, src_header);
if (src_header.GetHasSpecialHeader()) {
MessageBuffer dst_msg(dst_msg_buffer, client_buffer_size);
result = ProcessMessageSpecialData<true>(dst_process, src_process, *server_thread,
dst_msg, src_msg, src_special_header);
if (R_FAILED(result)) {
CleanupSpecialData(dst_process, dst_msg_buffer, client_buffer_size);
}
}
}
} else {
result = ResultSessionClosed;
@@ -330,12 +465,28 @@ Result KServerSession::ReceiveRequest(std::shared_ptr<Service::HLERequestContext
->PopulateFromIncomingCommandBuffer(client_thread->GetOwnerProcess()->GetHandleTable(),
cmd_buf);
} else {
KThread* server_thread{GetCurrentThreadPointer(m_kernel)};
UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
KThread* server_thread = GetCurrentThreadPointer(m_kernel);
KProcess& src_process = *client_thread->GetOwnerProcess();
KProcess& dst_process = *server_thread->GetOwnerProcess();
UNIMPLEMENTED_IF(client_thread->GetOwnerProcess() != server_thread->GetOwnerProcess());
auto* src_msg_buffer = memory.GetPointer(client_message);
auto* dst_msg_buffer = memory.GetPointer(server_thread->GetTlsAddress());
auto* src_msg_buffer = memory.GetPointer<u32>(client_message);
auto* dst_msg_buffer = memory.GetPointer<u32>(server_thread->GetTlsAddress());
std::memcpy(dst_msg_buffer, src_msg_buffer, client_buffer_size);
// Translate special header ad-hoc.
// TODO: fix this mess
MessageBuffer src_msg(src_msg_buffer, client_buffer_size);
MessageBuffer::MessageHeader src_header(src_msg);
MessageBuffer::SpecialHeader src_special_header(src_msg, src_header);
if (src_header.GetHasSpecialHeader()) {
MessageBuffer dst_msg(dst_msg_buffer, client_buffer_size);
Result res = ProcessMessageSpecialData<false>(dst_process, src_process, *client_thread,
dst_msg, src_msg, src_special_header);
if (R_FAILED(res)) {
CleanupSpecialData(dst_process, dst_msg_buffer, client_buffer_size);
}
}
}
// We succeeded.

View File

@@ -302,12 +302,12 @@ Result KThread::InitializeServiceThread(Core::System& system, KThread* thread,
std::function<void()>&& func, s32 prio, s32 virt_core,
KProcess* owner) {
system.Kernel().GlobalSchedulerContext().AddThread(thread);
std::function<void()> func2{[&system, func{std::move(func)}] {
std::function<void()> func2{[&system, func_{std::move(func)}] {
// Similar to UserModeThreadStarter.
system.Kernel().CurrentScheduler()->OnThreadStart();
// Run the guest function.
func();
func_();
// Exit.
Svc::ExitThread(system);

View File

@@ -1089,15 +1089,15 @@ static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process,
KThread::Register(kernel, thread);
return std::jthread(
[&kernel, thread, thread_name{std::move(thread_name)}, func{std::move(func)}] {
[&kernel, thread, thread_name_{std::move(thread_name)}, func_{std::move(func)}] {
// Set the thread name.
Common::SetCurrentThreadName(thread_name.c_str());
Common::SetCurrentThreadName(thread_name_.c_str());
// Set the thread as current.
kernel.RegisterHostThread(thread);
// Run the callback.
func();
func_();
// Close the thread.
// This will free the process if it is the last reference.

View File

@@ -0,0 +1,612 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/alignment.h"
#include "common/bit_field.h"
#include "core/hle/kernel/k_thread.h"
namespace Kernel {
constexpr inline size_t MessageBufferSize = 0x100;
class MessageBuffer {
public:
class MessageHeader {
private:
static constexpr inline u64 NullTag = 0;
public:
enum class ReceiveListCountType : u32 {
None = 0,
ToMessageBuffer = 1,
ToSingleBuffer = 2,
CountOffset = 2,
CountMax = 13,
};
private:
union {
std::array<u32, 2> raw;
struct {
// Define fields for the first header word.
union {
BitField<0, 16, u16> tag;
BitField<16, 4, u32> pointer_count;
BitField<20, 4, u32> send_count;
BitField<24, 4, u32> receive_count;
BitField<28, 4, u32> exchange_count;
};
// Define fields for the second header word.
union {
BitField<0, 10, u32> raw_count;
BitField<10, 4, ReceiveListCountType> receive_list_count;
BitField<14, 6, u32> reserved0;
BitField<20, 11, u32> receive_list_offset;
BitField<31, 1, u32> has_special_header;
};
};
} m_header;
public:
constexpr MessageHeader() : m_header{} {}
constexpr MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch,
s32 raw, ReceiveListCountType recv_list)
: m_header{} {
m_header.raw[0] = 0;
m_header.raw[1] = 0;
m_header.tag.Assign(tag);
m_header.pointer_count.Assign(ptr);
m_header.send_count.Assign(send);
m_header.receive_count.Assign(recv);
m_header.exchange_count.Assign(exch);
m_header.raw_count.Assign(raw);
m_header.receive_list_count.Assign(recv_list);
m_header.has_special_header.Assign(special);
}
explicit MessageHeader(const MessageBuffer& buf) : m_header{} {
buf.Get(0, m_header.raw.data(), 2);
}
explicit MessageHeader(const u32* msg) : m_header{{msg[0], msg[1]}} {}
constexpr u16 GetTag() const {
return m_header.tag;
}
constexpr s32 GetPointerCount() const {
return m_header.pointer_count;
}
constexpr s32 GetSendCount() const {
return m_header.send_count;
}
constexpr s32 GetReceiveCount() const {
return m_header.receive_count;
}
constexpr s32 GetExchangeCount() const {
return m_header.exchange_count;
}
constexpr s32 GetMapAliasCount() const {
return this->GetSendCount() + this->GetReceiveCount() + this->GetExchangeCount();
}
constexpr s32 GetRawCount() const {
return m_header.raw_count;
}
constexpr ReceiveListCountType GetReceiveListCount() const {
return m_header.receive_list_count;
}
constexpr s32 GetReceiveListOffset() const {
return m_header.receive_list_offset;
}
constexpr bool GetHasSpecialHeader() const {
return m_header.has_special_header.Value() != 0;
}
constexpr void SetReceiveListCount(ReceiveListCountType recv_list) {
m_header.receive_list_count.Assign(recv_list);
}
constexpr const u32* GetData() const {
return m_header.raw.data();
}
static constexpr size_t GetDataSize() {
return sizeof(m_header);
}
};
class SpecialHeader {
private:
union {
std::array<u32, 1> raw;
// Define fields for the header word.
BitField<0, 1, u32> has_process_id;
BitField<1, 4, u32> copy_handle_count;
BitField<5, 4, u32> move_handle_count;
} m_header;
bool m_has_header;
public:
constexpr explicit SpecialHeader(bool pid, s32 copy, s32 move)
: m_header{}, m_has_header(true) {
m_header.has_process_id.Assign(pid);
m_header.copy_handle_count.Assign(copy);
m_header.move_handle_count.Assign(move);
}
constexpr explicit SpecialHeader(bool pid, s32 copy, s32 move, bool _has_header)
: m_header{}, m_has_header(_has_header) {
m_header.has_process_id.Assign(pid);
m_header.copy_handle_count.Assign(copy);
m_header.move_handle_count.Assign(move);
}
explicit SpecialHeader(const MessageBuffer& buf, const MessageHeader& hdr)
: m_header{}, m_has_header(hdr.GetHasSpecialHeader()) {
if (m_has_header) {
buf.Get(static_cast<s32>(MessageHeader::GetDataSize() / sizeof(u32)),
m_header.raw.data(), sizeof(m_header) / sizeof(u32));
}
}
constexpr bool GetHasProcessId() const {
return m_header.has_process_id.Value() != 0;
}
constexpr s32 GetCopyHandleCount() const {
return m_header.copy_handle_count;
}
constexpr s32 GetMoveHandleCount() const {
return m_header.move_handle_count;
}
constexpr const u32* GetHeader() const {
return m_header.raw.data();
}
constexpr size_t GetHeaderSize() const {
if (m_has_header) {
return sizeof(m_header);
} else {
return 0;
}
}
constexpr size_t GetDataSize() const {
if (m_has_header) {
return (this->GetHasProcessId() ? sizeof(u64) : 0) +
(this->GetCopyHandleCount() * sizeof(Handle)) +
(this->GetMoveHandleCount() * sizeof(Handle));
} else {
return 0;
}
}
};
class MapAliasDescriptor {
public:
enum class Attribute : u32 {
Ipc = 0,
NonSecureIpc = 1,
NonDeviceIpc = 3,
};
private:
static constexpr u32 SizeLowCount = 32;
static constexpr u32 SizeHighCount = 4;
static constexpr u32 AddressLowCount = 32;
static constexpr u32 AddressMidCount = 4;
constexpr u32 GetAddressMid(u64 address) {
return static_cast<u32>(address >> AddressLowCount) & ((1U << AddressMidCount) - 1);
}
constexpr u32 GetAddressHigh(u64 address) {
return static_cast<u32>(address >> (AddressLowCount + AddressMidCount));
}
private:
union {
std::array<u32, 3> raw;
struct {
// Define fields for the first two words.
u32 size_low;
u32 address_low;
// Define fields for the packed descriptor word.
union {
BitField<0, 2, Attribute> attributes;
BitField<2, 3, u32> address_high;
BitField<5, 19, u32> reserved;
BitField<24, 4, u32> size_high;
BitField<28, 4, u32> address_mid;
};
};
} m_data;
public:
constexpr MapAliasDescriptor() : m_data{} {}
MapAliasDescriptor(const void* buffer, size_t _size, Attribute attr = Attribute::Ipc)
: m_data{} {
const u64 address = reinterpret_cast<u64>(buffer);
const u64 size = static_cast<u64>(_size);
m_data.size_low = static_cast<u32>(size);
m_data.address_low = static_cast<u32>(address);
m_data.attributes.Assign(attr);
m_data.address_mid.Assign(GetAddressMid(address));
m_data.size_high.Assign(static_cast<u32>(size >> SizeLowCount));
m_data.address_high.Assign(GetAddressHigh(address));
}
MapAliasDescriptor(const MessageBuffer& buf, s32 index) : m_data{} {
buf.Get(index, m_data.raw.data(), 3);
}
constexpr uintptr_t GetAddress() const {
return (static_cast<u64>((m_data.address_high << AddressMidCount) | m_data.address_mid)
<< AddressLowCount) |
m_data.address_low;
}
constexpr uintptr_t GetSize() const {
return (static_cast<u64>(m_data.size_high) << SizeLowCount) | m_data.size_low;
}
constexpr Attribute GetAttribute() const {
return m_data.attributes;
}
constexpr const u32* GetData() const {
return m_data.raw.data();
}
static constexpr size_t GetDataSize() {
return sizeof(m_data);
}
};
class PointerDescriptor {
private:
static constexpr u32 AddressLowCount = 32;
static constexpr u32 AddressMidCount = 4;
constexpr u32 GetAddressMid(u64 address) {
return static_cast<u32>(address >> AddressLowCount) & ((1u << AddressMidCount) - 1);
}
constexpr u32 GetAddressHigh(u64 address) {
return static_cast<u32>(address >> (AddressLowCount + AddressMidCount));
}
private:
union {
std::array<u32, 2> raw;
struct {
// Define fields for the packed descriptor word.
union {
BitField<0, 4, u32> index;
BitField<4, 2, u32> reserved0;
BitField<6, 3, u32> address_high;
BitField<9, 3, u32> reserved1;
BitField<12, 4, u32> address_mid;
BitField<16, 16, u32> size;
};
// Define fields for the second word.
u32 address_low;
};
} m_data;
public:
constexpr PointerDescriptor() : m_data{} {}
PointerDescriptor(const void* buffer, size_t size, s32 index) : m_data{} {
const u64 address = reinterpret_cast<u64>(buffer);
m_data.index.Assign(index);
m_data.address_high.Assign(GetAddressHigh(address));
m_data.address_mid.Assign(GetAddressMid(address));
m_data.size.Assign(static_cast<u32>(size));
m_data.address_low = static_cast<u32>(address);
}
PointerDescriptor(const MessageBuffer& buf, s32 index) : m_data{} {
buf.Get(index, m_data.raw.data(), 2);
}
constexpr s32 GetIndex() const {
return m_data.index;
}
constexpr uintptr_t GetAddress() const {
return (static_cast<u64>((m_data.address_high << AddressMidCount) | m_data.address_mid)
<< AddressLowCount) |
m_data.address_low;
}
constexpr size_t GetSize() const {
return m_data.size;
}
constexpr const u32* GetData() const {
return m_data.raw.data();
}
static constexpr size_t GetDataSize() {
return sizeof(m_data);
}
};
class ReceiveListEntry {
private:
static constexpr u32 AddressLowCount = 32;
constexpr u32 GetAddressHigh(u64 address) {
return static_cast<u32>(address >> (AddressLowCount));
}
private:
union {
std::array<u32, 2> raw;
struct {
// Define fields for the first word.
u32 address_low;
// Define fields for the packed descriptor word.
union {
BitField<0, 7, u32> address_high;
BitField<7, 9, u32> reserved;
BitField<16, 16, u32> size;
};
};
} m_data;
public:
constexpr ReceiveListEntry() : m_data{} {}
ReceiveListEntry(const void* buffer, size_t size) : m_data{} {
const u64 address = reinterpret_cast<u64>(buffer);
m_data.address_low = static_cast<u32>(address);
m_data.address_high.Assign(GetAddressHigh(address));
m_data.size.Assign(static_cast<u32>(size));
}
ReceiveListEntry(u32 a, u32 b) : m_data{{a, b}} {}
constexpr uintptr_t GetAddress() const {
return (static_cast<u64>(m_data.address_high) << AddressLowCount) | m_data.address_low;
}
constexpr size_t GetSize() const {
return m_data.size;
}
constexpr const u32* GetData() const {
return m_data.raw.data();
}
static constexpr size_t GetDataSize() {
return sizeof(m_data);
}
};
private:
u32* m_buffer;
size_t m_size;
public:
constexpr MessageBuffer(u32* b, size_t sz) : m_buffer(b), m_size(sz) {}
constexpr explicit MessageBuffer(u32* b) : m_buffer(b), m_size(MessageBufferSize) {}
constexpr void* GetBufferForDebug() const {
return m_buffer;
}
constexpr size_t GetBufferSize() const {
return m_size;
}
void Get(s32 index, u32* dst, size_t count) const {
// Ensure that this doesn't get re-ordered.
std::atomic_thread_fence(std::memory_order_seq_cst);
// Get the words.
static_assert(sizeof(*dst) == sizeof(*m_buffer));
memcpy(dst, m_buffer + index, count * sizeof(*dst));
}
s32 Set(s32 index, u32* src, size_t count) const {
// Ensure that this doesn't get re-ordered.
std::atomic_thread_fence(std::memory_order_seq_cst);
// Set the words.
memcpy(m_buffer + index, src, count * sizeof(*src));
// Ensure that this doesn't get re-ordered.
std::atomic_thread_fence(std::memory_order_seq_cst);
return static_cast<s32>(index + count);
}
template <typename T>
const T& GetRaw(s32 index) const {
return *reinterpret_cast<const T*>(m_buffer + index);
}
template <typename T>
s32 SetRaw(s32 index, const T& val) const {
*reinterpret_cast<const T*>(m_buffer + index) = val;
return index + (Common::AlignUp(sizeof(val), sizeof(*m_buffer)) / sizeof(*m_buffer));
}
void GetRawArray(s32 index, void* dst, size_t len) const {
memcpy(dst, m_buffer + index, len);
}
void SetRawArray(s32 index, const void* src, size_t len) const {
memcpy(m_buffer + index, src, len);
}
void SetNull() const {
this->Set(MessageHeader());
}
s32 Set(const MessageHeader& hdr) const {
memcpy(m_buffer, hdr.GetData(), hdr.GetDataSize());
return static_cast<s32>(hdr.GetDataSize() / sizeof(*m_buffer));
}
s32 Set(const SpecialHeader& spc) const {
const s32 index = static_cast<s32>(MessageHeader::GetDataSize() / sizeof(*m_buffer));
memcpy(m_buffer + index, spc.GetHeader(), spc.GetHeaderSize());
return static_cast<s32>(index + (spc.GetHeaderSize() / sizeof(*m_buffer)));
}
s32 SetHandle(s32 index, const Handle& hnd) const {
memcpy(m_buffer + index, std::addressof(hnd), sizeof(hnd));
return static_cast<s32>(index + (sizeof(hnd) / sizeof(*m_buffer)));
}
s32 SetProcessId(s32 index, const u64 pid) const {
memcpy(m_buffer + index, std::addressof(pid), sizeof(pid));
return static_cast<s32>(index + (sizeof(pid) / sizeof(*m_buffer)));
}
s32 Set(s32 index, const MapAliasDescriptor& desc) const {
memcpy(m_buffer + index, desc.GetData(), desc.GetDataSize());
return static_cast<s32>(index + (desc.GetDataSize() / sizeof(*m_buffer)));
}
s32 Set(s32 index, const PointerDescriptor& desc) const {
memcpy(m_buffer + index, desc.GetData(), desc.GetDataSize());
return static_cast<s32>(index + (desc.GetDataSize() / sizeof(*m_buffer)));
}
s32 Set(s32 index, const ReceiveListEntry& desc) const {
memcpy(m_buffer + index, desc.GetData(), desc.GetDataSize());
return static_cast<s32>(index + (desc.GetDataSize() / sizeof(*m_buffer)));
}
s32 Set(s32 index, const u32 val) const {
memcpy(m_buffer + index, std::addressof(val), sizeof(val));
return static_cast<s32>(index + (sizeof(val) / sizeof(*m_buffer)));
}
Result GetAsyncResult() const {
MessageHeader hdr(m_buffer);
MessageHeader null{};
if (memcmp(hdr.GetData(), null.GetData(), MessageHeader::GetDataSize()) != 0) [[unlikely]] {
R_SUCCEED();
}
return Result(m_buffer[MessageHeader::GetDataSize() / sizeof(*m_buffer)]);
}
void SetAsyncResult(Result res) const {
const s32 index = this->Set(MessageHeader());
const auto value = res.raw;
memcpy(m_buffer + index, std::addressof(value), sizeof(value));
}
u32 Get32(s32 index) const {
return m_buffer[index];
}
u64 Get64(s32 index) const {
u64 value;
memcpy(std::addressof(value), m_buffer + index, sizeof(value));
return value;
}
u64 GetProcessId(s32 index) const {
return this->Get64(index);
}
Handle GetHandle(s32 index) const {
static_assert(sizeof(Handle) == sizeof(*m_buffer));
return Handle(m_buffer[index]);
}
static constexpr s32 GetSpecialDataIndex(const MessageHeader& hdr, const SpecialHeader& spc) {
return static_cast<s32>((MessageHeader::GetDataSize() / sizeof(u32)) +
(spc.GetHeaderSize() / sizeof(u32)));
}
static constexpr s32 GetPointerDescriptorIndex(const MessageHeader& hdr,
const SpecialHeader& spc) {
return static_cast<s32>(GetSpecialDataIndex(hdr, spc) + (spc.GetDataSize() / sizeof(u32)));
}
static constexpr s32 GetMapAliasDescriptorIndex(const MessageHeader& hdr,
const SpecialHeader& spc) {
return GetPointerDescriptorIndex(hdr, spc) +
static_cast<s32>(hdr.GetPointerCount() * PointerDescriptor::GetDataSize() /
sizeof(u32));
}
static constexpr s32 GetRawDataIndex(const MessageHeader& hdr, const SpecialHeader& spc) {
return GetMapAliasDescriptorIndex(hdr, spc) +
static_cast<s32>(hdr.GetMapAliasCount() * MapAliasDescriptor::GetDataSize() /
sizeof(u32));
}
static constexpr s32 GetReceiveListIndex(const MessageHeader& hdr, const SpecialHeader& spc) {
if (const s32 recv_list_index = hdr.GetReceiveListOffset()) {
return recv_list_index;
} else {
return GetRawDataIndex(hdr, spc) + hdr.GetRawCount();
}
}
static constexpr size_t GetMessageBufferSize(const MessageHeader& hdr,
const SpecialHeader& spc) {
// Get the size of the plain message.
size_t msg_size = GetReceiveListIndex(hdr, spc) * sizeof(u32);
// Add the size of the receive list.
const auto count = hdr.GetReceiveListCount();
switch (count) {
case MessageHeader::ReceiveListCountType::None:
break;
case MessageHeader::ReceiveListCountType::ToMessageBuffer:
break;
case MessageHeader::ReceiveListCountType::ToSingleBuffer:
msg_size += ReceiveListEntry::GetDataSize();
break;
default:
msg_size += (static_cast<s32>(count) -
static_cast<s32>(MessageHeader::ReceiveListCountType::CountOffset)) *
ReceiveListEntry::GetDataSize();
break;
}
return msg_size;
}
};
} // namespace Kernel

View File

@@ -506,8 +506,8 @@ void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
idle_time_detection_extension = rp.Pop<u32>();
LOG_WARNING(Service_AM, "(STUBBED) called idle_time_detection_extension={}",
idle_time_detection_extension);
LOG_DEBUG(Service_AM, "(STUBBED) called idle_time_detection_extension={}",
idle_time_detection_extension);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);

View File

@@ -7,6 +7,7 @@
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/server_manager.h"
#include "network/network.h"
namespace {

View File

@@ -4,14 +4,15 @@
#pragma once
#include "core/hle/service/service.h"
#include "network/network.h"
#include "network/room.h"
#include "network/room_member.h"
namespace Core {
class System;
}
namespace Network {
class RoomNetwork;
}
namespace Service::NIFM {
void LoopProcess(Core::System& system);

View File

@@ -3,15 +3,15 @@
#pragma once
#include "core/hle/result.h"
#include "common/common_types.h"
#include <memory>
#include <span>
#include <string>
#include <vector>
#include "common/common_types.h"
#include "core/hle/result.h"
namespace Network {
class SocketBase;
}

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ssl/ssl_backend.h"
#include "common/logging/log.h"
#include "core/hle/service/ssl/ssl_backend.h"
namespace Service::SSL {
ResultVal<std::unique_ptr<SSLConnectionBackend>> CreateSSLConnectionBackend() {

View File

@@ -1,14 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
#include "common/fs/file.h"
#include "common/hex_util.h"
#include "common/string_util.h"
#include <mutex>
#include <openssl/bio.h>
@@ -16,6 +8,14 @@
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "common/fs/file.h"
#include "common/hex_util.h"
#include "common/string_util.h"
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
using namespace Common::FS;
namespace Service::SSL {

View File

@@ -1,16 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
#include <mutex>
#include "common/error.h"
#include "common/fs/file.h"
#include "common/hex_util.h"
#include "common/string_util.h"
#include <mutex>
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
namespace {
@@ -20,6 +20,7 @@ namespace {
#define SECURITY_WIN32
#include <schnlsp.h>
#include <security.h>
#include <wincrypt.h>
std::once_flag one_time_init_flag;
bool one_time_init_success = false;

View File

@@ -1,18 +1,21 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
#include <mutex>
#include <Security/SecureTransport.h>
// SecureTransport has been deprecated in its entirety in favor of
// Network.framework, but that does not allow layering TLS on top of an
// arbitrary socket.
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <Security/SecureTransport.h>
#pragma GCC diagnostic pop
#endif
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
namespace {

View File

@@ -10,6 +10,7 @@
#include "core/internal_network/network.h"
#include "core/internal_network/network_interface.h"
#include "core/internal_network/socket_proxy.h"
#include "network/network.h"
#if YUZU_UNIX
#include <sys/socket.h>

View File

@@ -10,10 +10,12 @@
#include "common/common_funcs.h"
#include "core/internal_network/sockets.h"
#include "network/network.h"
#include "network/room_member.h"
namespace Network {
class RoomNetwork;
class ProxySocket : public SocketBase {
public:
explicit ProxySocket(RoomNetwork& room_network_) noexcept;

View File

@@ -15,12 +15,13 @@
#include "common/common_types.h"
#include "core/internal_network/network.h"
#include "network/network.h"
// TODO: C++20 Replace std::vector usages with std::span
namespace Network {
struct ProxyPacket;
class SocketBase {
public:
#ifdef YUZU_UNIX

View File

@@ -274,6 +274,7 @@ add_library(video_core STATIC
vulkan_common/vulkan_wrapper.h
vulkan_common/nsight_aftermath_tracker.cpp
vulkan_common/nsight_aftermath_tracker.h
vulkan_common/vma.cpp
)
create_target_directory_groups(video_core)
@@ -291,7 +292,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
add_dependencies(video_core host_shaders)
target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
target_link_libraries(video_core PRIVATE sirit Vulkan::Headers vma)
target_link_libraries(video_core PRIVATE sirit Vulkan::Headers GPUOpen::VulkanMemoryAllocator)
if (ENABLE_NSIGHT_AFTERMATH)
if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK})
@@ -324,6 +325,9 @@ else()
# xbyak
set_source_files_properties(macro/macro_jit_x64.cpp PROPERTIES COMPILE_OPTIONS "-Wno-conversion;-Wno-shadow")
# VMA
set_source_files_properties(vulkan_common/vma.cpp PROPERTIES COMPILE_OPTIONS "-Wno-conversion;-Wno-unused-variable;-Wno-unused-parameter;-Wno-missing-field-initializers")
endif()
if (ARCHITECTURE_x86_64)

View File

@@ -442,6 +442,11 @@ void BufferCache<P>::UnbindComputeStorageBuffers() {
template <class P>
void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset,
bool is_written) {
if (ssbo_index >= channel_state->compute_storage_buffers.size()) [[unlikely]] {
LOG_ERROR(HW_GPU, "Storage buffer index {} exceeds maximum storage buffer count",
ssbo_index);
return;
}
channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index;
channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index;
@@ -464,6 +469,11 @@ void BufferCache<P>::UnbindComputeTextureBuffers() {
template <class P>
void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size,
PixelFormat format, bool is_written, bool is_image) {
if (tbo_index >= channel_state->compute_texture_buffers.size()) [[unlikely]] {
LOG_ERROR(HW_GPU, "Texture buffer index {} exceeds maximum texture buffer count",
tbo_index);
return;
}
channel_state->enabled_compute_texture_buffers |= 1U << tbo_index;
channel_state->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index;
if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) {

View File

@@ -67,7 +67,7 @@ constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4;
constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18;
constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8;
constexpr u32 NUM_STORAGE_BUFFERS = 16;
constexpr u32 NUM_TEXTURE_BUFFERS = 16;
constexpr u32 NUM_TEXTURE_BUFFERS = 32;
constexpr u32 NUM_STAGES = 5;
using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;

View File

@@ -38,8 +38,8 @@ void RendererBase::RequestScreenshot(void* data, std::function<void(bool)> callb
LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request");
return;
}
auto async_callback{[callback = std::move(callback)](bool invert_y) {
std::thread t{callback, invert_y};
auto async_callback{[callback_ = std::move(callback)](bool invert_y) {
std::thread t{callback_, invert_y};
t.detach();
}};
renderer_settings.screenshot_bits = data;

View File

@@ -231,24 +231,25 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
}
const bool in_parallel = thread_worker != nullptr;
const auto backend = device.GetShaderBackend();
auto func{[this, sources = std::move(sources), sources_spirv = std::move(sources_spirv),
auto func{[this, sources_ = std::move(sources), sources_spirv_ = std::move(sources_spirv),
shader_notify, backend, in_parallel,
force_context_flush](ShaderContext::Context*) mutable {
for (size_t stage = 0; stage < 5; ++stage) {
switch (backend) {
case Settings::ShaderBackend::GLSL:
if (!sources[stage].empty()) {
source_programs[stage] = CreateProgram(sources[stage], Stage(stage));
if (!sources_[stage].empty()) {
source_programs[stage] = CreateProgram(sources_[stage], Stage(stage));
}
break;
case Settings::ShaderBackend::GLASM:
if (!sources[stage].empty()) {
assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage));
if (!sources_[stage].empty()) {
assembly_programs[stage] =
CompileProgram(sources_[stage], AssemblyStage(stage));
}
break;
case Settings::ShaderBackend::SPIRV:
if (!sources_spirv[stage].empty()) {
source_programs[stage] = CreateProgram(sources_spirv[stage], Stage(stage));
if (!sources_spirv_[stage].empty()) {
source_programs[stage] = CreateProgram(sources_spirv_[stage], Stage(stage));
}
break;
}

View File

@@ -288,9 +288,9 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const auto load_compute{[&](std::ifstream& file, FileEnvironment env) {
ComputePipelineKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key));
queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
queue_work([this, key, env_ = std::move(env), &state, &callback](Context* ctx) mutable {
ctx->pools.ReleaseContents();
auto pipeline{CreateComputePipeline(ctx->pools, key, env, true)};
auto pipeline{CreateComputePipeline(ctx->pools, key, env_, true)};
std::scoped_lock lock{state.mutex};
if (pipeline) {
compute_cache.emplace(key, std::move(pipeline));
@@ -305,9 +305,9 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) {
GraphicsPipelineKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key));
queue_work([this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable {
queue_work([this, key, envs_ = std::move(envs), &state, &callback](Context* ctx) mutable {
boost::container::static_vector<Shader::Environment*, 5> env_ptrs;
for (auto& env : envs) {
for (auto& env : envs_) {
env_ptrs.push_back(&env);
}
ctx->pools.ReleaseContents();

View File

@@ -206,8 +206,8 @@ public:
const size_t sub_first_offset = static_cast<size_t>(first % 4) * GetQuadsNum(num_indices);
const size_t offset =
(sub_first_offset + GetQuadsNum(first)) * 6ULL * BytesPerIndex(index_type);
scheduler.Record([buffer = *buffer, index_type_, offset](vk::CommandBuffer cmdbuf) {
cmdbuf.BindIndexBuffer(buffer, offset, index_type_);
scheduler.Record([buffer_ = *buffer, index_type_, offset](vk::CommandBuffer cmdbuf) {
cmdbuf.BindIndexBuffer(buffer_, offset, index_type_);
});
}
@@ -528,17 +528,18 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi
buffer_handles.push_back(handle);
}
if (device.IsExtExtendedDynamicStateSupported()) {
scheduler.Record([bindings = std::move(bindings),
buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindVertexBuffers2EXT(
bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(),
bindings.offsets.data(), bindings.sizes.data(), bindings.strides.data());
scheduler.Record([bindings_ = std::move(bindings),
buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindVertexBuffers2EXT(bindings_.min_index,
bindings_.max_index - bindings_.min_index,
buffer_handles_.data(), bindings_.offsets.data(),
bindings_.sizes.data(), bindings_.strides.data());
});
} else {
scheduler.Record([bindings = std::move(bindings),
buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindVertexBuffers(bindings.min_index, bindings.max_index - bindings.min_index,
buffer_handles.data(), bindings.offsets.data());
scheduler.Record([bindings_ = std::move(bindings),
buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindVertexBuffers(bindings_.min_index, bindings_.max_index - bindings_.min_index,
buffer_handles_.data(), bindings_.offsets.data());
});
}
}
@@ -573,11 +574,11 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<
for (u32 index = 0; index < bindings.buffers.size(); ++index) {
buffer_handles.push_back(bindings.buffers[index]->Handle());
}
scheduler.Record([bindings = std::move(bindings),
buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles.size()),
buffer_handles.data(), bindings.offsets.data(),
bindings.sizes.data());
scheduler.Record([bindings_ = std::move(bindings),
buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles_.size()),
buffer_handles_.data(), bindings_.offsets.data(),
bindings_.sizes.data());
});
}

View File

@@ -469,9 +469,9 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
ComputePipelineCacheKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key));
workers.QueueWork([this, key, env = std::move(env), &state, &callback]() mutable {
workers.QueueWork([this, key, env_ = std::move(env), &state, &callback]() mutable {
ShaderPools pools;
auto pipeline{CreateComputePipeline(pools, key, env, state.statistics.get(), false)};
auto pipeline{CreateComputePipeline(pools, key, env_, state.statistics.get(), false)};
std::scoped_lock lock{state.mutex};
if (pipeline) {
compute_cache.emplace(key, std::move(pipeline));
@@ -500,10 +500,10 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
(key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) {
return;
}
workers.QueueWork([this, key, envs = std::move(envs), &state, &callback]() mutable {
workers.QueueWork([this, key, envs_ = std::move(envs), &state, &callback]() mutable {
ShaderPools pools;
boost::container::static_vector<Shader::Environment*, 5> env_ptrs;
for (auto& env : envs) {
for (auto& env : envs_) {
env_ptrs.push_back(&env);
}
auto pipeline{CreateGraphicsPipeline(pools, key, MakeSpan(env_ptrs),
@@ -702,8 +702,8 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
if (!pipeline || pipeline_cache_filename.empty()) {
return pipeline;
}
serialization_thread.QueueWork([this, key, env = std::move(env)] {
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
serialization_thread.QueueWork([this, key, env_ = std::move(env)] {
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env_},
pipeline_cache_filename, CACHE_VERSION);
});
return pipeline;

View File

@@ -98,10 +98,10 @@ HostCounter::HostCounter(QueryCache& cache_, std::shared_ptr<HostCounter> depend
: HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_},
query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} {
const vk::Device* logical = &cache.GetDevice().GetLogical();
cache.GetScheduler().Record([logical, query = query](vk::CommandBuffer cmdbuf) {
cache.GetScheduler().Record([logical, query_ = query](vk::CommandBuffer cmdbuf) {
const bool use_precise = Settings::IsGPULevelHigh();
logical->ResetQueryPool(query.first, query.second, 1);
cmdbuf.BeginQuery(query.first, query.second,
logical->ResetQueryPool(query_.first, query_.second, 1);
cmdbuf.BeginQuery(query_.first, query_.second,
use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0);
});
}
@@ -111,8 +111,9 @@ HostCounter::~HostCounter() {
}
void HostCounter::EndQuery() {
cache.GetScheduler().Record(
[query = query](vk::CommandBuffer cmdbuf) { cmdbuf.EndQuery(query.first, query.second); });
cache.GetScheduler().Record([query_ = query](vk::CommandBuffer cmdbuf) {
cmdbuf.EndQuery(query_.first, query_.second);
});
}
u64 HostCounter::BlockingQuery(bool async) const {

View File

@@ -1412,7 +1412,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceS
}
scheduler->RequestOutsideRenderPassOperationContext();
scheduler->Record([buffers = std::move(buffers_vector), image = *original_image,
aspect_mask = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
@@ -1424,7 +1424,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceS
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange{
.aspectMask = aspect_mask,
.aspectMask = aspect_mask_,
.baseMipLevel = 0,
.levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0,
@@ -1456,7 +1456,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceS
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange{
.aspectMask = aspect_mask,
.aspectMask = aspect_mask_,
.baseMipLevel = 0,
.levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0,

View File

@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#define VMA_IMPLEMENTATION
#define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
#include <vk_mem_alloc.h>

View File

@@ -135,11 +135,11 @@ void RoomJson::Delete() {
LOG_ERROR(WebService, "Room must be registered to be deleted");
return;
}
Common::DetachedTasks::AddTask(
[host{this->host}, username{this->username}, token{this->token}, room_id{this->room_id}]() {
// create a new client here because the this->client might be destroyed.
Client{host, username, token}.DeleteJson(fmt::format("/lobby/{}", room_id), "", false);
});
Common::DetachedTasks::AddTask([host_{this->host}, username_{this->username},
token_{this->token}, room_id_{this->room_id}]() {
// create a new client here because the this->client might be destroyed.
Client{host_, username_, token_}.DeleteJson(fmt::format("/lobby/{}", room_id_), "", false);
});
}
} // namespace WebService