early-access version 2121

This commit is contained in:
pineappleEA 2021-10-12 03:16:41 +02:00
parent ac669c832d
commit 2c54215c89
7 changed files with 78 additions and 55 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 2118. This is the source code for early-access 2121.
## Legal Notice ## Legal Notice

View file

@ -170,7 +170,8 @@ public:
float GetAxis(int axis, float range, float offset) const { float GetAxis(int axis, float range, float offset) const {
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
const float value = static_cast<float>(state.axes.at(axis)) / 32767.0f; const float value = static_cast<float>(state.axes.at(axis)) / 32767.0f;
return (value + offset) / range; const float offset_scale = (value + offset) > 0.0f ? 1.0f + offset : 1.0f - offset;
return (value + offset) / range / offset_scale;
} }
bool RumblePlay(u16 amp_low, u16 amp_high) { bool RumblePlay(u16 amp_low, u16 amp_high) {
@ -789,8 +790,8 @@ public:
const std::string invert_y_value = params.Get("invert_y", "+"); const std::string invert_y_value = params.Get("invert_y", "+");
const bool invert_x = invert_x_value == "-"; const bool invert_x = invert_x_value == "-";
const bool invert_y = invert_y_value == "-"; const bool invert_y = invert_y_value == "-";
const float offset_x = params.Get("offset_x", 0.0f); const float offset_x = std::clamp(params.Get("offset_x", 0.0f), -0.99f, 0.99f);
const float offset_y = params.Get("offset_y", 0.0f); const float offset_y = std::clamp(params.Get("offset_y", 0.0f), -0.99f, 0.99f);
auto joystick = state.GetSDLJoystickByGUID(guid, port); auto joystick = state.GetSDLJoystickByGUID(guid, port);
// This is necessary so accessing GetAxis with axis_x and axis_y won't crash // This is necessary so accessing GetAxis with axis_x and axis_y won't crash

View file

@ -20,6 +20,8 @@
#include <array> #include <array>
#include <bit> #include <bit>
#include "common/settings.h"
#include "video_core/command_classes/codecs/h264.h" #include "video_core/command_classes/codecs/h264.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
#include "video_core/memory_manager.h" #include "video_core/memory_manager.h"
@ -96,7 +98,10 @@ const std::vector<u8>& H264::ComposeFrameHeader(const NvdecCommon::NvdecRegister
(context.h264_parameter_set.frame_mbs_only_flag ? 1 : 2); (context.h264_parameter_set.frame_mbs_only_flag ? 1 : 2);
// TODO (ameerj): Where do we get this number, it seems to be particular for each stream // TODO (ameerj): Where do we get this number, it seems to be particular for each stream
writer.WriteUe(6); // Max number of reference frames const auto nvdec_decoding = Settings::values.nvdec_emulation.GetValue();
const bool uses_gpu_decoding = nvdec_decoding == Settings::NvdecEmulation::GPU;
const u32 max_num_ref_frames = uses_gpu_decoding ? 6u : 16u;
writer.WriteUe(max_num_ref_frames);
writer.WriteBit(false); writer.WriteBit(false);
writer.WriteUe(context.h264_parameter_set.pic_width_in_mbs - 1); writer.WriteUe(context.h264_parameter_set.pic_width_in_mbs - 1);
writer.WriteUe(pic_height - 1); writer.WriteUe(pic_height - 1);

View file

@ -32,7 +32,7 @@ enum class VideoPixelFormat : u64_le {
RGBA8 = 0x1f, RGBA8 = 0x1f,
BGRA8 = 0x20, BGRA8 = 0x20,
RGBX8 = 0x23, RGBX8 = 0x23,
Yuv420 = 0x44, YUV420 = 0x44,
}; };
} // Anonymous namespace } // Anonymous namespace
@ -90,9 +90,8 @@ void Vic::Execute() {
if (static_cast<u64>(frame->width) != surface_width || if (static_cast<u64>(frame->width) != surface_width ||
static_cast<u64>(frame->height) != surface_height) { static_cast<u64>(frame->height) != surface_height) {
// TODO: Properly support multiple video streams with differing frame dimensions // TODO: Properly support multiple video streams with differing frame dimensions
LOG_WARNING(Debug, "Frame dimensions {}x{} do not match expected surface dimensions {}x{}", LOG_WARNING(Service_NVDRV, "Frame dimensions {}x{} don't match surface dimensions {}x{}",
frame->width, frame->height, surface_width, surface_height); frame->width, frame->height, surface_width, surface_height);
return;
} }
switch (config.pixel_format) { switch (config.pixel_format) {
case VideoPixelFormat::RGBA8: case VideoPixelFormat::RGBA8:
@ -100,7 +99,7 @@ void Vic::Execute() {
case VideoPixelFormat::RGBX8: case VideoPixelFormat::RGBX8:
WriteRGBFrame(frame, config); WriteRGBFrame(frame, config);
break; break;
case VideoPixelFormat::Yuv420: case VideoPixelFormat::YUV420:
WriteYUVFrame(frame, config); WriteYUVFrame(frame, config);
break; break;
default: default:
@ -135,21 +134,20 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
scaler_height = frame->height; scaler_height = frame->height;
converted_frame_buffer.reset(); converted_frame_buffer.reset();
} }
// Get Converted frame
const u32 width = static_cast<u32>(frame->width);
const u32 height = static_cast<u32>(frame->height);
const std::size_t linear_size = width * height * 4;
// Only allocate frame_buffer once per stream, as the size is not expected to change
if (!converted_frame_buffer) { if (!converted_frame_buffer) {
converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(linear_size)), av_free}; const size_t frame_size = frame->width * frame->height * 4;
converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(frame_size)), av_free};
} }
const std::array<int, 4> converted_stride{frame->width * 4, frame->height * 4, 0, 0}; const std::array<int, 4> converted_stride{frame->width * 4, frame->height * 4, 0, 0};
u8* const converted_frame_buf_addr{converted_frame_buffer.get()}; u8* const converted_frame_buf_addr{converted_frame_buffer.get()};
sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height, &converted_frame_buf_addr, sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height, &converted_frame_buf_addr,
converted_stride.data()); converted_stride.data());
// Use the minimum of surface/frame dimensions to avoid buffer overflow.
const u32 surface_width = static_cast<u32>(config.surface_width_minus1) + 1;
const u32 surface_height = static_cast<u32>(config.surface_height_minus1) + 1;
const u32 width = std::min(surface_width, static_cast<u32>(frame->width));
const u32 height = std::min(surface_height, static_cast<u32>(frame->height));
const u32 blk_kind = static_cast<u32>(config.block_linear_kind); const u32 blk_kind = static_cast<u32>(config.block_linear_kind);
if (blk_kind != 0) { if (blk_kind != 0) {
// swizzle pitch linear to block linear // swizzle pitch linear to block linear
@ -157,11 +155,12 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0); const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0);
luma_buffer.resize(size); luma_buffer.resize(size);
Texture::SwizzleSubrect(width, height, width * 4, width, 4, luma_buffer.data(), Texture::SwizzleSubrect(width, height, width * 4, width, 4, luma_buffer.data(),
converted_frame_buffer.get(), block_height, 0, 0); converted_frame_buf_addr, block_height, 0, 0);
gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size); gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size);
} else { } else {
// send pitch linear frame // send pitch linear frame
const size_t linear_size = width * height * 4;
gpu.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr, gpu.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr,
linear_size); linear_size);
} }
@ -172,9 +171,10 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
const std::size_t surface_width = config.surface_width_minus1 + 1; const std::size_t surface_width = config.surface_width_minus1 + 1;
const std::size_t surface_height = config.surface_height_minus1 + 1; const std::size_t surface_height = config.surface_height_minus1 + 1;
const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL;
// Use the minimum of surface/frame dimensions to avoid buffer overflow.
const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width)); const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width));
const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height)); const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height));
const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL;
const auto stride = static_cast<size_t>(frame->linesize[0]); const auto stride = static_cast<size_t>(frame->linesize[0]);

View file

@ -1172,10 +1172,16 @@ void GMainWindow::ConnectMenuEvents() {
&GMainWindow::OnDisplayTitleBars); &GMainWindow::OnDisplayTitleBars);
connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar); connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar);
connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible);
connect(ui.action_Reset_Window_Size_720, &QAction::triggered, this, connect(ui.action_Reset_Window_Size_720, &QAction::triggered, this,
&GMainWindow::ResetWindowSize720); &GMainWindow::ResetWindowSize720);
connect(ui.action_Reset_Window_Size_900, &QAction::triggered, this,
&GMainWindow::ResetWindowSize900);
connect(ui.action_Reset_Window_Size_1080, &QAction::triggered, this, connect(ui.action_Reset_Window_Size_1080, &QAction::triggered, this,
&GMainWindow::ResetWindowSize1080); &GMainWindow::ResetWindowSize1080);
ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_720);
ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_900);
ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_1080);
// Fullscreen // Fullscreen
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
@ -2611,32 +2617,29 @@ void GMainWindow::ToggleWindowMode() {
} }
} }
void GMainWindow::ResetWindowSize720() { void GMainWindow::ResetWindowSize(u32 width, u32 height) {
const auto aspect_ratio = Layout::EmulationAspectRatio( const auto aspect_ratio = Layout::EmulationAspectRatio(
static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()), static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()),
static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); static_cast<float>(height) / width);
if (!ui.action_Single_Window_Mode->isChecked()) { if (!ui.action_Single_Window_Mode->isChecked()) {
render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio, render_window->resize(height / aspect_ratio, height);
Layout::ScreenUndocked::Height);
} else { } else {
resize(Layout::ScreenUndocked::Height / aspect_ratio, const bool show_status_bar = ui.action_Show_Status_Bar->isChecked();
Layout::ScreenUndocked::Height + menuBar()->height() + const auto status_bar_height = show_status_bar ? statusBar()->height() : 0;
(ui.action_Show_Status_Bar->isChecked() ? statusBar()->height() : 0)); resize(height / aspect_ratio, height + menuBar()->height() + status_bar_height);
} }
} }
void GMainWindow::ResetWindowSize720() {
ResetWindowSize(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height);
}
void GMainWindow::ResetWindowSize900() {
ResetWindowSize(1600U, 900U);
}
void GMainWindow::ResetWindowSize1080() { void GMainWindow::ResetWindowSize1080() {
const auto aspect_ratio = Layout::EmulationAspectRatio( ResetWindowSize(Layout::ScreenDocked::Width, Layout::ScreenDocked::Height);
static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()),
static_cast<float>(Layout::ScreenDocked::Height) / Layout::ScreenDocked::Width);
if (!ui.action_Single_Window_Mode->isChecked()) {
render_window->resize(Layout::ScreenDocked::Height / aspect_ratio,
Layout::ScreenDocked::Height);
} else {
resize(Layout::ScreenDocked::Height / aspect_ratio,
Layout::ScreenDocked::Height + menuBar()->height() +
(ui.action_Show_Status_Bar->isChecked() ? statusBar()->height() : 0));
}
} }
void GMainWindow::OnConfigure() { void GMainWindow::OnConfigure() {

View file

@ -272,7 +272,9 @@ private slots:
void ShowFullscreen(); void ShowFullscreen();
void HideFullscreen(); void HideFullscreen();
void ToggleWindowMode(); void ToggleWindowMode();
void ResetWindowSize(u32 width, u32 height);
void ResetWindowSize720(); void ResetWindowSize720();
void ResetWindowSize900();
void ResetWindowSize1080(); void ResetWindowSize1080();
void OnCaptureScreenshot(); void OnCaptureScreenshot();
void OnCoreError(Core::System::ResultStatus, std::string); void OnCoreError(Core::System::ResultStatus, std::string);

View file

@ -78,6 +78,35 @@
<property name="title"> <property name="title">
<string>&amp;View</string> <string>&amp;View</string>
</property> </property>
<widget class="QMenu" name="menu_Reset_Window_Size">
<property name="title">
<string>&amp;Reset Window Size</string>
</property>
</widget>
<action name="action_Reset_Window_Size_720">
<property name="text">
<string>Reset Window Size to &amp;720p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 720p</string>
</property>
</action>
<action name="action_Reset_Window_Size_900">
<property name="text">
<string>Reset Window Size to &amp;900p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 900p</string>
</property>
</action>
<action name="action_Reset_Window_Size_1080">
<property name="text">
<string>Reset Window Size to &amp;1080p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 1080p</string>
</property>
</action>
<widget class="QMenu" name="menu_View_Debugging"> <widget class="QMenu" name="menu_View_Debugging">
<property name="title"> <property name="title">
<string>&amp;Debugging</string> <string>&amp;Debugging</string>
@ -88,9 +117,8 @@
<addaction name="action_Display_Dock_Widget_Headers"/> <addaction name="action_Display_Dock_Widget_Headers"/>
<addaction name="action_Show_Filter_Bar"/> <addaction name="action_Show_Filter_Bar"/>
<addaction name="action_Show_Status_Bar"/> <addaction name="action_Show_Status_Bar"/>
<addaction name="action_Reset_Window_Size_720"/>
<addaction name="action_Reset_Window_Size_1080"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="menu_Reset_Window_Size"/>
<addaction name="menu_View_Debugging"/> <addaction name="menu_View_Debugging"/>
</widget> </widget>
<widget class="QMenu" name="menu_Tools"> <widget class="QMenu" name="menu_Tools">
@ -216,22 +244,6 @@
<string>Show Status Bar</string> <string>Show Status Bar</string>
</property> </property>
</action> </action>
<action name="action_Reset_Window_Size_720">
<property name="text">
<string>Reset Window Size to &amp;720p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 720p</string>
</property>
</action>
<action name="action_Reset_Window_Size_1080">
<property name="text">
<string>Reset Window Size to &amp;1080p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 1080p</string>
</property>
</action>
<action name="action_Fullscreen"> <action name="action_Fullscreen">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>