early-access version 2649
This commit is contained in:
parent
2ffe9685e5
commit
447daccd21
19 changed files with 103 additions and 19 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2648.
|
This is the source code for early-access 2649.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -1207,4 +1207,12 @@ void EmulatedController::DeleteCallback(int key) {
|
||||||
}
|
}
|
||||||
callback_list.erase(iterator);
|
callback_list.erase(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmulatedController::RemoveServiceCallbacks() {
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
const auto count = std::erase_if(
|
||||||
|
callback_list, [](const auto& callback) { return callback.second.is_npad_service; });
|
||||||
|
LOG_DEBUG(Input, "Elements deleted {}", count);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core::HID
|
} // namespace Core::HID
|
||||||
|
|
|
@ -335,6 +335,9 @@ public:
|
||||||
*/
|
*/
|
||||||
void DeleteCallback(int key);
|
void DeleteCallback(int key);
|
||||||
|
|
||||||
|
/// Removes all callbacks created from npad services
|
||||||
|
void RemoveServiceCallbacks();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// creates input devices from params
|
/// creates input devices from params
|
||||||
void LoadDevices();
|
void LoadDevices();
|
||||||
|
|
|
@ -211,4 +211,17 @@ void HIDCore::UnloadInputDevices() {
|
||||||
devices->UnloadInput();
|
devices->UnloadInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HIDCore::RemoveServiceCallbacks() {
|
||||||
|
player_1->RemoveServiceCallbacks();
|
||||||
|
player_2->RemoveServiceCallbacks();
|
||||||
|
player_3->RemoveServiceCallbacks();
|
||||||
|
player_4->RemoveServiceCallbacks();
|
||||||
|
player_5->RemoveServiceCallbacks();
|
||||||
|
player_6->RemoveServiceCallbacks();
|
||||||
|
player_7->RemoveServiceCallbacks();
|
||||||
|
player_8->RemoveServiceCallbacks();
|
||||||
|
other->RemoveServiceCallbacks();
|
||||||
|
handheld->RemoveServiceCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core::HID
|
} // namespace Core::HID
|
||||||
|
|
|
@ -61,6 +61,9 @@ public:
|
||||||
/// Removes all callbacks from input common
|
/// Removes all callbacks from input common
|
||||||
void UnloadInputDevices();
|
void UnloadInputDevices();
|
||||||
|
|
||||||
|
/// Removes all callbacks from npad services
|
||||||
|
void RemoveServiceCallbacks();
|
||||||
|
|
||||||
/// Number of emulated controllers
|
/// Number of emulated controllers
|
||||||
static constexpr std::size_t available_controllers{10};
|
static constexpr std::size_t available_controllers{10};
|
||||||
|
|
||||||
|
|
|
@ -148,9 +148,9 @@ u64 GenerateUniformRange(u64 min, u64 max, F f) {
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
u64 KSystemControl::GenerateRandomU64() {
|
u64 KSystemControl::GenerateRandomU64() {
|
||||||
static std::random_device device;
|
std::random_device device;
|
||||||
static std::mt19937 gen(device());
|
std::mt19937 gen(device());
|
||||||
static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
|
std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
|
||||||
return distribution(gen);
|
return distribution(gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ public:
|
||||||
do {
|
do {
|
||||||
ASSERT(cur_ref_count > 0);
|
ASSERT(cur_ref_count > 0);
|
||||||
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1,
|
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1,
|
||||||
std::memory_order_relaxed));
|
std::memory_order_acq_rel));
|
||||||
|
|
||||||
// If ref count hits zero, destroy the object.
|
// If ref count hits zero, destroy the object.
|
||||||
if (cur_ref_count - 1 == 0) {
|
if (cur_ref_count - 1 == 0) {
|
||||||
|
|
|
@ -422,7 +422,7 @@ private:
|
||||||
bool is_64bit_process = true;
|
bool is_64bit_process = true;
|
||||||
|
|
||||||
/// Total running time for the process in ticks.
|
/// Total running time for the process in ticks.
|
||||||
u64 total_process_running_time_ticks = 0;
|
std::atomic<u64> total_process_running_time_ticks = 0;
|
||||||
|
|
||||||
/// Per-process handle table for storing created object handles in.
|
/// Per-process handle table for storing created object handles in.
|
||||||
KHandleTable handle_table;
|
KHandleTable handle_table;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "core/hle/kernel/k_spin_lock.h"
|
#include "core/hle/kernel/k_spin_lock.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
|
@ -75,7 +76,7 @@ private:
|
||||||
KernelCore& kernel;
|
KernelCore& kernel;
|
||||||
KAlignedSpinLock spin_lock{};
|
KAlignedSpinLock spin_lock{};
|
||||||
s32 lock_count{};
|
s32 lock_count{};
|
||||||
KThread* owner_thread{};
|
std::atomic<KThread*> owner_thread{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -723,7 +723,7 @@ void KThread::UpdateState() {
|
||||||
ASSERT(kernel.GlobalSchedulerContext().IsLocked());
|
ASSERT(kernel.GlobalSchedulerContext().IsLocked());
|
||||||
|
|
||||||
// Set our suspend flags in state.
|
// Set our suspend flags in state.
|
||||||
const auto old_state = thread_state;
|
const ThreadState old_state = thread_state;
|
||||||
const auto new_state =
|
const auto new_state =
|
||||||
static_cast<ThreadState>(this->GetSuspendFlags()) | (old_state & ThreadState::Mask);
|
static_cast<ThreadState>(this->GetSuspendFlags()) | (old_state & ThreadState::Mask);
|
||||||
thread_state = new_state;
|
thread_state = new_state;
|
||||||
|
@ -738,7 +738,7 @@ void KThread::Continue() {
|
||||||
ASSERT(kernel.GlobalSchedulerContext().IsLocked());
|
ASSERT(kernel.GlobalSchedulerContext().IsLocked());
|
||||||
|
|
||||||
// Clear our suspend flags in state.
|
// Clear our suspend flags in state.
|
||||||
const auto old_state = thread_state;
|
const ThreadState old_state = thread_state;
|
||||||
thread_state = old_state & ThreadState::Mask;
|
thread_state = old_state & ThreadState::Mask;
|
||||||
|
|
||||||
// Note the state change in scheduler.
|
// Note the state change in scheduler.
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -751,7 +752,7 @@ private:
|
||||||
KAffinityMask original_physical_affinity_mask{};
|
KAffinityMask original_physical_affinity_mask{};
|
||||||
s32 original_physical_ideal_core_id{};
|
s32 original_physical_ideal_core_id{};
|
||||||
s32 num_core_migration_disables{};
|
s32 num_core_migration_disables{};
|
||||||
ThreadState thread_state{};
|
std::atomic<ThreadState> thread_state{};
|
||||||
std::atomic<bool> termination_requested{};
|
std::atomic<bool> termination_requested{};
|
||||||
bool wait_cancelled{};
|
bool wait_cancelled{};
|
||||||
bool cancellable{};
|
bool cancellable{};
|
||||||
|
|
|
@ -85,7 +85,7 @@ struct KernelCore::Impl {
|
||||||
|
|
||||||
void InitializeCores() {
|
void InitializeCores() {
|
||||||
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
|
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
|
||||||
cores[core_id].Initialize(current_process->Is64BitProcess());
|
cores[core_id].Initialize((*current_process).Is64BitProcess());
|
||||||
system.Memory().SetCurrentPageTable(*current_process, core_id);
|
system.Memory().SetCurrentPageTable(*current_process, core_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,11 +169,11 @@ struct KernelCore::Impl {
|
||||||
|
|
||||||
// Shutdown all processes.
|
// Shutdown all processes.
|
||||||
if (current_process) {
|
if (current_process) {
|
||||||
current_process->Finalize();
|
(*current_process).Finalize();
|
||||||
// current_process->Close();
|
// current_process->Close();
|
||||||
// TODO: The current process should be destroyed based on accurate ref counting after
|
// TODO: The current process should be destroyed based on accurate ref counting after
|
||||||
// calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
|
// calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
|
||||||
current_process->Destroy();
|
(*current_process).Destroy();
|
||||||
current_process = nullptr;
|
current_process = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +713,7 @@ struct KernelCore::Impl {
|
||||||
|
|
||||||
// Lists all processes that exist in the current session.
|
// Lists all processes that exist in the current session.
|
||||||
std::vector<KProcess*> process_list;
|
std::vector<KProcess*> process_list;
|
||||||
KProcess* current_process{};
|
std::atomic<KProcess*> current_process{};
|
||||||
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
|
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
|
||||||
Kernel::TimeManager time_manager;
|
Kernel::TimeManager time_manager;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ set(SHADER_FILES
|
||||||
full_screen_triangle.vert
|
full_screen_triangle.vert
|
||||||
fxaa.frag
|
fxaa.frag
|
||||||
fxaa.vert
|
fxaa.vert
|
||||||
|
opengl_convert_s8d24.comp
|
||||||
opengl_copy_bc4.comp
|
opengl_copy_bc4.comp
|
||||||
opengl_present.frag
|
opengl_present.frag
|
||||||
opengl_present.vert
|
opengl_present.vert
|
||||||
|
|
18
src/video_core/host_shaders/opengl_convert_s8d24.comp
Executable file
18
src/video_core/host_shaders/opengl_convert_s8d24.comp
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2022 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#version 430 core
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 8) in;
|
||||||
|
|
||||||
|
layout(binding = 0, rgba8ui) restrict uniform uimage2D destination;
|
||||||
|
layout(location = 0) uniform uvec3 size;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if (any(greaterThanEqual(gl_GlobalInvocationID, size))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uvec4 components = imageLoad(destination, ivec2(gl_GlobalInvocationID.xy));
|
||||||
|
imageStore(destination, ivec2(gl_GlobalInvocationID.xy), components.wxyz);
|
||||||
|
}
|
|
@ -409,8 +409,8 @@ ImageBufferMap::~ImageBufferMap() {
|
||||||
|
|
||||||
TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager,
|
TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager,
|
||||||
StateTracker& state_tracker_)
|
StateTracker& state_tracker_)
|
||||||
: device{device_}, state_tracker{state_tracker_},
|
: device{device_}, state_tracker{state_tracker_}, util_shaders(program_manager),
|
||||||
util_shaders(program_manager), resolution{Settings::values.resolution_info} {
|
format_conversion_pass{util_shaders}, resolution{Settings::values.resolution_info} {
|
||||||
static constexpr std::array TARGETS{GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D};
|
static constexpr std::array TARGETS{GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D};
|
||||||
for (size_t i = 0; i < TARGETS.size(); ++i) {
|
for (size_t i = 0; i < TARGETS.size(); ++i) {
|
||||||
const GLenum target = TARGETS[i];
|
const GLenum target = TARGETS[i];
|
||||||
|
@ -1325,6 +1325,9 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
|
||||||
|
|
||||||
Framebuffer::~Framebuffer() = default;
|
Framebuffer::~Framebuffer() = default;
|
||||||
|
|
||||||
|
FormatConversionPass::FormatConversionPass(UtilShaders& util_shaders_)
|
||||||
|
: util_shaders{util_shaders_} {}
|
||||||
|
|
||||||
void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
|
void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
|
||||||
std::span<const VideoCommon::ImageCopy> copies) {
|
std::span<const VideoCommon::ImageCopy> copies) {
|
||||||
const GLenum dst_target = ImageTarget(dst_image.info);
|
const GLenum dst_target = ImageTarget(dst_image.info);
|
||||||
|
@ -1357,6 +1360,12 @@ void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
|
||||||
dst_origin.z, region.width, region.height, region.depth,
|
dst_origin.z, region.width, region.height, region.depth,
|
||||||
dst_image.GlFormat(), dst_image.GlType(), nullptr);
|
dst_image.GlFormat(), dst_image.GlType(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swap component order of S8D24 to ABGR8 reinterprets
|
||||||
|
if (src_image.info.format == PixelFormat::D24_UNORM_S8_UINT &&
|
||||||
|
dst_image.info.format == PixelFormat::A8B8G8R8_UNORM) {
|
||||||
|
util_shaders.ConvertS8D24(dst_image, copies);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -55,13 +55,14 @@ struct FormatProperties {
|
||||||
|
|
||||||
class FormatConversionPass {
|
class FormatConversionPass {
|
||||||
public:
|
public:
|
||||||
FormatConversionPass() = default;
|
explicit FormatConversionPass(UtilShaders& util_shaders);
|
||||||
~FormatConversionPass() = default;
|
~FormatConversionPass() = default;
|
||||||
|
|
||||||
void ConvertImage(Image& dst_image, Image& src_image,
|
void ConvertImage(Image& dst_image, Image& src_image,
|
||||||
std::span<const VideoCommon::ImageCopy> copies);
|
std::span<const VideoCommon::ImageCopy> copies);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
UtilShaders& util_shaders;
|
||||||
OGLBuffer intermediate_pbo;
|
OGLBuffer intermediate_pbo;
|
||||||
size_t pbo_size{};
|
size_t pbo_size{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "video_core/host_shaders/astc_decoder_comp.h"
|
#include "video_core/host_shaders/astc_decoder_comp.h"
|
||||||
#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h"
|
#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h"
|
||||||
#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h"
|
#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h"
|
||||||
|
#include "video_core/host_shaders/opengl_convert_s8d24_comp.h"
|
||||||
#include "video_core/host_shaders/opengl_copy_bc4_comp.h"
|
#include "video_core/host_shaders/opengl_copy_bc4_comp.h"
|
||||||
#include "video_core/host_shaders/pitch_unswizzle_comp.h"
|
#include "video_core/host_shaders/pitch_unswizzle_comp.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
|
@ -50,7 +51,8 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
|
||||||
block_linear_unswizzle_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)),
|
block_linear_unswizzle_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)),
|
||||||
block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
|
block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
|
||||||
pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
|
pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
|
||||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)) {
|
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
|
||||||
|
convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)) {
|
||||||
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
|
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
|
||||||
swizzle_table_buffer.Create();
|
swizzle_table_buffer.Create();
|
||||||
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
|
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
|
||||||
|
@ -248,6 +250,26 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im
|
||||||
program_manager.RestoreGuestCompute();
|
program_manager.RestoreGuestCompute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UtilShaders::ConvertS8D24(Image& dst_image, std::span<const ImageCopy> copies) {
|
||||||
|
static constexpr GLuint BINDING_DESTINATION = 0;
|
||||||
|
static constexpr GLuint LOC_SIZE = 0;
|
||||||
|
|
||||||
|
program_manager.BindComputeProgram(convert_s8d24_program.handle);
|
||||||
|
for (const ImageCopy& copy : copies) {
|
||||||
|
ASSERT(copy.src_subresource.base_layer == 0);
|
||||||
|
ASSERT(copy.src_subresource.num_layers == 1);
|
||||||
|
ASSERT(copy.dst_subresource.base_layer == 0);
|
||||||
|
ASSERT(copy.dst_subresource.num_layers == 1);
|
||||||
|
|
||||||
|
glUniform3ui(LOC_SIZE, copy.extent.width, copy.extent.height, copy.extent.depth);
|
||||||
|
glBindImageTexture(BINDING_DESTINATION, dst_image.StorageHandle(),
|
||||||
|
copy.dst_subresource.base_level, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA8UI);
|
||||||
|
glDispatchCompute(Common::DivCeil(copy.extent.width, 16u),
|
||||||
|
Common::DivCeil(copy.extent.height, 8u), copy.extent.depth);
|
||||||
|
}
|
||||||
|
program_manager.RestoreGuestCompute();
|
||||||
|
}
|
||||||
|
|
||||||
GLenum StoreFormat(u32 bytes_per_block) {
|
GLenum StoreFormat(u32 bytes_per_block) {
|
||||||
switch (bytes_per_block) {
|
switch (bytes_per_block) {
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -39,6 +39,8 @@ public:
|
||||||
void CopyBC4(Image& dst_image, Image& src_image,
|
void CopyBC4(Image& dst_image, Image& src_image,
|
||||||
std::span<const VideoCommon::ImageCopy> copies);
|
std::span<const VideoCommon::ImageCopy> copies);
|
||||||
|
|
||||||
|
void ConvertS8D24(Image& dst_image, std::span<const VideoCommon::ImageCopy> copies);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProgramManager& program_manager;
|
ProgramManager& program_manager;
|
||||||
|
|
||||||
|
@ -49,6 +51,7 @@ private:
|
||||||
OGLProgram block_linear_unswizzle_3d_program;
|
OGLProgram block_linear_unswizzle_3d_program;
|
||||||
OGLProgram pitch_unswizzle_program;
|
OGLProgram pitch_unswizzle_program;
|
||||||
OGLProgram copy_bc4_program;
|
OGLProgram copy_bc4_program;
|
||||||
|
OGLProgram convert_s8d24_program;
|
||||||
};
|
};
|
||||||
|
|
||||||
GLenum StoreFormat(u32 bytes_per_block);
|
GLenum StoreFormat(u32 bytes_per_block);
|
||||||
|
|
|
@ -1540,8 +1540,9 @@ void GMainWindow::ShutdownGame() {
|
||||||
input_subsystem->GetTas()->Stop();
|
input_subsystem->GetTas()->Stop();
|
||||||
OnTasStateChanged();
|
OnTasStateChanged();
|
||||||
|
|
||||||
// Enable all controllers
|
// Enable all controllers types and remove all service callbacks
|
||||||
system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
|
system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
|
||||||
|
system->HIDCore().RemoveServiceCallbacks();
|
||||||
|
|
||||||
render_window->removeEventFilter(render_window);
|
render_window->removeEventFilter(render_window);
|
||||||
render_window->setAttribute(Qt::WA_Hover, false);
|
render_window->setAttribute(Qt::WA_Hover, false);
|
||||||
|
|
Loading…
Reference in a new issue