Compare commits

...

7 Commits

Author SHA1 Message Date
lizzie
518b806473 oops 2025-12-26 06:42:20 +01:00
lizzie
8f6e23bba0 [host_memory] avoid doing syscall for a simple memset() op 2025-12-26 06:42:20 +01:00
xbzk
cfae726289 [video_core] nvn descriptor layout fix (#3206)
Yxzx presumes this:
// The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size.
But in MCI i`ve discovered that there are no sizes, both registers are GPU addresses (hence the 2.8gb allocation, it was an address actually)

Method could be much simpler but for safety i`ve routed both old and new worlds.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3206
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2025-12-26 04:54:14 +01:00
Gamer64
bb94cff886 [chore] Fixed a couple memory leaks using up ~15 MB each iteration (#398)
Co-authored-by: Jarrod Norwell <official.antique@gmail.com>
Co-authored-by: Gamer64 <76565986+Gamer64ytb@users.noreply.github.com>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/398
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: Gamer64 <gamer64@eden-emu.dev>
Co-committed-by: Gamer64 <gamer64@eden-emu.dev>
2025-12-26 02:55:52 +01:00
lizzie
370997f42e [externals/ffmpeg] remove --disable-postproc causing issues in OpenOrbis toolchain (#3203)
why was disable-postproc added? either way this fixes build errors not only on PS4 but also on Haiku i think

Signed-off-by: lizzie lizzie@eden-emu.dev

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3203
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-12-26 02:36:08 +01:00
crueter
5213cc5689 Revert "[vk] Correct polygon draw topology mapping for line and point modes (#2834)" (#3158)
This reverts commit 6ba25b6cc0.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3158
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-12-26 02:33:53 +01:00
lizzie
bc9af86269 [externals] update Vulkan headers from 1.4.328.1 -> 1.4.335.0 (#3202)
notably adds access to `VK_KHR_maintenance10` :)
I'm not sure if we want to update vk as regularly as with other deps as the only worthwhile change I saw was the addition of maintainance10
Signed-off-by: lizzie lizzie@eden-emu.dev

Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3202
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-12-25 20:48:28 +01:00
32 changed files with 142 additions and 379 deletions

View File

@@ -96,8 +96,8 @@
"package": "VVL", "package": "VVL",
"repo": "KhronosGroup/Vulkan-ValidationLayers", "repo": "KhronosGroup/Vulkan-ValidationLayers",
"tag": "vulkan-sdk-%VERSION%", "tag": "vulkan-sdk-%VERSION%",
"git_version": "1.4.328.1", "git_version": "1.4.335.0",
"artifact": "android-binaries-%VERSION%.zip", "artifact": "android-binaries-%VERSION%.zip",
"hash": "5ec895a453cb7c2f156830b9766953a0c2bd44dea99e6a3dac4160305041ccd3e87534b4ce0bd102392178d2a8eca48411856298f9395e60117cdfe89f72137e" "hash": "48167c4a17736301bd08f9290f41830443e1f18cce8ad867fc6f289b49e18b40e93c9850b377951af82f51b5b6d7313aa6a884fc5df79f5ce3df82696c1c1244"
} }
} }

View File

@@ -119,10 +119,10 @@
"package": "VulkanUtilityLibraries", "package": "VulkanUtilityLibraries",
"repo": "scripts/VulkanUtilityHeaders", "repo": "scripts/VulkanUtilityHeaders",
"tag": "%VERSION%", "tag": "%VERSION%",
"git_version": "1.4.328", "git_version": "1.4.335",
"artifact": "VulkanUtilityHeaders.tar.zst", "artifact": "VulkanUtilityHeaders.tar.zst",
"git_host": "git.crueter.xyz", "git_host": "git.crueter.xyz",
"hash": "9922217b39faf73cd4fc1510f2fdba14a49aa5c0d77f9ee24ee0512cef16b234d0cabc83c1fec861fa5df1d43e7f086ca9b6501753899119f39c5ca530cb0dae" "hash": "16dac0e6586702580c4279e4cd37ffe3cf909c93eb31b5069da7af36436d47b270a9cbaac953bb66c22ed12ed67ffa096688599267f307dfb62be1bc09f79833"
}, },
"spirv-tools": { "spirv-tools": {
"package": "SPIRV-Tools", "package": "SPIRV-Tools",

View File

@@ -217,7 +217,6 @@ else()
--disable-ffmpeg --disable-ffmpeg
--disable-ffprobe --disable-ffprobe
--disable-network --disable-network
--disable-postproc
--disable-swresample --disable-swresample
--enable-decoder=h264 --enable-decoder=h264
--enable-decoder=vp8 --enable-decoder=vp8

View File

@@ -39,7 +39,6 @@ android {
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
buildConfig = true
} }
compileOptions { compileOptions {

View File

@@ -14,6 +14,8 @@ android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete": # Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official kotlin.code.style=official
kotlin.parallel.tasks.in.project=true kotlin.parallel.tasks.in.project=true
android.defaults.buildfeatures.buildconfig=true
# Android Gradle plugin 8.0.2 # Android Gradle plugin 8.0.2
android.suppressUnsupportedCompileSdk=34 android.suppressUnsupportedCompileSdk=34
android.native.buildOutput=verbose android.native.buildOutput=verbose

View File

@@ -34,8 +34,8 @@ struct Member {
struct RoomInformation { struct RoomInformation {
std::string name; ///< Name of the server std::string name; ///< Name of the server
std::string description; ///< Server description std::string description; ///< Server description
u32 member_slots; ///< Maximum number of members in this room u32 member_slots{}; ///< Maximum number of members in this room
u16 port; ///< The port of this room u16 port{}; ///< The port of this room
GameInfo preferred_game; ///< Game to advertise that you want to play GameInfo preferred_game; ///< Game to advertise that you want to play
std::string host_username; ///< Forum username of the host std::string host_username; ///< Forum username of the host
}; };
@@ -46,8 +46,8 @@ struct Room {
std::string id; std::string id;
std::string verify_uid; ///< UID used for verification std::string verify_uid; ///< UID used for verification
std::string ip; std::string ip;
u32 net_version; u32 net_version{};
bool has_password; bool has_password = false;
std::vector<Member> members; std::vector<Member> members;
}; };

View File

@@ -219,11 +219,6 @@ public:
} }
} }
bool ClearBackingRegion(size_t physical_offset, size_t length) {
// TODO: This does not seem to be possible on Windows.
return false;
}
void EnableDirectMappedAddress() { void EnableDirectMappedAddress() {
// TODO // TODO
UNREACHABLE(); UNREACHABLE();
@@ -617,24 +612,6 @@ public:
ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno)); ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno));
} }
bool ClearBackingRegion(size_t physical_offset, size_t length) {
#ifdef __linux__
// Only incur syscall cost IF memset would be slower (theshold = 16MiB)
// TODO(lizzie): Smarter way to dynamically get this threshold (broadwell != raptor lake) for example
if (length >= 2097152UL * 8) {
// Set MADV_REMOVE on backing map to destroy it instantly.
// This also deletes the area from the backing file.
int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE);
ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno));
return true;
} else {
return false;
}
#else
return false;
#endif
}
void EnableDirectMappedAddress() { void EnableDirectMappedAddress() {
virtual_base = nullptr; virtual_base = nullptr;
} }
@@ -762,9 +739,7 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission
} }
void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) { void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) {
if (!impl || fill_value != 0 || !impl->ClearBackingRegion(physical_offset, length)) { std::memset(backing_base + physical_offset, fill_value, length);
std::memset(backing_base + physical_offset, fill_value, length);
}
} }
void HostMemory::EnableDirectMappedAddress() { void HostMemory::EnableDirectMappedAddress() {

View File

@@ -21,7 +21,7 @@ namespace Core::Frontend {
struct CabinetParameters { struct CabinetParameters {
Service::NFP::TagInfo tag_info; Service::NFP::TagInfo tag_info;
Service::NFP::RegisterInfo register_info; Service::NFP::RegisterInfo register_info;
Service::NFP::CabinetMode mode; Service::NFP::CabinetMode mode{};
}; };
using CabinetCallback = std::function<void(bool, const std::string&)>; using CabinetCallback = std::function<void(bool, const std::string&)>;

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -20,9 +23,9 @@ struct KeyboardInitializeParameters {
std::u16string initial_text; std::u16string initial_text;
char16_t left_optional_symbol_key; char16_t left_optional_symbol_key;
char16_t right_optional_symbol_key; char16_t right_optional_symbol_key;
u32 max_text_length; u32 max_text_length{};
u32 min_text_length; u32 min_text_length{};
s32 initial_cursor_position; s32 initial_cursor_position{};
Service::AM::Frontend::SwkbdType type; Service::AM::Frontend::SwkbdType type;
Service::AM::Frontend::SwkbdPasswordMode password_mode; Service::AM::Frontend::SwkbdPasswordMode password_mode;
Service::AM::Frontend::SwkbdTextDrawType text_draw_type; Service::AM::Frontend::SwkbdTextDrawType text_draw_type;
@@ -34,12 +37,12 @@ struct KeyboardInitializeParameters {
}; };
struct InlineAppearParameters { struct InlineAppearParameters {
u32 max_text_length; u32 max_text_length{};
u32 min_text_length; u32 min_text_length{};
f32 key_top_scale_x; f32 key_top_scale_x{};
f32 key_top_scale_y; f32 key_top_scale_y{};
f32 key_top_translate_x; f32 key_top_translate_x{};
f32 key_top_translate_y; f32 key_top_translate_y{};
Service::AM::Frontend::SwkbdType type; Service::AM::Frontend::SwkbdType type;
Service::AM::Frontend::SwkbdKeyDisableFlags key_disable_flags; Service::AM::Frontend::SwkbdKeyDisableFlags key_disable_flags;
bool key_top_as_floating; bool key_top_as_floating;
@@ -50,7 +53,7 @@ struct InlineAppearParameters {
struct InlineTextParameters { struct InlineTextParameters {
std::u16string input_text; std::u16string input_text;
s32 cursor_position; s32 cursor_position{};
}; };
class SoftwareKeyboardApplet : public Applet { class SoftwareKeyboardApplet : public Applet {

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@@ -79,7 +82,7 @@ using DeviceHandle = u64;
// This is nn::nfc::TagInfo // This is nn::nfc::TagInfo
struct TagInfo { struct TagInfo {
UniqueSerialNumber uuid; UniqueSerialNumber uuid{};
u8 uuid_length; u8 uuid_length;
INSERT_PADDING_BYTES(0x15); INSERT_PADDING_BYTES(0x15);
NfcProtocol protocol; NfcProtocol protocol;

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@@ -315,7 +318,7 @@ static_assert(sizeof(ModelInfo) == 0x40, "ModelInfo is an invalid size");
// This is nn::nfp::RegisterInfo // This is nn::nfp::RegisterInfo
struct RegisterInfo { struct RegisterInfo {
Service::Mii::CharInfo mii_char_info; Service::Mii::CharInfo mii_char_info;
WriteDate creation_date; WriteDate creation_date{};
AmiiboName amiibo_name; AmiiboName amiibo_name;
u8 font_region; u8 font_region;
INSERT_PADDING_BYTES(0x7A); INSERT_PADDING_BYTES(0x7A);

View File

@@ -164,7 +164,7 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch
// Rebuild shared fonts from data ncas or synthesize // Rebuild shared fonts from data ncas or synthesize
impl->shared_font = std::make_shared<Kernel::PhysicalMemory>(SHARED_FONT_MEM_SIZE); impl->shared_font = std::make_shared<Kernel::PhysicalMemory>(SHARED_FONT_MEM_SIZE);
for (auto font : SHARED_FONTS) { for (auto& font : SHARED_FONTS) {
FileSys::VirtualFile romfs; FileSys::VirtualFile romfs;
const auto nca = const auto nca =
nand->GetEntry(static_cast<u64>(font.first), FileSys::ContentRecordType::Data); nand->GetEntry(static_cast<u64>(font.first), FileSys::ContentRecordType::Data);
@@ -261,7 +261,7 @@ Result IPlatformServiceManager::GetSharedFontInOrderOfPriority(
out_font_sizes.size(), impl->shared_font_regions.size()}); out_font_sizes.size(), impl->shared_font_regions.size()});
for (size_t i = 0; i < max_size; i++) { for (size_t i = 0; i < max_size; i++) {
auto region = impl->GetSharedFontRegion(i); auto& region = impl->GetSharedFontRegion(i);
out_font_codes[i] = static_cast<u32>(i); out_font_codes[i] = static_cast<u32>(i);
out_font_offsets[i] = region.offset; out_font_offsets[i] = region.offset;

View File

@@ -48,7 +48,7 @@ private:
void Save(); void Save();
PlayTimeDatabase database; PlayTimeDatabase database;
u64 running_program_id; u64 running_program_id{};
std::jthread play_time_thread; std::jthread play_time_thread;
}; };

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -53,7 +56,7 @@ struct ChatEntry {
/// Represents a system status message. /// Represents a system status message.
struct StatusMessageEntry { struct StatusMessageEntry {
StatusMessageTypes type; ///< Type of the message StatusMessageTypes type{}; ///< Type of the message
/// Subject of the message. i.e. the user who is joining/leaving/being banned, etc. /// Subject of the message. i.e. the user who is joining/leaving/being banned, etc.
std::string nickname; std::string nickname;
std::string username; std::string username;

View File

@@ -7,7 +7,6 @@
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <cstring>
#include <memory> #include <memory>
#include <numeric> #include <numeric>
@@ -16,8 +15,6 @@
#include "video_core/guest_memory.h" #include "video_core/guest_memory.h"
#include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/host1x/gpu_device_memory_manager.h"
#include "video_core/texture_cache/util.h" #include "video_core/texture_cache/util.h"
#include "video_core/polygon_mode_utils.h"
#include "video_core/renderer_vulkan/line_loop_utils.h"
namespace VideoCommon { namespace VideoCommon {
@@ -356,37 +353,14 @@ void BufferCache<P>::UpdateComputeBuffers() {
template <class P> template <class P>
void BufferCache<P>::BindHostGeometryBuffers(bool is_indexed) { void BufferCache<P>::BindHostGeometryBuffers(bool is_indexed) {
const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
if (is_indexed) { if (is_indexed) {
BindHostIndexBuffer(); BindHostIndexBuffer();
} else { } else if constexpr (!HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
if constexpr (!P::IS_OPENGL) { const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
const auto polygon_mode = VideoCore::EffectivePolygonMode(maxwell3d->regs); if (draw_state.topology == Maxwell::PrimitiveTopology::Quads ||
if (draw_state.topology == Maxwell::PrimitiveTopology::Polygon && draw_state.topology == Maxwell::PrimitiveTopology::QuadStrip) {
polygon_mode == Maxwell::PolygonMode::Line && draw_state.vertex_buffer.count > 1) { runtime.BindQuadIndexBuffer(draw_state.topology, draw_state.vertex_buffer.first,
const u32 vertex_count = draw_state.vertex_buffer.count; draw_state.vertex_buffer.count);
const u32 generated_count = vertex_count + 1;
const bool use_u16 = vertex_count <= 0x10000;
const u32 element_size = use_u16 ? sizeof(u16) : sizeof(u32);
auto staging = runtime.UploadStagingBuffer(
static_cast<size_t>(generated_count) * element_size);
std::span<u8> dst_span{staging.mapped_span.data(),
generated_count * static_cast<size_t>(element_size)};
Vulkan::LineLoop::GenerateSequentialWithClosureRaw(dst_span, element_size);
const auto synthetic_format = use_u16 ? Maxwell::IndexFormat::UnsignedShort
: Maxwell::IndexFormat::UnsignedInt;
runtime.BindIndexBuffer(draw_state.topology, synthetic_format,
draw_state.vertex_buffer.first, generated_count,
staging.buffer, static_cast<u32>(staging.offset),
generated_count * element_size);
}
}
if constexpr (!HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
if (draw_state.topology == Maxwell::PrimitiveTopology::Quads ||
draw_state.topology == Maxwell::PrimitiveTopology::QuadStrip) {
runtime.BindQuadIndexBuffer(draw_state.topology, draw_state.vertex_buffer.first,
draw_state.vertex_buffer.count);
}
} }
} }
BindHostVertexBuffers(); BindHostVertexBuffers();
@@ -715,44 +689,6 @@ void BufferCache<P>::BindHostIndexBuffer() {
const u32 offset = buffer.Offset(channel_state->index_buffer.device_addr); const u32 offset = buffer.Offset(channel_state->index_buffer.device_addr);
const u32 size = channel_state->index_buffer.size; const u32 size = channel_state->index_buffer.size;
const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
if constexpr (!P::IS_OPENGL) {
const auto polygon_mode = VideoCore::EffectivePolygonMode(maxwell3d->regs);
const bool polygon_line =
draw_state.topology == Maxwell::PrimitiveTopology::Polygon &&
polygon_mode == Maxwell::PolygonMode::Line;
if (polygon_line && draw_state.index_buffer.count > 1) {
const u32 element_size = draw_state.index_buffer.FormatSizeInBytes();
const size_t src_bytes = static_cast<size_t>(draw_state.index_buffer.count) * element_size;
const size_t total_bytes = src_bytes + element_size;
auto staging = runtime.UploadStagingBuffer(total_bytes);
std::span<u8> dst_span{staging.mapped_span.data(), total_bytes};
std::span<const u8> src_span;
if (!draw_state.inline_index_draw_indexes.empty()) {
const u8* const src =
draw_state.inline_index_draw_indexes.data() +
static_cast<size_t>(draw_state.index_buffer.first) * element_size;
src_span = {src, src_bytes};
} else if (const u8* const cpu_base =
device_memory.GetPointer<u8>(channel_state->index_buffer.device_addr)) {
const u8* const src = cpu_base +
static_cast<size_t>(draw_state.index_buffer.first) * element_size;
src_span = {src, src_bytes};
} else {
const DAddr src_addr =
channel_state->index_buffer.device_addr +
static_cast<DAddr>(draw_state.index_buffer.first) * element_size;
device_memory.ReadBlockUnsafe(src_addr, dst_span.data(), src_bytes);
src_span = {dst_span.data(), src_bytes};
}
Vulkan::LineLoop::CopyWithClosureRaw(dst_span, src_span, element_size);
buffer.MarkUsage(offset, size);
runtime.BindIndexBuffer(draw_state.topology, draw_state.index_buffer.format,
draw_state.index_buffer.first, draw_state.index_buffer.count + 1,
staging.buffer, static_cast<u32>(staging.offset),
static_cast<u32>(total_bytes));
return;
}
}
if (!draw_state.inline_index_draw_indexes.empty()) [[unlikely]] { if (!draw_state.inline_index_draw_indexes.empty()) [[unlikely]] {
if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) { if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
auto upload_staging = runtime.UploadStagingBuffer(size); auto upload_staging = runtime.UploadStagingBuffer(size);
@@ -1769,21 +1705,26 @@ Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index,
return NULL_BINDING; return NULL_BINDING;
} }
// xbzk: New size logic. Fixes MCI.
// If ever the * comment below prove wrong, the 'if' block may be removed.
const auto size = [&]() { const auto size = [&]() {
const bool is_nvn_cbuf = cbuf_index == 0; const bool is_nvn_cbuf = cbuf_index == 0;
// The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size.
if (is_nvn_cbuf) { if (is_nvn_cbuf) {
const u32 ssbo_size = gpu_memory->Read<u32>(ssbo_addr + 8); // * The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size.
if (ssbo_size != 0) { const u64 next_qword = gpu_memory->Read<u64>(ssbo_addr + 8);
return ssbo_size; const u32 upper_32 = static_cast<u32>(next_qword >> 32);
// Hardware-based detection: GPU addresses have non-zero upper bits
if (upper_32 == 0) {
// This is a size field, not a GPU address
return static_cast<u32>(next_qword); // Return lower_32
} }
} }
// Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined // Fall through: either not NVN cbuf (Doom Eternal & +), or NVN but ssbo_addr+8 is a GPU address (MCI)
// cbufs, which do not store the sizes adjacent to the addresses, so use the fully
// mapped buffer size for now.
const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr));
// Cap at 8MB to prevent allocator overflow from misinterpreted addresses
return (std::min)(memory_layout_size, static_cast<u32>(8_MiB)); return (std::min)(memory_layout_size, static_cast<u32>(8_MiB));
}(); }();
// Alignment only applies to the offset of the buffer // Alignment only applies to the offset of the buffer
const u32 alignment = runtime.GetStorageBufferAlignment(); const u32 alignment = runtime.GetStorageBufferAlignment();
const GPUVAddr aligned_gpu_addr = Common::AlignDown(gpu_addr, alignment); const GPUVAddr aligned_gpu_addr = Common::AlignDown(gpu_addr, alignment);

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project // SPDX-FileCopyrightText: 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@@ -17,7 +20,7 @@ void Scheduler::Push(s32 channel, CommandList&& entries) {
std::unique_lock lk(scheduling_guard); std::unique_lock lk(scheduling_guard);
auto it = channels.find(channel); auto it = channels.find(channel);
ASSERT(it != channels.end()); ASSERT(it != channels.end());
auto channel_state = it->second; auto& channel_state = it->second;
gpu.BindChannel(channel_state->bind_id); gpu.BindChannel(channel_state->bind_id);
channel_state->dma_pusher->Push(std::move(entries)); channel_state->dma_pusher->Push(std::move(entries));
channel_state->dma_pusher->DispatchCalls(); channel_state->dma_pusher->DispatchCalls();

View File

@@ -1,46 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "video_core/engines/maxwell_3d.h"
namespace VideoCore {
inline Tegra::Engines::Maxwell3D::Regs::PolygonMode EffectivePolygonMode(
const Tegra::Engines::Maxwell3D::Regs& regs) {
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
const bool cull_enabled = regs.gl_cull_test_enabled != 0;
const auto cull_face = regs.gl_cull_face;
const bool cull_front = cull_enabled && (cull_face == Maxwell::CullFace::Front ||
cull_face == Maxwell::CullFace::FrontAndBack);
const bool cull_back = cull_enabled && (cull_face == Maxwell::CullFace::Back ||
cull_face == Maxwell::CullFace::FrontAndBack);
const bool render_front = !cull_front;
const bool render_back = !cull_back;
const auto front_mode = regs.polygon_mode_front;
const auto back_mode = regs.polygon_mode_back;
if (render_front && render_back && front_mode != back_mode) {
if (front_mode == Maxwell::PolygonMode::Line || back_mode == Maxwell::PolygonMode::Line) {
return Maxwell::PolygonMode::Line;
}
if (front_mode == Maxwell::PolygonMode::Point || back_mode == Maxwell::PolygonMode::Point) {
return Maxwell::PolygonMode::Point;
}
}
if (render_front) {
return front_mode;
}
if (render_back) {
return back_mode;
}
return front_mode;
}
} // namespace VideoCore

View File

@@ -15,7 +15,6 @@
#include "video_core/engines/draw_manager.h" #include "video_core/engines/draw_manager.h"
#include "video_core/renderer_vulkan/fixed_pipeline_state.h" #include "video_core/renderer_vulkan/fixed_pipeline_state.h"
#include "video_core/renderer_vulkan/vk_state_tracker.h" #include "video_core/renderer_vulkan/vk_state_tracker.h"
#include "video_core/polygon_mode_utils.h"
namespace Vulkan { namespace Vulkan {
namespace { namespace {
@@ -66,7 +65,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0); dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0);
xfb_enabled.Assign(regs.transform_feedback_enabled != 0); xfb_enabled.Assign(regs.transform_feedback_enabled != 0);
ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
polygon_mode.Assign(PackPolygonMode(VideoCore::EffectivePolygonMode(regs))); polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front));
tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value())); tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value()));
tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value())); tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value()));
tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() == tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() ==

View File

@@ -1,68 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <algorithm>
#include <cstring>
#include <span>
#include "common/assert.h"
#include "common/common_types.h"
namespace Vulkan::LineLoop {
inline void CopyWithClosureRaw(std::span<u8> dst, std::span<const u8> src, size_t element_size) {
ASSERT_MSG(dst.size() == src.size() + element_size, "Invalid line loop copy sizes");
if (src.empty()) {
if (!dst.empty()) {
std::fill(dst.begin(), dst.end(), u8{0});
}
return;
}
std::memcpy(dst.data(), src.data(), src.size());
std::memcpy(dst.data() + src.size(), src.data(), element_size);
}
inline void GenerateSequentialWithClosureRaw(std::span<u8> dst, size_t element_size,
u64 start_value = 0) {
if (dst.empty()) {
return;
}
const size_t last = dst.size() - element_size;
size_t offset = 0;
u64 value = start_value;
while (offset < last) {
std::memcpy(dst.data() + offset, &value, element_size);
offset += element_size;
++value;
}
std::memcpy(dst.data() + offset, &start_value, element_size);
}
template <typename T>
inline void CopyWithClosure(std::span<T> dst, std::span<const T> src) {
ASSERT_MSG(dst.size() == src.size() + 1, "Invalid destination size for line loop copy");
if (src.empty()) {
if (!dst.empty()) {
dst.front() = {};
}
return;
}
std::copy(src.begin(), src.end(), dst.begin());
dst.back() = src.front();
}
template <typename T>
inline void GenerateSequentialWithClosure(std::span<T> dst, T start_value = {}) {
if (dst.empty()) {
return;
}
const size_t last = dst.size() - 1;
for (size_t i = 0; i < last; ++i) {
dst[i] = static_cast<T>(start_value + static_cast<T>(i));
}
dst.back() = start_value;
}
} // namespace Vulkan::LineLoop

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -326,9 +323,44 @@ VkShaderStageFlagBits ShaderStage(Shader::Stage stage) {
} }
VkPrimitiveTopology PrimitiveTopology([[maybe_unused]] const Device& device, VkPrimitiveTopology PrimitiveTopology([[maybe_unused]] const Device& device,
Maxwell::PrimitiveTopology topology, Maxwell::PrimitiveTopology topology) {
Maxwell::PolygonMode polygon_mode) { switch (topology) {
return detail::PrimitiveTopologyNoDevice(topology, polygon_mode); case Maxwell::PrimitiveTopology::Points:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case Maxwell::PrimitiveTopology::Lines:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case Maxwell::PrimitiveTopology::LineLoop:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case Maxwell::PrimitiveTopology::LineStrip:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case Maxwell::PrimitiveTopology::Triangles:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case Maxwell::PrimitiveTopology::TriangleStrip:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case Maxwell::PrimitiveTopology::TriangleFan:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case Maxwell::PrimitiveTopology::LinesAdjacency:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::LineStripAdjacency:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::Quads:
case Maxwell::PrimitiveTopology::QuadStrip:
// TODO: Use VK_PRIMITIVE_TOPOLOGY_QUAD_LIST_EXT/VK_PRIMITIVE_TOPOLOGY_QUAD_STRIP_EXT
// whenever it releases
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case Maxwell::PrimitiveTopology::Patches:
return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
case Maxwell::PrimitiveTopology::Polygon:
LOG_WARNING(Render_Vulkan, "Draw mode is Polygon with a polygon mode of lines should be a "
"single body and not a bunch of triangles.");
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
}
UNIMPLEMENTED_MSG("Unimplemented topology={}", topology);
return {};
} }
VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -18,52 +15,6 @@ namespace Vulkan::MaxwellToVK {
using Maxwell = Tegra::Engines::Maxwell3D::Regs; using Maxwell = Tegra::Engines::Maxwell3D::Regs;
using PixelFormat = VideoCore::Surface::PixelFormat; using PixelFormat = VideoCore::Surface::PixelFormat;
namespace detail {
constexpr VkPrimitiveTopology PrimitiveTopologyNoDevice(Maxwell::PrimitiveTopology topology,
Maxwell::PolygonMode polygon_mode) {
switch (topology) {
case Maxwell::PrimitiveTopology::Points:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case Maxwell::PrimitiveTopology::Lines:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case Maxwell::PrimitiveTopology::LineLoop:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case Maxwell::PrimitiveTopology::LineStrip:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case Maxwell::PrimitiveTopology::Triangles:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case Maxwell::PrimitiveTopology::TriangleStrip:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case Maxwell::PrimitiveTopology::TriangleFan:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case Maxwell::PrimitiveTopology::LinesAdjacency:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::LineStripAdjacency:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
case Maxwell::PrimitiveTopology::Quads:
case Maxwell::PrimitiveTopology::QuadStrip:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case Maxwell::PrimitiveTopology::Patches:
return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
case Maxwell::PrimitiveTopology::Polygon:
switch (polygon_mode) {
case Maxwell::PolygonMode::Fill:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case Maxwell::PolygonMode::Line:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case Maxwell::PolygonMode::Point:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
}
break;
}
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
}
} // namespace detail
namespace Sampler { namespace Sampler {
VkFilter Filter(Tegra::Texture::TextureFilter filter); VkFilter Filter(Tegra::Texture::TextureFilter filter);
@@ -95,8 +46,7 @@ struct FormatInfo {
VkShaderStageFlagBits ShaderStage(Shader::Stage stage); VkShaderStageFlagBits ShaderStage(Shader::Stage stage);
VkPrimitiveTopology PrimitiveTopology(const Device& device, Maxwell::PrimitiveTopology topology, VkPrimitiveTopology PrimitiveTopology(const Device& device, Maxwell::PrimitiveTopology topology);
Maxwell::PolygonMode polygon_mode);
VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
Maxwell::VertexAttribute::Size size); Maxwell::VertexAttribute::Size size);

View File

@@ -7,7 +7,6 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <span> #include <span>
#include <string_view>
#include <boost/container/small_vector.hpp> #include <boost/container/small_vector.hpp>
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
@@ -23,7 +22,6 @@
#include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_texture_cache.h" #include "video_core/renderer_vulkan/vk_texture_cache.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h" #include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/polygon_mode_utils.h"
#include "video_core/shader_notify.h" #include "video_core/shader_notify.h"
#include "video_core/texture_cache/texture_cache.h" #include "video_core/texture_cache/texture_cache.h"
#include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_device.h"
@@ -616,10 +614,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
vertex_input_ci.pNext = &input_divisor_ci; vertex_input_ci.pNext = &input_divisor_ci;
} }
const bool has_tess_stages = spv_modules[1] || spv_modules[2]; const bool has_tess_stages = spv_modules[1] || spv_modules[2];
const auto polygon_mode = auto input_assembly_topology = MaxwellToVK::PrimitiveTopology(device, key.state.topology);
FixedPipelineState::UnpackPolygonMode(key.state.polygon_mode.Value());
auto input_assembly_topology =
MaxwellToVK::PrimitiveTopology(device, key.state.topology, polygon_mode);
if (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { if (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) {
if (!has_tess_stages) { if (!has_tess_stages) {
LOG_WARNING(Render_Vulkan, "Patch topology used without tessellation, using points"); LOG_WARNING(Render_Vulkan, "Patch topology used without tessellation, using points");
@@ -634,33 +629,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
input_assembly_topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; input_assembly_topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
} }
} }
if (key.state.topology == Maxwell::PrimitiveTopology::Polygon) {
const auto polygon_mode_name = [polygon_mode]() -> std::string_view {
switch (polygon_mode) {
case Maxwell::PolygonMode::Fill:
return "Fill";
case Maxwell::PolygonMode::Line:
return "Line";
case Maxwell::PolygonMode::Point:
return "Point";
}
return "Unknown";
}();
const auto vk_topology_name = [input_assembly_topology]() -> std::string_view {
switch (input_assembly_topology) {
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
return "TriangleFan";
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return "LineStrip";
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return "PointList";
default:
return "Unexpected";
}
}();
LOG_DEBUG(Render_Vulkan, "Polygon primitive in {} mode mapped to {}", polygon_mode_name,
vk_topology_name);
}
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{ const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,

View File

@@ -37,7 +37,6 @@
#include "video_core/renderer_vulkan/vk_update_descriptor.h" #include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/shader_cache.h" #include "video_core/shader_cache.h"
#include "video_core/texture_cache/texture_cache_base.h" #include "video_core/texture_cache/texture_cache_base.h"
#include "video_core/polygon_mode_utils.h"
#include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -109,7 +108,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) { VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) {
const auto& src = regs.scissor_test[index]; const auto& src = regs.scissor_test[index];
VkRect2D scissor; VkRect2D scissor{};
const auto scale_up = [&](s32 value) -> s32 { const auto scale_up = [&](s32 value) -> s32 {
if (value == 0) { if (value == 0) {
return 0U; return 0U;
@@ -149,8 +148,7 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u3
return scissor; return scissor;
} }
DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances, bool is_indexed, DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances, bool is_indexed) {
Maxwell::PolygonMode polygon_mode) {
DrawParams params{ DrawParams params{
.base_instance = draw_state.base_instance, .base_instance = draw_state.base_instance,
.num_instances = num_instances, .num_instances = num_instances,
@@ -170,21 +168,6 @@ DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances,
params.base_vertex = 0; params.base_vertex = 0;
params.is_indexed = true; params.is_indexed = true;
} }
const bool polygon_line =
draw_state.topology == Maxwell::PrimitiveTopology::Polygon &&
polygon_mode == Maxwell::PolygonMode::Line;
if (polygon_line) {
if (params.is_indexed) {
if (draw_state.index_buffer.count > 1) {
params.num_vertices = draw_state.index_buffer.count + 1;
}
} else if (draw_state.vertex_buffer.count > 1) {
params.num_vertices = draw_state.vertex_buffer.count + 1;
params.is_indexed = true;
params.first_index = 0;
params.base_vertex = draw_state.vertex_buffer.first;
}
}
return params; return params;
} }
} // Anonymous namespace } // Anonymous namespace
@@ -250,8 +233,7 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
PrepareDraw(is_indexed, [this, is_indexed, instance_count] { PrepareDraw(is_indexed, [this, is_indexed, instance_count] {
const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
const u32 num_instances{instance_count}; const u32 num_instances{instance_count};
const auto polygon_mode = VideoCore::EffectivePolygonMode(maxwell3d->regs); const DrawParams draw_params{MakeDrawParams(draw_state, num_instances, is_indexed)};
const DrawParams draw_params{MakeDrawParams(draw_state, num_instances, is_indexed, polygon_mode)};
scheduler.Record([draw_params](vk::CommandBuffer cmdbuf) { scheduler.Record([draw_params](vk::CommandBuffer cmdbuf) {
if (draw_params.is_indexed) { if (draw_params.is_indexed) {
cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances, cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances,
@@ -392,7 +374,7 @@ void RasterizerVulkan::Clear(u32 layer_count) {
} }
UpdateViewportsState(regs); UpdateViewportsState(regs);
VkRect2D default_scissor; VkRect2D default_scissor{};
default_scissor.offset.x = 0; default_scissor.offset.x = 0;
default_scissor.offset.y = 0; default_scissor.offset.y = 0;
default_scissor.extent.width = (std::numeric_limits<s32>::max)(); default_scissor.extent.width = (std::numeric_limits<s32>::max)();

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -71,11 +74,11 @@ private:
std::unique_ptr<InputProfiles> profiles; std::unique_ptr<InputProfiles> profiles;
std::array<ConfigureInputPlayer*, 8> player_controllers; std::array<ConfigureInputPlayer*, 8> player_controllers{};
std::array<QWidget*, 8> player_tabs; std::array<QWidget*, 8> player_tabs{};
// Checkboxes representing the "Connected Controllers". // Checkboxes representing the "Connected Controllers".
std::array<QCheckBox*, 8> connected_controller_checkboxes; std::array<QCheckBox*, 8> connected_controller_checkboxes{};
ConfigureInputAdvanced* advanced; ConfigureInputAdvanced* advanced = nullptr;
Core::System& system; Core::System& system;
}; };

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -689,10 +692,10 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen
{ {
// Draw joysticks // Draw joysticks
using namespace Settings::NativeAnalog; using namespace Settings::NativeAnalog;
const auto l_stick = QPointF(stick_values[LStick].x.value, stick_values[LStick].y.value); const auto& l_stick = QPointF(stick_values[LStick].x.value, stick_values[LStick].y.value);
const auto l_button = button_values[Settings::NativeButton::LStick]; const auto& l_button = button_values[Settings::NativeButton::LStick];
const auto r_stick = QPointF(stick_values[RStick].x.value, stick_values[RStick].y.value); const auto& r_stick = QPointF(stick_values[RStick].x.value, stick_values[RStick].y.value);
const auto r_button = button_values[Settings::NativeButton::RStick]; const auto& r_button = button_values[Settings::NativeButton::RStick];
DrawJoystick(p, center + QPointF(-171, -41) + (l_stick * 4), 1.0f, l_button); DrawJoystick(p, center + QPointF(-171, -41) + (l_stick * 4), 1.0f, l_button);
DrawJoystick(p, center + QPointF(171, 8) + (r_stick * 4), 1.0f, r_button); DrawJoystick(p, center + QPointF(171, 8) + (r_stick * 4), 1.0f, r_button);

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -214,7 +217,7 @@ private:
bool mapping_active{}; bool mapping_active{};
int blink_counter{}; int blink_counter{};
int callback_key; int callback_key{};
QColor button_color{}; QColor button_color{};
ColorMapping colors{}; ColorMapping colors{};
Core::HID::LedPattern led_pattern{0, 0, 0, 0}; Core::HID::LedPattern led_pattern{0, 0, 0, 0};

View File

@@ -1495,7 +1495,7 @@ void MainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
(state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) {
auto_paused = true; auto_paused = true;
OnPauseGame(); OnPauseGame();
} else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { } else if (!emu_thread->IsRunning() && auto_paused && (state & Qt::ApplicationActive)) {
auto_paused = false; auto_paused = false;
OnStartGame(); OnStartGame();
} }
@@ -1505,7 +1505,7 @@ void MainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
(state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) {
Settings::values.audio_muted = true; Settings::values.audio_muted = true;
auto_muted = true; auto_muted = true;
} else if (auto_muted && state == Qt::ApplicationActive) { } else if (auto_muted && (state & Qt::ApplicationActive)) {
Settings::values.audio_muted = false; Settings::values.audio_muted = false;
auto_muted = false; auto_muted = false;
} }

View File

@@ -482,13 +482,13 @@ private:
MultiplayerState* multiplayer_state = nullptr; MultiplayerState* multiplayer_state = nullptr;
GRenderWindow* render_window; GRenderWindow* render_window = nullptr;
GameList* game_list; GameList* game_list = nullptr;
LoadingScreen* loading_screen; LoadingScreen* loading_screen = nullptr;
QTimer shutdown_timer; QTimer shutdown_timer;
OverlayDialog* shutdown_dialog{}; OverlayDialog* shutdown_dialog{};
GameListPlaceholder* game_list_placeholder; GameListPlaceholder* game_list_placeholder = nullptr;
std::vector<VkDeviceInfo::Record> vk_device_records; std::vector<VkDeviceInfo::Record> vk_device_records;
@@ -531,7 +531,7 @@ private:
QString startup_icon_theme; QString startup_icon_theme;
// Debugger panes // Debugger panes
ControllerDialog* controller_dialog; ControllerDialog* controller_dialog = nullptr;
QAction* actions_recent_files[max_recent_files_item]; QAction* actions_recent_files[max_recent_files_item];
@@ -543,7 +543,7 @@ private:
QTranslator translator; QTranslator translator;
// Install progress dialog // Install progress dialog
QProgressDialog* install_progress; QProgressDialog* install_progress = nullptr;
// Last game booted, used for multi-process apps // Last game booted, used for multi-process apps
QString last_filename_booted; QString last_filename_booted;

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -175,7 +178,7 @@ public:
private: private:
QString username; QString username;
QString nickname; QString nickname;
u64 title_id; u64 title_id{};
QString game_name; QString game_name;
}; };

View File

@@ -14,7 +14,7 @@ try {
Exit 1 Exit 1
} }
$VulkanSDKVer = "1.4.328.1" $VulkanSDKVer = "1.4.335.0"
$VULKAN_SDK = "C:/VulkanSDK/$VulkanSDKVer" $VULKAN_SDK = "C:/VulkanSDK/$VulkanSDKVer"
$ExeFile = "vulkansdk-windows-X64-$VulkanSDKVer.exe" $ExeFile = "vulkansdk-windows-X64-$VulkanSDKVer.exe"
$Uri = "https://sdk.lunarg.com/sdk/download/$VulkanSDKVer/windows/$ExeFile" $Uri = "https://sdk.lunarg.com/sdk/download/$VulkanSDKVer/windows/$ExeFile"

View File

@@ -2,7 +2,7 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
: "${VULKAN_SDK_VER:=1.4.328.1}" : "${VULKAN_SDK_VER:=1.4.335.0}"
: "${VULKAN_ROOT:=C:/VulkanSDK/$VULKAN_SDK_VER}" : "${VULKAN_ROOT:=C:/VulkanSDK/$VULKAN_SDK_VER}"
EXE_FILE="vulkansdk-windows-X64-$VULKAN_SDK_VER.exe" EXE_FILE="vulkansdk-windows-X64-$VULKAN_SDK_VER.exe"
URI="https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/windows/$EXE_FILE" URI="https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/windows/$EXE_FILE"