summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/device/audio_buffers.h8
-rw-r--r--src/audio_core/device/device_session.cpp6
-rw-r--r--src/audio_core/device/device_session.h5
-rw-r--r--src/audio_core/in/audio_in_system.cpp7
-rw-r--r--src/audio_core/out/audio_out_system.cpp7
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp14
-rw-r--r--src/input_common/drivers/camera.cpp2
-rw-r--r--src/input_common/drivers/camera.h4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_special.cpp5
-rw-r--r--src/shader_recompiler/profile.h1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp18
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp3
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp25
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h6
-rw-r--r--src/yuzu/bootmanager.cpp25
-rw-r--r--src/yuzu/bootmanager.h3
-rw-r--r--src/yuzu/main.cpp3
20 files changed, 109 insertions, 37 deletions
diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h
index 3dae1a3b7..15082f6c6 100644
--- a/src/audio_core/device/audio_buffers.h
+++ b/src/audio_core/device/audio_buffers.h
@@ -91,9 +91,10 @@ public:
91 * @param core_timing - The CoreTiming instance 91 * @param core_timing - The CoreTiming instance
92 * @param session - The device session 92 * @param session - The device session
93 * 93 *
94 * @return Is the buffer was released. 94 * @return If any buffer was released.
95 */ 95 */
96 bool ReleaseBuffers(const Core::Timing::CoreTiming& core_timing, const DeviceSession& session) { 96 bool ReleaseBuffers(const Core::Timing::CoreTiming& core_timing, const DeviceSession& session,
97 bool force) {
97 std::scoped_lock l{lock}; 98 std::scoped_lock l{lock};
98 bool buffer_released{false}; 99 bool buffer_released{false};
99 while (registered_count > 0) { 100 while (registered_count > 0) {
@@ -103,7 +104,8 @@ public:
103 } 104 }
104 105
105 // Check with the backend if this buffer can be released yet. 106 // Check with the backend if this buffer can be released yet.
106 if (!session.IsBufferConsumed(buffers[index])) { 107 // If we're shutting down, we don't care if it's been played or not.
108 if (!force && !session.IsBufferConsumed(buffers[index])) {
107 break; 109 break;
108 } 110 }
109 111
diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp
index 995060414..5a327a606 100644
--- a/src/audio_core/device/device_session.cpp
+++ b/src/audio_core/device/device_session.cpp
@@ -73,6 +73,12 @@ void DeviceSession::Stop() {
73 } 73 }
74} 74}
75 75
76void DeviceSession::ClearBuffers() {
77 if (stream) {
78 stream->ClearQueue();
79 }
80}
81
76void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const { 82void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const {
77 for (const auto& buffer : buffers) { 83 for (const auto& buffer : buffers) {
78 Sink::SinkBuffer new_buffer{ 84 Sink::SinkBuffer new_buffer{
diff --git a/src/audio_core/device/device_session.h b/src/audio_core/device/device_session.h
index 74f4dc085..75f766c68 100644
--- a/src/audio_core/device/device_session.h
+++ b/src/audio_core/device/device_session.h
@@ -91,6 +91,11 @@ public:
91 void Stop(); 91 void Stop();
92 92
93 /** 93 /**
94 * Clear out the underlying audio buffers in the backend stream.
95 */
96 void ClearBuffers();
97
98 /**
94 * Set this device session's volume. 99 * Set this device session's volume.
95 * 100 *
96 * @param volume - New volume for this session. 101 * @param volume - New volume for this session.
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp
index 4324cafd8..934ef8c1c 100644
--- a/src/audio_core/in/audio_in_system.cpp
+++ b/src/audio_core/in/audio_in_system.cpp
@@ -23,7 +23,6 @@ System::~System() {
23void System::Finalize() { 23void System::Finalize() {
24 Stop(); 24 Stop();
25 session->Finalize(); 25 session->Finalize();
26 buffer_event->Signal();
27} 26}
28 27
29void System::StartSession() { 28void System::StartSession() {
@@ -102,6 +101,10 @@ Result System::Stop() {
102 if (state == State::Started) { 101 if (state == State::Started) {
103 session->Stop(); 102 session->Stop();
104 session->SetVolume(0.0f); 103 session->SetVolume(0.0f);
104 session->ClearBuffers();
105 if (buffers.ReleaseBuffers(system.CoreTiming(), *session, true)) {
106 buffer_event->Signal();
107 }
105 state = State::Stopped; 108 state = State::Stopped;
106 } 109 }
107 110
@@ -138,7 +141,7 @@ void System::RegisterBuffers() {
138} 141}
139 142
140void System::ReleaseBuffers() { 143void System::ReleaseBuffers() {
141 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)}; 144 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session, false)};
142 145
143 if (signal) { 146 if (signal) {
144 // Signal if any buffer was released, or if none are registered, we need more. 147 // Signal if any buffer was released, or if none are registered, we need more.
diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp
index a66208ed9..e096a1dac 100644
--- a/src/audio_core/out/audio_out_system.cpp
+++ b/src/audio_core/out/audio_out_system.cpp
@@ -24,7 +24,6 @@ System::~System() {
24void System::Finalize() { 24void System::Finalize() {
25 Stop(); 25 Stop();
26 session->Finalize(); 26 session->Finalize();
27 buffer_event->Signal();
28} 27}
29 28
30std::string_view System::GetDefaultOutputDeviceName() const { 29std::string_view System::GetDefaultOutputDeviceName() const {
@@ -102,6 +101,10 @@ Result System::Stop() {
102 if (state == State::Started) { 101 if (state == State::Started) {
103 session->Stop(); 102 session->Stop();
104 session->SetVolume(0.0f); 103 session->SetVolume(0.0f);
104 session->ClearBuffers();
105 if (buffers.ReleaseBuffers(system.CoreTiming(), *session, true)) {
106 buffer_event->Signal();
107 }
105 state = State::Stopped; 108 state = State::Stopped;
106 } 109 }
107 110
@@ -138,7 +141,7 @@ void System::RegisterBuffers() {
138} 141}
139 142
140void System::ReleaseBuffers() { 143void System::ReleaseBuffers() {
141 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)}; 144 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session, false)};
142 if (signal) { 145 if (signal) {
143 // Signal if any buffer was released, or if none are registered, we need more. 146 // Signal if any buffer was released, or if none are registered, we need more.
144 buffer_event->Signal(); 147 buffer_event->Signal();
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index e6479c131..738b6d0f1 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -326,25 +326,23 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_threa
326} 326}
327 327
328std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { 328std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
329 std::vector<u8> buffer{};
330 const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && 329 const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
331 BufferDescriptorA()[buffer_index].Size()}; 330 BufferDescriptorA()[buffer_index].Size()};
332
333 if (is_buffer_a) { 331 if (is_buffer_a) {
334 ASSERT_OR_EXECUTE_MSG( 332 ASSERT_OR_EXECUTE_MSG(
335 BufferDescriptorA().size() > buffer_index, { return buffer; }, 333 BufferDescriptorA().size() > buffer_index, { return {}; },
336 "BufferDescriptorA invalid buffer_index {}", buffer_index); 334 "BufferDescriptorA invalid buffer_index {}", buffer_index);
337 buffer.resize(BufferDescriptorA()[buffer_index].Size()); 335 std::vector<u8> buffer(BufferDescriptorA()[buffer_index].Size());
338 memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); 336 memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size());
337 return buffer;
339 } else { 338 } else {
340 ASSERT_OR_EXECUTE_MSG( 339 ASSERT_OR_EXECUTE_MSG(
341 BufferDescriptorX().size() > buffer_index, { return buffer; }, 340 BufferDescriptorX().size() > buffer_index, { return {}; },
342 "BufferDescriptorX invalid buffer_index {}", buffer_index); 341 "BufferDescriptorX invalid buffer_index {}", buffer_index);
343 buffer.resize(BufferDescriptorX()[buffer_index].Size()); 342 std::vector<u8> buffer(BufferDescriptorX()[buffer_index].Size());
344 memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); 343 memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size());
344 return buffer;
345 } 345 }
346
347 return buffer;
348} 346}
349 347
350std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, 348std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
diff --git a/src/input_common/drivers/camera.cpp b/src/input_common/drivers/camera.cpp
index dceea67e0..fad9177dc 100644
--- a/src/input_common/drivers/camera.cpp
+++ b/src/input_common/drivers/camera.cpp
@@ -17,7 +17,7 @@ Camera::Camera(std::string input_engine_) : InputEngine(std::move(input_engine_)
17 PreSetController(identifier); 17 PreSetController(identifier);
18} 18}
19 19
20void Camera::SetCameraData(std::size_t width, std::size_t height, std::vector<u32> data) { 20void Camera::SetCameraData(std::size_t width, std::size_t height, std::span<const u32> data) {
21 const std::size_t desired_width = getImageWidth(); 21 const std::size_t desired_width = getImageWidth();
22 const std::size_t desired_height = getImageHeight(); 22 const std::size_t desired_height = getImageHeight();
23 status.data.resize(desired_width * desired_height); 23 status.data.resize(desired_width * desired_height);
diff --git a/src/input_common/drivers/camera.h b/src/input_common/drivers/camera.h
index b8a7c75e5..38fb1ae4c 100644
--- a/src/input_common/drivers/camera.h
+++ b/src/input_common/drivers/camera.h
@@ -3,6 +3,8 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <span>
7
6#include "input_common/input_engine.h" 8#include "input_common/input_engine.h"
7 9
8namespace InputCommon { 10namespace InputCommon {
@@ -15,7 +17,7 @@ class Camera final : public InputEngine {
15public: 17public:
16 explicit Camera(std::string input_engine_); 18 explicit Camera(std::string input_engine_);
17 19
18 void SetCameraData(std::size_t width, std::size_t height, std::vector<u32> data); 20 void SetCameraData(std::size_t width, std::size_t height, std::span<const u32> data);
19 21
20 std::size_t getImageWidth() const; 22 std::size_t getImageWidth() const;
21 std::size_t getImageHeight() const; 23 std::size_t getImageHeight() const;
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index 01f6ec9b5..73b67f0af 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -461,7 +461,7 @@ void EmitSetSampleMask(EmitContext& ctx, Id value) {
461} 461}
462 462
463void EmitSetFragDepth(EmitContext& ctx, Id value) { 463void EmitSetFragDepth(EmitContext& ctx, Id value) {
464 if (!ctx.runtime_info.convert_depth_mode) { 464 if (!ctx.runtime_info.convert_depth_mode || ctx.profile.support_native_ndc) {
465 ctx.OpStore(ctx.frag_depth, value); 465 ctx.OpStore(ctx.frag_depth, value);
466 return; 466 return;
467 } 467 }
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
index 00be1f127..9f7b6bb4b 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
@@ -116,7 +116,8 @@ void EmitPrologue(EmitContext& ctx) {
116} 116}
117 117
118void EmitEpilogue(EmitContext& ctx) { 118void EmitEpilogue(EmitContext& ctx) {
119 if (ctx.stage == Stage::VertexB && ctx.runtime_info.convert_depth_mode) { 119 if (ctx.stage == Stage::VertexB && ctx.runtime_info.convert_depth_mode &&
120 !ctx.profile.support_native_ndc) {
120 ConvertDepthMode(ctx); 121 ConvertDepthMode(ctx);
121 } 122 }
122 if (ctx.stage == Stage::Fragment) { 123 if (ctx.stage == Stage::Fragment) {
@@ -125,7 +126,7 @@ void EmitEpilogue(EmitContext& ctx) {
125} 126}
126 127
127void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { 128void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
128 if (ctx.runtime_info.convert_depth_mode) { 129 if (ctx.runtime_info.convert_depth_mode && !ctx.profile.support_native_ndc) {
129 ConvertDepthMode(ctx); 130 ConvertDepthMode(ctx);
130 } 131 }
131 if (stream.IsImmediate()) { 132 if (stream.IsImmediate()) {
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h
index 21d3d236b..b8841a536 100644
--- a/src/shader_recompiler/profile.h
+++ b/src/shader_recompiler/profile.h
@@ -35,6 +35,7 @@ struct Profile {
35 bool support_int64_atomics{}; 35 bool support_int64_atomics{};
36 bool support_derivative_control{}; 36 bool support_derivative_control{};
37 bool support_geometry_shader_passthrough{}; 37 bool support_geometry_shader_passthrough{};
38 bool support_native_ndc{};
38 bool support_gl_nv_gpu_shader_5{}; 39 bool support_gl_nv_gpu_shader_5{};
39 bool support_gl_amd_gpu_shader_half_float{}; 40 bool support_gl_amd_gpu_shader_half_float{};
40 bool support_gl_texture_shadow_lod{}; 41 bool support_gl_texture_shadow_lod{};
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index fff55d585..f8868a012 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -204,6 +204,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
204 .support_int64_atomics = false, 204 .support_int64_atomics = false,
205 .support_derivative_control = device.HasDerivativeControl(), 205 .support_derivative_control = device.HasDerivativeControl(),
206 .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(), 206 .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),
207 .support_native_ndc = true,
207 .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(), 208 .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
208 .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(), 209 .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
209 .support_gl_texture_shadow_lod = device.HasTextureShadowLod(), 210 .support_gl_texture_shadow_lod = device.HasTextureShadowLod(),
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 4b10fe7bc..515d8d869 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -640,23 +640,33 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
640 }; 640 };
641 std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles; 641 std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles;
642 std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle); 642 std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle);
643 const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{ 643 VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{
644 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV, 644 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
645 .pNext = nullptr, 645 .pNext = nullptr,
646 .flags = 0, 646 .flags = 0,
647 .viewportCount = Maxwell::NumViewports, 647 .viewportCount = Maxwell::NumViewports,
648 .pViewportSwizzles = swizzles.data(), 648 .pViewportSwizzles = swizzles.data(),
649 }; 649 };
650 const VkPipelineViewportStateCreateInfo viewport_ci{ 650 VkPipelineViewportDepthClipControlCreateInfoEXT ndc_info{
651 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
652 .pNext = nullptr,
653 .negativeOneToOne = key.state.ndc_minus_one_to_one.Value() != 0 ? VK_TRUE : VK_FALSE,
654 };
655 VkPipelineViewportStateCreateInfo viewport_ci{
651 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 656 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
652 .pNext = device.IsNvViewportSwizzleSupported() ? &swizzle_ci : nullptr, 657 .pNext = nullptr,
653 .flags = 0, 658 .flags = 0,
654 .viewportCount = Maxwell::NumViewports, 659 .viewportCount = Maxwell::NumViewports,
655 .pViewports = nullptr, 660 .pViewports = nullptr,
656 .scissorCount = Maxwell::NumViewports, 661 .scissorCount = Maxwell::NumViewports,
657 .pScissors = nullptr, 662 .pScissors = nullptr,
658 }; 663 };
659 664 if (device.IsNvViewportSwizzleSupported()) {
665 swizzle_ci.pNext = std::exchange(viewport_ci.pNext, &swizzle_ci);
666 }
667 if (device.IsExtDepthClipControlSupported()) {
668 ndc_info.pNext = std::exchange(viewport_ci.pNext, &ndc_info);
669 }
660 VkPipelineRasterizationStateCreateInfo rasterization_ci{ 670 VkPipelineRasterizationStateCreateInfo rasterization_ci{
661 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 671 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
662 .pNext = nullptr, 672 .pNext = nullptr,
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 86fdde014..e7262420c 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -321,6 +321,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
321 .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(), 321 .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
322 .support_derivative_control = true, 322 .support_derivative_control = true,
323 .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), 323 .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
324 .support_native_ndc = device.IsExtDepthClipControlSupported(),
324 325
325 .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), 326 .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
326 327
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index a8b82abae..4b7126c30 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -658,8 +658,7 @@ void RasterizerVulkan::BeginTransformFeedback() {
658 return; 658 return;
659 } 659 }
660 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || 660 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
661 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) || 661 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation));
662 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
663 scheduler.Record( 662 scheduler.Record(
664 [](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); }); 663 [](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); });
665} 664}
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index f45030311..c4d31681a 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -660,6 +660,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
660 LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted"); 660 LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted");
661 } 661 }
662 662
663 VkPhysicalDeviceDepthClipControlFeaturesEXT depth_clip_control_features;
664 if (ext_depth_clip_control) {
665 depth_clip_control_features = {
666 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT,
667 .pNext = nullptr,
668 .depthClipControl = VK_TRUE,
669 };
670 SetNext(next, depth_clip_control_features);
671 }
672
663 VkDeviceDiagnosticsConfigCreateInfoNV diagnostics_nv; 673 VkDeviceDiagnosticsConfigCreateInfoNV diagnostics_nv;
664 if (Settings::values.enable_nsight_aftermath && nv_device_diagnostics_config) { 674 if (Settings::values.enable_nsight_aftermath && nv_device_diagnostics_config) {
665 nsight_aftermath_tracker = std::make_unique<NsightAftermathTracker>(); 675 nsight_aftermath_tracker = std::make_unique<NsightAftermathTracker>();
@@ -1084,6 +1094,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
1084 bool has_ext_vertex_input_dynamic_state{}; 1094 bool has_ext_vertex_input_dynamic_state{};
1085 bool has_ext_line_rasterization{}; 1095 bool has_ext_line_rasterization{};
1086 bool has_ext_primitive_topology_list_restart{}; 1096 bool has_ext_primitive_topology_list_restart{};
1097 bool has_ext_depth_clip_control{};
1087 for (const std::string& extension : supported_extensions) { 1098 for (const std::string& extension : supported_extensions) {
1088 const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, 1099 const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name,
1089 bool push) { 1100 bool push) {
@@ -1117,6 +1128,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
1117 test(ext_shader_stencil_export, VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, true); 1128 test(ext_shader_stencil_export, VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, true);
1118 test(ext_conservative_rasterization, VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, 1129 test(ext_conservative_rasterization, VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME,
1119 true); 1130 true);
1131 test(has_ext_depth_clip_control, VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME, false);
1120 test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false); 1132 test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false);
1121 test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); 1133 test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
1122 test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); 1134 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) {
1280 ext_line_rasterization = true; 1292 ext_line_rasterization = true;
1281 } 1293 }
1282 } 1294 }
1295 if (has_ext_depth_clip_control) {
1296 VkPhysicalDeviceDepthClipControlFeaturesEXT depth_clip_control_features;
1297 depth_clip_control_features.sType =
1298 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT;
1299 depth_clip_control_features.pNext = nullptr;
1300 features.pNext = &depth_clip_control_features;
1301 physical.GetFeatures2(features);
1302
1303 if (depth_clip_control_features.depthClipControl) {
1304 extensions.push_back(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
1305 ext_depth_clip_control = true;
1306 }
1307 }
1283 if (has_khr_workgroup_memory_explicit_layout) { 1308 if (has_khr_workgroup_memory_explicit_layout) {
1284 VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR layout; 1309 VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR layout;
1285 layout.sType = 1310 layout.sType =
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 391b7604c..6a26c4e6e 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -256,6 +256,11 @@ public:
256 return ext_depth_range_unrestricted; 256 return ext_depth_range_unrestricted;
257 } 257 }
258 258
259 /// Returns true if the device supports VK_EXT_depth_clip_control.
260 bool IsExtDepthClipControlSupported() const {
261 return ext_depth_clip_control;
262 }
263
259 /// Returns true if the device supports VK_EXT_shader_viewport_index_layer. 264 /// Returns true if the device supports VK_EXT_shader_viewport_index_layer.
260 bool IsExtShaderViewportIndexLayerSupported() const { 265 bool IsExtShaderViewportIndexLayerSupported() const {
261 return ext_shader_viewport_index_layer; 266 return ext_shader_viewport_index_layer;
@@ -454,6 +459,7 @@ private:
454 bool khr_swapchain_mutable_format{}; ///< Support for VK_KHR_swapchain_mutable_format. 459 bool khr_swapchain_mutable_format{}; ///< Support for VK_KHR_swapchain_mutable_format.
455 bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. 460 bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8.
456 bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. 461 bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax.
462 bool ext_depth_clip_control{}; ///< Support for VK_EXT_depth_clip_control
457 bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. 463 bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted.
458 bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer. 464 bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer.
459 bool ext_tooling_info{}; ///< Support for VK_EXT_tooling_info. 465 bool ext_tooling_info{}; ///< Support for VK_EXT_tooling_info.
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 642f96690..682b37f47 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -44,6 +44,8 @@
44#include "yuzu/bootmanager.h" 44#include "yuzu/bootmanager.h"
45#include "yuzu/main.h" 45#include "yuzu/main.h"
46 46
47static Core::Frontend::WindowSystemType GetWindowSystemType();
48
47EmuThread::EmuThread(Core::System& system_) : system{system_} {} 49EmuThread::EmuThread(Core::System& system_) : system{system_} {}
48 50
49EmuThread::~EmuThread() = default; 51EmuThread::~EmuThread() = default;
@@ -228,8 +230,10 @@ class RenderWidget : public QWidget {
228public: 230public:
229 explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) { 231 explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) {
230 setAttribute(Qt::WA_NativeWindow); 232 setAttribute(Qt::WA_NativeWindow);
231 setAttribute(Qt::WA_DontCreateNativeAncestors);
232 setAttribute(Qt::WA_PaintOnScreen); 233 setAttribute(Qt::WA_PaintOnScreen);
234 if (GetWindowSystemType() == Core::Frontend::WindowSystemType::Wayland) {
235 setAttribute(Qt::WA_DontCreateNativeAncestors);
236 }
233 } 237 }
234 238
235 virtual ~RenderWidget() = default; 239 virtual ~RenderWidget() = default;
@@ -274,12 +278,14 @@ static Core::Frontend::WindowSystemType GetWindowSystemType() {
274 return Core::Frontend::WindowSystemType::X11; 278 return Core::Frontend::WindowSystemType::X11;
275 else if (platform_name == QStringLiteral("wayland")) 279 else if (platform_name == QStringLiteral("wayland"))
276 return Core::Frontend::WindowSystemType::Wayland; 280 return Core::Frontend::WindowSystemType::Wayland;
281 else if (platform_name == QStringLiteral("wayland-egl"))
282 return Core::Frontend::WindowSystemType::Wayland;
277 else if (platform_name == QStringLiteral("cocoa")) 283 else if (platform_name == QStringLiteral("cocoa"))
278 return Core::Frontend::WindowSystemType::Cocoa; 284 return Core::Frontend::WindowSystemType::Cocoa;
279 else if (platform_name == QStringLiteral("android")) 285 else if (platform_name == QStringLiteral("android"))
280 return Core::Frontend::WindowSystemType::Android; 286 return Core::Frontend::WindowSystemType::Android;
281 287
282 LOG_CRITICAL(Frontend, "Unknown Qt platform!"); 288 LOG_CRITICAL(Frontend, "Unknown Qt platform {}!", platform_name.toStdString());
283 return Core::Frontend::WindowSystemType::Windows; 289 return Core::Frontend::WindowSystemType::Windows;
284} 290}
285 291
@@ -319,7 +325,8 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
319 input_subsystem->Initialize(); 325 input_subsystem->Initialize();
320 this->setMouseTracking(true); 326 this->setMouseTracking(true);
321 327
322 strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland"); 328 strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland") ||
329 QGuiApplication::platformName() == QStringLiteral("wayland-egl");
323 330
324 connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); 331 connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
325 connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram, 332 connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
@@ -757,6 +764,7 @@ void GRenderWindow::InitializeCamera() {
757 return; 764 return;
758 } 765 }
759 766
767 camera_data.resize(CAMERA_WIDTH * CAMERA_HEIGHT);
760 camera_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer); 768 camera_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer);
761 connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this, 769 connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this,
762 &GRenderWindow::OnCameraCapture); 770 &GRenderWindow::OnCameraCapture);
@@ -812,16 +820,13 @@ void GRenderWindow::RequestCameraCapture() {
812} 820}
813 821
814void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) { 822void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) {
815 constexpr std::size_t camera_width = 320; 823 // TODO: Capture directly in the format and resolution needed
816 constexpr std::size_t camera_height = 240;
817 const auto converted = 824 const auto converted =
818 img.scaled(camera_width, camera_height, Qt::AspectRatioMode::IgnoreAspectRatio, 825 img.scaled(CAMERA_WIDTH, CAMERA_HEIGHT, Qt::AspectRatioMode::IgnoreAspectRatio,
819 Qt::TransformationMode::SmoothTransformation) 826 Qt::TransformationMode::SmoothTransformation)
820 .mirrored(false, true); 827 .mirrored(false, true);
821 std::vector<u32> camera_data{}; 828 std::memcpy(camera_data.data(), converted.bits(), CAMERA_WIDTH * CAMERA_HEIGHT * sizeof(u32));
822 camera_data.resize(camera_width * camera_height); 829 input_subsystem->GetCamera()->SetCameraData(CAMERA_WIDTH, CAMERA_HEIGHT, camera_data);
823 std::memcpy(camera_data.data(), converted.bits(), camera_width * camera_height * sizeof(u32));
824 input_subsystem->GetCamera()->SetCameraData(camera_width, camera_height, camera_data);
825 pending_camera_snapshots = 0; 830 pending_camera_snapshots = 0;
826} 831}
827 832
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index f0edad6e4..5bbcf61f7 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -247,6 +247,9 @@ private:
247#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA 247#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
248 std::unique_ptr<QCamera> camera; 248 std::unique_ptr<QCamera> camera;
249 std::unique_ptr<QCameraImageCapture> camera_capture; 249 std::unique_ptr<QCameraImageCapture> camera_capture;
250 static constexpr std::size_t CAMERA_WIDTH = 320;
251 static constexpr std::size_t CAMERA_HEIGHT = 240;
252 std::vector<u32> camera_data;
250#endif 253#endif
251 std::unique_ptr<QTimer> camera_timer; 254 std::unique_ptr<QTimer> camera_timer;
252 255
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 70552bdb8..2e6c2311a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -3067,7 +3067,8 @@ static QScreen* GuessCurrentScreen(QWidget* window) {
3067 3067
3068bool GMainWindow::UsingExclusiveFullscreen() { 3068bool GMainWindow::UsingExclusiveFullscreen() {
3069 return Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive || 3069 return Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive ||
3070 QGuiApplication::platformName() == QStringLiteral("wayland"); 3070 QGuiApplication::platformName() == QStringLiteral("wayland") ||
3071 QGuiApplication::platformName() == QStringLiteral("wayland-egl");
3071} 3072}
3072 3073
3073void GMainWindow::ShowFullscreen() { 3074void GMainWindow::ShowFullscreen() {