Compare commits

..

15 Commits

Author SHA1 Message Date
Behunin
8832446730 Make player input configuration scrollable
Use minimumContentsLength to size the profile combo box
ZL/RL slider threshold 18 -> 20 max height
2022-12-17 14:29:12 -07:00
liamwhite
5da72a891f Merge pull request #7450 from FernandoS27/ndc-vulkan
Vulkan: Add support for VK_EXT_depth_clip_control.
2022-12-17 16:08:10 -05:00
Mai
f8a7d6a0ae Merge pull request #9461 from liamwhite/wanative
qt: avoid setting WA_DontCreateNativeAncestors on all platforms
2022-12-17 21:07:01 +00:00
Mai
da31326c17 Merge pull request #9454 from liamwhite/wayland-egl
qt: handle wayland-egl platform name
2022-12-17 21:05:46 +00:00
Liam
45672d43e3 qt: avoid setting WA_DontCreateNativeAncestors on all platforms 2022-12-17 10:41:20 -05:00
liamwhite
a3bac5550d Merge pull request #9451 from ameerj/camera-data-array
camera: Use pre-allocated vector for camera data
2022-12-17 10:21:50 -05:00
liamwhite
4faea2bbf4 Merge pull request #9452 from ameerj/hle-read-buffer-resreve
hle_ipc: Refactor ReadBuffer to set buffer size upon initialization
2022-12-17 10:21:30 -05:00
liamwhite
fa10374d39 Merge pull request #9455 from Kelebek1/audio_signal
[audio_core] Signal buffer event on audio in/out system stop
2022-12-17 10:21:19 -05:00
liamwhite
98135dee16 Merge pull request #9457 from Kelebek1/silence_tfb
Remove unimplemented geometry transform feedback log spam
2022-12-17 10:21:05 -05:00
ameerj
7bf4bec257 camera: Use pre-allocated vector for camera data
And avoid an unnecessary copy
2022-12-16 18:00:47 -05:00
Kelebek1
f7d95d0a3a Remove unimplemented transform feedback geometry spam, it should be implemented 2022-12-16 22:52:29 +00:00
Kelebek1
6a56f42f5d Signal buffer event on audio in/out system stop, and force remove all registered audio buffers 2022-12-16 16:07:24 +00:00
Liam
b81caf1879 qt: handle wayland-egl platform name 2022-12-16 08:47:22 -05:00
ameerj
b1d633532f hle_ipc: Refactor ReadBuffer to set buffer size upon initialization
Initializing the vector size during initialization is more efficient than a later call to resize()
2022-12-15 23:22:11 -05:00
FernandoS27
0104e28fe4 Vulkan: Add support for VK_EXT_depth_clip_control. 2022-12-13 21:39:18 -05:00
30 changed files with 3118 additions and 3329 deletions

View File

@@ -91,9 +91,10 @@ public:
* @param core_timing - The CoreTiming instance
* @param session - The device session
*
* @return Is the buffer was released.
* @return If any buffer was released.
*/
bool ReleaseBuffers(const Core::Timing::CoreTiming& core_timing, const DeviceSession& session) {
bool ReleaseBuffers(const Core::Timing::CoreTiming& core_timing, const DeviceSession& session,
bool force) {
std::scoped_lock l{lock};
bool buffer_released{false};
while (registered_count > 0) {
@@ -103,7 +104,8 @@ public:
}
// Check with the backend if this buffer can be released yet.
if (!session.IsBufferConsumed(buffers[index])) {
// If we're shutting down, we don't care if it's been played or not.
if (!force && !session.IsBufferConsumed(buffers[index])) {
break;
}

View File

@@ -73,6 +73,12 @@ void DeviceSession::Stop() {
}
}
void DeviceSession::ClearBuffers() {
if (stream) {
stream->ClearQueue();
}
}
void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const {
for (const auto& buffer : buffers) {
Sink::SinkBuffer new_buffer{

View File

@@ -90,6 +90,11 @@ public:
*/
void Stop();
/**
* Clear out the underlying audio buffers in the backend stream.
*/
void ClearBuffers();
/**
* Set this device session's volume.
*

View File

@@ -23,7 +23,6 @@ System::~System() {
void System::Finalize() {
Stop();
session->Finalize();
buffer_event->Signal();
}
void System::StartSession() {
@@ -102,6 +101,10 @@ Result System::Stop() {
if (state == State::Started) {
session->Stop();
session->SetVolume(0.0f);
session->ClearBuffers();
if (buffers.ReleaseBuffers(system.CoreTiming(), *session, true)) {
buffer_event->Signal();
}
state = State::Stopped;
}
@@ -138,7 +141,7 @@ void System::RegisterBuffers() {
}
void System::ReleaseBuffers() {
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session, false)};
if (signal) {
// Signal if any buffer was released, or if none are registered, we need more.

View File

@@ -24,7 +24,6 @@ System::~System() {
void System::Finalize() {
Stop();
session->Finalize();
buffer_event->Signal();
}
std::string_view System::GetDefaultOutputDeviceName() const {
@@ -102,6 +101,10 @@ Result System::Stop() {
if (state == State::Started) {
session->Stop();
session->SetVolume(0.0f);
session->ClearBuffers();
if (buffers.ReleaseBuffers(system.CoreTiming(), *session, true)) {
buffer_event->Signal();
}
state = State::Stopped;
}
@@ -138,7 +141,7 @@ void System::RegisterBuffers() {
}
void System::ReleaseBuffers() {
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session, false)};
if (signal) {
// Signal if any buffer was released, or if none are registered, we need more.
buffer_event->Signal();

View File

@@ -145,7 +145,6 @@ void EmulatedController::LoadDevices() {
output_params[3].Set("output", true);
LoadTASParams();
LoadVirtualGamepadParams();
std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice);
@@ -164,12 +163,6 @@ void EmulatedController::LoadDevices() {
Common::Input::CreateInputDevice);
std::ranges::transform(tas_stick_params, tas_stick_devices.begin(),
Common::Input::CreateInputDevice);
// Initialize virtual gamepad devices
std::ranges::transform(virtual_button_params, virtual_button_devices.begin(),
Common::Input::CreateInputDevice);
std::ranges::transform(virtual_stick_params, virtual_stick_devices.begin(),
Common::Input::CreateInputDevice);
}
void EmulatedController::LoadTASParams() {
@@ -212,46 +205,6 @@ void EmulatedController::LoadTASParams() {
tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
}
void EmulatedController::LoadVirtualGamepadParams() {
const auto player_index = NpadIdTypeToIndex(npad_id_type);
Common::ParamPackage common_params{};
common_params.Set("engine", "virtual_gamepad");
common_params.Set("port", static_cast<int>(player_index));
for (auto& param : virtual_button_params) {
param = common_params;
}
for (auto& param : virtual_stick_params) {
param = common_params;
}
// TODO(german77): Replace this with an input profile or something better
virtual_button_params[Settings::NativeButton::A].Set("button", 0);
virtual_button_params[Settings::NativeButton::B].Set("button", 1);
virtual_button_params[Settings::NativeButton::X].Set("button", 2);
virtual_button_params[Settings::NativeButton::Y].Set("button", 3);
virtual_button_params[Settings::NativeButton::LStick].Set("button", 4);
virtual_button_params[Settings::NativeButton::RStick].Set("button", 5);
virtual_button_params[Settings::NativeButton::L].Set("button", 6);
virtual_button_params[Settings::NativeButton::R].Set("button", 7);
virtual_button_params[Settings::NativeButton::ZL].Set("button", 8);
virtual_button_params[Settings::NativeButton::ZR].Set("button", 9);
virtual_button_params[Settings::NativeButton::Plus].Set("button", 10);
virtual_button_params[Settings::NativeButton::Minus].Set("button", 11);
virtual_button_params[Settings::NativeButton::DLeft].Set("button", 12);
virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
virtual_button_params[Settings::NativeButton::SL].Set("button", 16);
virtual_button_params[Settings::NativeButton::SR].Set("button", 17);
virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_x", 2);
virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
}
void EmulatedController::ReloadInput() {
// If you load any device here add the equivalent to the UnloadInput() function
LoadDevices();
@@ -369,35 +322,6 @@ void EmulatedController::ReloadInput() {
},
});
}
// Use a common UUID for Virtual Gamepad
static constexpr Common::UUID VIRTUAL_UUID = Common::UUID{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
// Register virtual devices. No need to force update
for (std::size_t index = 0; index < virtual_button_devices.size(); ++index) {
if (!virtual_button_devices[index]) {
continue;
}
virtual_button_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetButton(callback, index, VIRTUAL_UUID);
},
});
}
for (std::size_t index = 0; index < virtual_stick_devices.size(); ++index) {
if (!virtual_stick_devices[index]) {
continue;
}
virtual_stick_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetStick(callback, index, VIRTUAL_UUID);
},
});
}
}
void EmulatedController::UnloadInput() {
@@ -425,12 +349,6 @@ void EmulatedController::UnloadInput() {
for (auto& stick : tas_stick_devices) {
stick.reset();
}
for (auto& button : virtual_button_devices) {
button.reset();
}
for (auto& stick : virtual_stick_devices) {
stick.reset();
}
camera_devices.reset();
nfc_devices.reset();
}

View File

@@ -385,9 +385,6 @@ private:
/// Set the params for TAS devices
void LoadTASParams();
/// Set the params for virtual pad devices
void LoadVirtualGamepadParams();
/**
* @param use_temporary_value If true tmp_npad_type will be used
* @return true if the controller style is fullkey
@@ -503,12 +500,6 @@ private:
ButtonDevices tas_button_devices;
StickDevices tas_stick_devices;
// Virtual gamepad related variables
ButtonParams virtual_button_params;
StickParams virtual_stick_params;
ButtonDevices virtual_button_devices;
StickDevices virtual_stick_devices;
mutable std::mutex mutex;
mutable std::mutex callback_mutex;
std::unordered_map<int, ControllerUpdateCallback> callback_list;

View File

@@ -326,25 +326,23 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_threa
}
std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
std::vector<u8> buffer{};
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
BufferDescriptorA()[buffer_index].Size()};
if (is_buffer_a) {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorA().size() > buffer_index, { return buffer; },
BufferDescriptorA().size() > buffer_index, { return {}; },
"BufferDescriptorA invalid buffer_index {}", buffer_index);
buffer.resize(BufferDescriptorA()[buffer_index].Size());
std::vector<u8> buffer(BufferDescriptorA()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size());
return buffer;
} else {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorX().size() > buffer_index, { return buffer; },
BufferDescriptorX().size() > buffer_index, { return {}; },
"BufferDescriptorX invalid buffer_index {}", buffer_index);
buffer.resize(BufferDescriptorX()[buffer_index].Size());
std::vector<u8> buffer(BufferDescriptorX()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size());
return buffer;
}
return buffer;
}
std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,

View File

@@ -20,8 +20,6 @@ add_library(input_common STATIC
drivers/udp_client.h
drivers/virtual_amiibo.cpp
drivers/virtual_amiibo.h
drivers/virtual_gamepad.cpp
drivers/virtual_gamepad.h
helpers/stick_from_buttons.cpp
helpers/stick_from_buttons.h
helpers/touch_from_buttons.cpp

View File

@@ -17,7 +17,7 @@ Camera::Camera(std::string input_engine_) : InputEngine(std::move(input_engine_)
PreSetController(identifier);
}
void Camera::SetCameraData(std::size_t width, std::size_t height, std::vector<u32> data) {
void Camera::SetCameraData(std::size_t width, std::size_t height, std::span<const u32> data) {
const std::size_t desired_width = getImageWidth();
const std::size_t desired_height = getImageHeight();
status.data.resize(desired_width * desired_height);

View File

@@ -3,6 +3,8 @@
#pragma once
#include <span>
#include "input_common/input_engine.h"
namespace InputCommon {
@@ -15,7 +17,7 @@ class Camera final : public InputEngine {
public:
explicit Camera(std::string input_engine_);
void SetCameraData(std::size_t width, std::size_t height, std::vector<u32> data);
void SetCameraData(std::size_t width, std::size_t height, std::span<const u32> data);
std::size_t getImageWidth() const;
std::size_t getImageHeight() const;

View File

@@ -1,78 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "input_common/drivers/virtual_gamepad.h"
namespace InputCommon {
constexpr std::size_t PlayerIndexCount = 10;
VirtualGamepad::VirtualGamepad(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
for (std::size_t i = 0; i < PlayerIndexCount; i++) {
PreSetController(GetIdentifier(i));
}
}
void VirtualGamepad::SetButtonState(std::size_t player_index, int button_id, bool value) {
if (player_index > PlayerIndexCount) {
return;
}
const auto identifier = GetIdentifier(player_index);
SetButton(identifier, button_id, value);
}
void VirtualGamepad::SetButtonState(std::size_t player_index, VirtualButton button_id, bool value) {
SetButtonState(player_index, static_cast<int>(button_id), value);
}
void VirtualGamepad::SetStickPosition(std::size_t player_index, int axis_id, float x_value,
float y_value) {
if (player_index > PlayerIndexCount) {
return;
}
const auto identifier = GetIdentifier(player_index);
SetAxis(identifier, axis_id * 2, x_value);
SetAxis(identifier, (axis_id * 2) + 1, y_value);
}
void VirtualGamepad::SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
float y_value) {
SetStickPosition(player_index, static_cast<int>(axis_id), x_value, y_value);
}
void VirtualGamepad::ResetControllers() {
for (std::size_t i = 0; i < PlayerIndexCount; i++) {
SetStickPosition(i, VirtualStick::Left, 0.0f, 0.0f);
SetStickPosition(i, VirtualStick::Right, 0.0f, 0.0f);
SetButtonState(i, VirtualButton::ButtonA, false);
SetButtonState(i, VirtualButton::ButtonB, false);
SetButtonState(i, VirtualButton::ButtonX, false);
SetButtonState(i, VirtualButton::ButtonY, false);
SetButtonState(i, VirtualButton::StickL, false);
SetButtonState(i, VirtualButton::StickR, false);
SetButtonState(i, VirtualButton::TriggerL, false);
SetButtonState(i, VirtualButton::TriggerR, false);
SetButtonState(i, VirtualButton::TriggerZL, false);
SetButtonState(i, VirtualButton::TriggerZR, false);
SetButtonState(i, VirtualButton::ButtonPlus, false);
SetButtonState(i, VirtualButton::ButtonMinus, false);
SetButtonState(i, VirtualButton::ButtonLeft, false);
SetButtonState(i, VirtualButton::ButtonUp, false);
SetButtonState(i, VirtualButton::ButtonRight, false);
SetButtonState(i, VirtualButton::ButtonDown, false);
SetButtonState(i, VirtualButton::ButtonSL, false);
SetButtonState(i, VirtualButton::ButtonSR, false);
SetButtonState(i, VirtualButton::ButtonHome, false);
SetButtonState(i, VirtualButton::ButtonCapture, false);
}
}
PadIdentifier VirtualGamepad::GetIdentifier(std::size_t player_index) const {
return {
.guid = Common::UUID{},
.port = player_index,
.pad = 0,
};
}
} // namespace InputCommon

View File

@@ -1,73 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "input_common/input_engine.h"
namespace InputCommon {
/**
* A virtual controller that is always assigned to the game input
*/
class VirtualGamepad final : public InputEngine {
public:
enum class VirtualButton {
ButtonA,
ButtonB,
ButtonX,
ButtonY,
StickL,
StickR,
TriggerL,
TriggerR,
TriggerZL,
TriggerZR,
ButtonPlus,
ButtonMinus,
ButtonLeft,
ButtonUp,
ButtonRight,
ButtonDown,
ButtonSL,
ButtonSR,
ButtonHome,
ButtonCapture,
};
enum class VirtualStick {
Left = 0,
Right = 1,
};
explicit VirtualGamepad(std::string input_engine_);
/**
* Sets the status of all buttons bound with the key to pressed
* @param player_index the player number that will take this action
* @param button_id the id of the button
* @param value indicates if the button is pressed or not
*/
void SetButtonState(std::size_t player_index, int button_id, bool value);
void SetButtonState(std::size_t player_index, VirtualButton button_id, bool value);
/**
* Sets the status of all buttons bound with the key to released
* @param player_index the player number that will take this action
* @param axis_id the id of the axis to move
* @param x_value the position of the stick in the x axis
* @param y_value the position of the stick in the y axis
*/
void SetStickPosition(std::size_t player_index, int axis_id, float x_value, float y_value);
void SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
float y_value);
/// Restores all inputs into the neutral position
void ResetControllers();
private:
/// Returns the correct identifier corresponding to the player index
PadIdentifier GetIdentifier(std::size_t player_index) const;
};
} // namespace InputCommon

View File

@@ -12,7 +12,6 @@
#include "input_common/drivers/touch_screen.h"
#include "input_common/drivers/udp_client.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/drivers/virtual_gamepad.h"
#include "input_common/helpers/stick_from_buttons.h"
#include "input_common/helpers/touch_from_buttons.h"
#include "input_common/input_engine.h"
@@ -86,12 +85,6 @@ struct InputSubsystem::Impl {
Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(),
virtual_amiibo_output_factory);
virtual_gamepad = std::make_shared<VirtualGamepad>("virtual_gamepad");
virtual_gamepad->SetMappingCallback(mapping_callback);
virtual_gamepad_input_factory = std::make_shared<InputFactory>(virtual_gamepad);
Common::Input::RegisterInputFactory(virtual_gamepad->GetEngineName(),
virtual_gamepad_input_factory);
#ifdef HAVE_SDL2
sdl = std::make_shared<SDLDriver>("sdl");
sdl->SetMappingCallback(mapping_callback);
@@ -139,9 +132,6 @@ struct InputSubsystem::Impl {
Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName());
virtual_amiibo.reset();
Common::Input::UnregisterInputFactory(virtual_gamepad->GetEngineName());
virtual_gamepad.reset();
#ifdef HAVE_SDL2
Common::Input::UnregisterInputFactory(sdl->GetEngineName());
Common::Input::UnregisterOutputFactory(sdl->GetEngineName());
@@ -300,9 +290,6 @@ struct InputSubsystem::Impl {
if (engine == tas_input->GetEngineName()) {
return true;
}
if (engine == virtual_gamepad->GetEngineName()) {
return true;
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return true;
@@ -351,7 +338,6 @@ struct InputSubsystem::Impl {
std::shared_ptr<CemuhookUDP::UDPClient> udp_client;
std::shared_ptr<Camera> camera;
std::shared_ptr<VirtualAmiibo> virtual_amiibo;
std::shared_ptr<VirtualGamepad> virtual_gamepad;
std::shared_ptr<InputFactory> keyboard_factory;
std::shared_ptr<InputFactory> mouse_factory;
@@ -361,7 +347,6 @@ struct InputSubsystem::Impl {
std::shared_ptr<InputFactory> tas_input_factory;
std::shared_ptr<InputFactory> camera_input_factory;
std::shared_ptr<InputFactory> virtual_amiibo_input_factory;
std::shared_ptr<InputFactory> virtual_gamepad_input_factory;
std::shared_ptr<OutputFactory> keyboard_output_factory;
std::shared_ptr<OutputFactory> mouse_output_factory;
@@ -438,14 +423,6 @@ const VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() const {
return impl->virtual_amiibo.get();
}
VirtualGamepad* InputSubsystem::GetVirtualGamepad() {
return impl->virtual_gamepad.get();
}
const VirtualGamepad* InputSubsystem::GetVirtualGamepad() const {
return impl->virtual_gamepad.get();
}
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
return impl->GetInputDevices();
}

View File

@@ -34,7 +34,6 @@ class Keyboard;
class Mouse;
class TouchScreen;
class VirtualAmiibo;
class VirtualGamepad;
struct MappingData;
} // namespace InputCommon
@@ -109,12 +108,6 @@ public:
/// Retrieves the underlying virtual amiibo input device.
[[nodiscard]] const VirtualAmiibo* GetVirtualAmiibo() const;
/// Retrieves the underlying virtual gamepad input device.
[[nodiscard]] VirtualGamepad* GetVirtualGamepad();
/// Retrieves the underlying virtual gamepad input device.
[[nodiscard]] const VirtualGamepad* GetVirtualGamepad() const;
/**
* Returns all available input devices that this Factory can create a new device with.
* Each returned ParamPackage should have a `display` field used for display, a `engine` field

View File

@@ -461,7 +461,7 @@ void EmitSetSampleMask(EmitContext& ctx, Id value) {
}
void EmitSetFragDepth(EmitContext& ctx, Id value) {
if (!ctx.runtime_info.convert_depth_mode) {
if (!ctx.runtime_info.convert_depth_mode || ctx.profile.support_native_ndc) {
ctx.OpStore(ctx.frag_depth, value);
return;
}

View File

@@ -116,7 +116,8 @@ void EmitPrologue(EmitContext& ctx) {
}
void EmitEpilogue(EmitContext& ctx) {
if (ctx.stage == Stage::VertexB && ctx.runtime_info.convert_depth_mode) {
if (ctx.stage == Stage::VertexB && ctx.runtime_info.convert_depth_mode &&
!ctx.profile.support_native_ndc) {
ConvertDepthMode(ctx);
}
if (ctx.stage == Stage::Fragment) {
@@ -125,7 +126,7 @@ void EmitEpilogue(EmitContext& ctx) {
}
void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
if (ctx.runtime_info.convert_depth_mode) {
if (ctx.runtime_info.convert_depth_mode && !ctx.profile.support_native_ndc) {
ConvertDepthMode(ctx);
}
if (stream.IsImmediate()) {

View File

@@ -35,6 +35,7 @@ struct Profile {
bool support_int64_atomics{};
bool support_derivative_control{};
bool support_geometry_shader_passthrough{};
bool support_native_ndc{};
bool support_gl_nv_gpu_shader_5{};
bool support_gl_amd_gpu_shader_half_float{};
bool support_gl_texture_shadow_lod{};

View File

@@ -204,6 +204,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
.support_int64_atomics = false,
.support_derivative_control = device.HasDerivativeControl(),
.support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),
.support_native_ndc = true,
.support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
.support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
.support_gl_texture_shadow_lod = device.HasTextureShadowLod(),

View File

@@ -640,23 +640,33 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
};
std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles;
std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle);
const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{
VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
.pNext = nullptr,
.flags = 0,
.viewportCount = Maxwell::NumViewports,
.pViewportSwizzles = swizzles.data(),
};
const VkPipelineViewportStateCreateInfo viewport_ci{
VkPipelineViewportDepthClipControlCreateInfoEXT ndc_info{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
.pNext = nullptr,
.negativeOneToOne = key.state.ndc_minus_one_to_one.Value() != 0 ? VK_TRUE : VK_FALSE,
};
VkPipelineViewportStateCreateInfo viewport_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pNext = device.IsNvViewportSwizzleSupported() ? &swizzle_ci : nullptr,
.pNext = nullptr,
.flags = 0,
.viewportCount = Maxwell::NumViewports,
.pViewports = nullptr,
.scissorCount = Maxwell::NumViewports,
.pScissors = nullptr,
};
if (device.IsNvViewportSwizzleSupported()) {
swizzle_ci.pNext = std::exchange(viewport_ci.pNext, &swizzle_ci);
}
if (device.IsExtDepthClipControlSupported()) {
ndc_info.pNext = std::exchange(viewport_ci.pNext, &ndc_info);
}
VkPipelineRasterizationStateCreateInfo rasterization_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pNext = nullptr,

View File

@@ -321,6 +321,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
.support_derivative_control = true,
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
.support_native_ndc = device.IsExtDepthClipControlSupported(),
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),

View File

@@ -658,8 +658,7 @@ void RasterizerVulkan::BeginTransformFeedback() {
return;
}
UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) ||
regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation));
scheduler.Record(
[](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); });
}

View File

@@ -660,6 +660,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted");
}
VkPhysicalDeviceDepthClipControlFeaturesEXT depth_clip_control_features;
if (ext_depth_clip_control) {
depth_clip_control_features = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT,
.pNext = nullptr,
.depthClipControl = VK_TRUE,
};
SetNext(next, depth_clip_control_features);
}
VkDeviceDiagnosticsConfigCreateInfoNV diagnostics_nv;
if (Settings::values.enable_nsight_aftermath && nv_device_diagnostics_config) {
nsight_aftermath_tracker = std::make_unique<NsightAftermathTracker>();
@@ -1084,6 +1094,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
bool has_ext_vertex_input_dynamic_state{};
bool has_ext_line_rasterization{};
bool has_ext_primitive_topology_list_restart{};
bool has_ext_depth_clip_control{};
for (const std::string& extension : supported_extensions) {
const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name,
bool push) {
@@ -1117,6 +1128,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
test(ext_shader_stencil_export, VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, true);
test(ext_conservative_rasterization, VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME,
true);
test(has_ext_depth_clip_control, VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME, false);
test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false);
test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
@@ -1280,6 +1292,19 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
ext_line_rasterization = true;
}
}
if (has_ext_depth_clip_control) {
VkPhysicalDeviceDepthClipControlFeaturesEXT depth_clip_control_features;
depth_clip_control_features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT;
depth_clip_control_features.pNext = nullptr;
features.pNext = &depth_clip_control_features;
physical.GetFeatures2(features);
if (depth_clip_control_features.depthClipControl) {
extensions.push_back(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
ext_depth_clip_control = true;
}
}
if (has_khr_workgroup_memory_explicit_layout) {
VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR layout;
layout.sType =

View File

@@ -256,6 +256,11 @@ public:
return ext_depth_range_unrestricted;
}
/// Returns true if the device supports VK_EXT_depth_clip_control.
bool IsExtDepthClipControlSupported() const {
return ext_depth_clip_control;
}
/// Returns true if the device supports VK_EXT_shader_viewport_index_layer.
bool IsExtShaderViewportIndexLayerSupported() const {
return ext_shader_viewport_index_layer;
@@ -454,6 +459,7 @@ private:
bool khr_swapchain_mutable_format{}; ///< Support for VK_KHR_swapchain_mutable_format.
bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8.
bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax.
bool ext_depth_clip_control{}; ///< Support for VK_EXT_depth_clip_control
bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted.
bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer.
bool ext_tooling_info{}; ///< Support for VK_EXT_tooling_info.

View File

@@ -44,6 +44,8 @@
#include "yuzu/bootmanager.h"
#include "yuzu/main.h"
static Core::Frontend::WindowSystemType GetWindowSystemType();
EmuThread::EmuThread(Core::System& system_) : system{system_} {}
EmuThread::~EmuThread() = default;
@@ -228,8 +230,10 @@ class RenderWidget : public QWidget {
public:
explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) {
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_PaintOnScreen);
if (GetWindowSystemType() == Core::Frontend::WindowSystemType::Wayland) {
setAttribute(Qt::WA_DontCreateNativeAncestors);
}
}
virtual ~RenderWidget() = default;
@@ -274,12 +278,14 @@ static Core::Frontend::WindowSystemType GetWindowSystemType() {
return Core::Frontend::WindowSystemType::X11;
else if (platform_name == QStringLiteral("wayland"))
return Core::Frontend::WindowSystemType::Wayland;
else if (platform_name == QStringLiteral("wayland-egl"))
return Core::Frontend::WindowSystemType::Wayland;
else if (platform_name == QStringLiteral("cocoa"))
return Core::Frontend::WindowSystemType::Cocoa;
else if (platform_name == QStringLiteral("android"))
return Core::Frontend::WindowSystemType::Android;
LOG_CRITICAL(Frontend, "Unknown Qt platform!");
LOG_CRITICAL(Frontend, "Unknown Qt platform {}!", platform_name.toStdString());
return Core::Frontend::WindowSystemType::Windows;
}
@@ -319,7 +325,8 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
input_subsystem->Initialize();
this->setMouseTracking(true);
strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland");
strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland") ||
QGuiApplication::platformName() == QStringLiteral("wayland-egl");
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
@@ -757,6 +764,7 @@ void GRenderWindow::InitializeCamera() {
return;
}
camera_data.resize(CAMERA_WIDTH * CAMERA_HEIGHT);
camera_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer);
connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this,
&GRenderWindow::OnCameraCapture);
@@ -812,16 +820,13 @@ void GRenderWindow::RequestCameraCapture() {
}
void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) {
constexpr std::size_t camera_width = 320;
constexpr std::size_t camera_height = 240;
// TODO: Capture directly in the format and resolution needed
const auto converted =
img.scaled(camera_width, camera_height, Qt::AspectRatioMode::IgnoreAspectRatio,
img.scaled(CAMERA_WIDTH, CAMERA_HEIGHT, Qt::AspectRatioMode::IgnoreAspectRatio,
Qt::TransformationMode::SmoothTransformation)
.mirrored(false, true);
std::vector<u32> camera_data{};
camera_data.resize(camera_width * camera_height);
std::memcpy(camera_data.data(), converted.bits(), camera_width * camera_height * sizeof(u32));
input_subsystem->GetCamera()->SetCameraData(camera_width, camera_height, camera_data);
std::memcpy(camera_data.data(), converted.bits(), CAMERA_WIDTH * CAMERA_HEIGHT * sizeof(u32));
input_subsystem->GetCamera()->SetCameraData(CAMERA_WIDTH, CAMERA_HEIGHT, camera_data);
pending_camera_snapshots = 0;
}

View File

@@ -247,6 +247,9 @@ private:
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
std::unique_ptr<QCamera> camera;
std::unique_ptr<QCameraImageCapture> camera_capture;
static constexpr std::size_t CAMERA_WIDTH = 320;
static constexpr std::size_t CAMERA_HEIGHT = 240;
std::vector<u32> camera_data;
#endif
std::unique_ptr<QTimer> camera_timer;

View File

@@ -269,7 +269,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
InputCommon::InputSubsystem* input_subsystem_,
InputProfiles* profiles_, Core::HID::HIDCore& hid_core_,
bool is_powered_on_, bool debug_)
: QWidget(parent),
: QScrollArea(parent),
ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index{player_index_}, debug{debug_},
is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, profiles(profiles_),
timeout_timer(std::make_unique<QTimer>()),

View File

@@ -10,7 +10,7 @@
#include <string>
#include <vector>
#include <QWidget>
#include <QScrollArea>
#include "common/param_package.h"
#include "common/settings.h"
@@ -46,7 +46,7 @@ class EmulatedController;
enum class NpadStyleIndex : u8;
} // namespace Core::HID
class ConfigureInputPlayer : public QWidget {
class ConfigureInputPlayer : public QScrollArea {
Q_OBJECT
public:

File diff suppressed because it is too large Load Diff

View File

@@ -3067,7 +3067,8 @@ static QScreen* GuessCurrentScreen(QWidget* window) {
bool GMainWindow::UsingExclusiveFullscreen() {
return Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive ||
QGuiApplication::platformName() == QStringLiteral("wayland");
QGuiApplication::platformName() == QStringLiteral("wayland") ||
QGuiApplication::platformName() == QStringLiteral("wayland-egl");
}
void GMainWindow::ShowFullscreen() {