diff --git a/README.md b/README.md index a6d661829..1883095d9 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2222. +This is the source code for early-access 2223. ## Legal Notice diff --git a/src/core/hid/hid_core.h b/src/core/hid/hid_core.h index 1fe2fd89b..609f40f3b 100755 --- a/src/core/hid/hid_core.h +++ b/src/core/hid/hid_core.h @@ -52,7 +52,7 @@ public: void UnloadInputDevices(); /// Number of emulated controllers - const std::size_t available_controllers{10}; + static constexpr std::size_t available_controllers{10}; private: std::unique_ptr player_1; diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 87042195a..a2e046f12 100755 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -11,6 +11,7 @@ set(SHADER_FILES block_linear_unswizzle_2d.comp block_linear_unswizzle_3d.comp convert_abgr8_to_d24s8.frag + convert_b10g11r11_to_d24s8.frag convert_d24s8_to_abgr8.frag convert_d24s8_to_b10g11r11.frag convert_d24s8_to_r16g16.frag diff --git a/src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag b/src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag new file mode 100755 index 000000000..b7358c15c --- /dev/null +++ b/src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag @@ -0,0 +1,19 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#version 450 +// #extension GL_ARB_shader_stencil_export : require + +layout(binding = 0) uniform sampler2D color_texture; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + vec4 color = texelFetch(color_texture, coord, 0).rgba; + uint depth_stencil_unorm = (uint(color.b * (exp2(10) - 1.0f)) << 22) + | (uint(color.g * (exp2(11) - 1.0f)) << 11) + | (uint(color.r * (exp2(11) - 1.0f))); + + gl_FragDepth = float(depth_stencil_unorm >> 8) / (exp2(24.0) - 1.0f); + // gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FF); +} diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 12b28aadd..e70459de5 100755 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -5,6 +5,7 @@ #include #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" +#include "video_core/host_shaders/convert_b10g11r11_to_d24s8_frag_spv.h" #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_d24s8_to_b10g11r11_frag_spv.h" #include "video_core/host_shaders/convert_d24s8_to_r16g16_frag_spv.h" @@ -359,6 +360,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), + convert_b10g11r11_to_d24s8_frag(BuildShader(device, CONVERT_B10G11R11_TO_D24S8_FRAG_SPV)), convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), convert_d24s8_to_b10g11r11_frag(BuildShader(device, CONVERT_D24S8_TO_B10G11R11_FRAG_SPV)), convert_d24s8_to_r16g16_frag(BuildShader(device, CONVERT_D24S8_TO_R16G16_FRAG_SPV)), @@ -459,16 +461,25 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, u32 up_scale, u32 down_shift) { - ConvertPipelineEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), - convert_abgr8_to_d24s8_frag, true); + ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), + convert_abgr8_to_d24s8_frag, true); Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); } +void BlitImageHelper::ConvertB10G11R11ToD24S8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view, u32 up_scale, + u32 down_shift) { + ConvertPipelineDepthTargetEx(convert_b10g11r11_to_d24s8_pipeline, dst_framebuffer->RenderPass(), + convert_b10g11r11_to_d24s8_frag, true); + Convert(*convert_b10g11r11_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, + down_shift); +} + void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, u32 up_scale, u32 down_shift) { - ConvertPipelineEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), - convert_d24s8_to_abgr8_frag, false); + ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), + convert_d24s8_to_abgr8_frag, false); ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); } @@ -476,8 +487,8 @@ void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertD24S8ToB10G11R11(const Framebuffer* dst_framebuffer, ImageView& src_image_view, u32 up_scale, u32 down_shift) { - ConvertPipelineEx(convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer->RenderPass(), - convert_d24s8_to_b10g11r11_frag, false); + ConvertPipelineColorTargetEx(convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer->RenderPass(), + convert_d24s8_to_b10g11r11_frag, false); ConvertDepthStencil(*convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); } @@ -485,8 +496,8 @@ void BlitImageHelper::ConvertD24S8ToB10G11R11(const Framebuffer* dst_framebuffer void BlitImageHelper::ConvertD24S8ToR16G16(const Framebuffer* dst_framebuffer, ImageView& src_image_view, u32 up_scale, u32 down_shift) { - ConvertPipelineEx(convert_d24s8_to_r16g16_pipeline, dst_framebuffer->RenderPass(), - convert_d24s8_to_r16g16_frag, false); + ConvertPipelineColorTargetEx(convert_d24s8_to_r16g16_pipeline, dst_framebuffer->RenderPass(), + convert_d24s8_to_r16g16_frag, false); ConvertDepthStencil(*convert_d24s8_to_r16g16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); } @@ -540,7 +551,7 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, ImageView& src_image_view, u32 up_scale, u32 down_shift) { - const VkPipelineLayout layout = *one_texture_pipeline_layout; + const VkPipelineLayout layout = *two_textures_pipeline_layout; const VkImageView src_depth_view = src_image_view.DepthView(); const VkImageView src_stencil_view = src_image_view.StencilView(); const VkSampler sampler = *nearest_sampler; @@ -727,8 +738,37 @@ void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRend }); } -void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, - vk::ShaderModule& module, bool single_texture) { +void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, + vk::ShaderModule& module, bool single_texture) { + if (pipeline) { + return; + } + const std::array stages = MakeStages(*full_screen_vert, *module); + pipeline = device.GetLogical().CreateGraphicsPipeline({ + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stageCount = static_cast(stages.size()), + .pStages = stages.data(), + .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .pTessellationState = nullptr, + .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .pDepthStencilState = nullptr, + .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, + .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .layout = single_texture ? *one_texture_pipeline_layout : *two_textures_pipeline_layout, + .renderPass = renderpass, + .subpass = 0, + .basePipelineHandle = VK_NULL_HANDLE, + .basePipelineIndex = 0, + }); +} + +void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, + vk::ShaderModule& module, bool single_texture) { if (pipeline) { return; } diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 10d24c4b7..607964b5e 100755 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h @@ -59,6 +59,9 @@ public: void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, u32 up_scale, u32 down_shift); + void ConvertB10G11R11ToD24S8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view, u32 up_scale, u32 down_shift); + void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, u32 up_scale, u32 down_shift); @@ -83,8 +86,11 @@ private: void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); - void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, - vk::ShaderModule& module, bool single_texture); + void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, + vk::ShaderModule& module, bool single_texture); + + void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, + vk::ShaderModule& module, bool single_texture); const Device& device; VKScheduler& scheduler; @@ -102,6 +108,7 @@ private: vk::ShaderModule convert_depth_to_float_frag; vk::ShaderModule convert_float_to_depth_frag; vk::ShaderModule convert_abgr8_to_d24s8_frag; + vk::ShaderModule convert_b10g11r11_to_d24s8_frag; vk::ShaderModule convert_d24s8_to_abgr8_frag; vk::ShaderModule convert_d24s8_to_b10g11r11_frag; vk::ShaderModule convert_d24s8_to_r16g16_frag; @@ -117,6 +124,7 @@ private: vk::Pipeline convert_d16_to_r16_pipeline; vk::Pipeline convert_r16_to_d16_pipeline; vk::Pipeline convert_abgr8_to_d24s8_pipeline; + vk::Pipeline convert_b10g11r11_to_d24s8_pipeline; vk::Pipeline convert_d24s8_to_abgr8_pipeline; vk::Pipeline convert_d24s8_to_b10g11r11_pipeline; vk::Pipeline convert_d24s8_to_r16g16_pipeline; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index b5a1344a4..fb0767d7d 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -917,6 +917,9 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im src_view.format == PixelFormat::B8G8R8A8_UNORM) { return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); } + if (src_view.format == PixelFormat::B10G11R11_FLOAT) { + return blit_image_helper.ConvertB10G11R11ToD24S8(dst, src_view, up_scale, down_shift); + } break; case PixelFormat::D32_FLOAT: if (src_view.format == PixelFormat::R32_FLOAT) { diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 06257f064..4188f93c5 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1096,13 +1096,13 @@ typename TextureCache

::BlitImages TextureCache

::GetBlitImages( if (GetFormatType(dst_info.format) != GetFormatType(src_info.format)) { continue; } - src_id = FindOrInsertImage(src_info, src_addr); - RelaxedOptions dst_options{}; + RelaxedOptions find_options{}; if (src_info.num_samples > 1) { // it's a resolve, we must enforce the same format. - dst_options = RelaxedOptions::ForceBrokenViews; + find_options = RelaxedOptions::ForceBrokenViews; } - dst_id = FindOrInsertImage(dst_info, dst_addr, dst_options); + src_id = FindOrInsertImage(src_info, src_addr, find_options); + dst_id = FindOrInsertImage(dst_info, dst_addr, find_options); } while (has_deleted_images); return BlitImages{ .dst_id = dst_id, diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 8f9eb387c..e4d82631e 100755 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -1151,19 +1151,25 @@ bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, const ImageBase* src) { + bool is_resolve = false; + const auto original_src_format = src_info.format; + const auto original_dst_format = dst_info.format; if (src) { - src_info.format = src->info.format; + if (GetFormatType(src->info.format) != SurfaceType::ColorTexture) { + src_info.format = src->info.format; + } + is_resolve = src->info.num_samples > 1; src_info.num_samples = src->info.num_samples; src_info.size = src->info.size; } - if (dst) { + if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { dst_info.format = dst->info.format; - dst_info.num_samples = dst->info.num_samples; - dst_info.size = dst->info.size; } if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) { if (dst) { - src_info.format = dst_info.format; + if (GetFormatType(dst->info.format) == SurfaceType::ColorTexture) { + src_info.format = original_src_format; + } } else { dst_info.format = src->info.format; } @@ -1171,18 +1177,13 @@ void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { if (src) { if (GetFormatType(src->info.format) == SurfaceType::ColorTexture) { - dst_info.format = src->info.format; + dst_info.format = original_dst_format; } } else { src_info.format = dst->info.format; } } - if (src_info.num_samples > 1) { - dst_info.format = src_info.format; - } - if (dst_info.num_samples > 1) { - src_info.format = dst_info.format; - } + ASSERT(!is_resolve || dst_info.format == src_info.format); } u32 MapSizeBytes(const ImageBase& image) { diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 2464eeee9..3c8e1e90d 100755 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -604,69 +604,88 @@ int GRenderWindow::QtKeyToSwitchKey(Qt::Key qt_key) { } } -int GRenderWindow::QtModifierToSwitchModifier(quint32 qt_modifiers) { +int GRenderWindow::QtModifierToSwitchModifier(Qt::KeyboardModifiers qt_modifiers) { int modifier = 0; - // The values are obtained through testing, Qt doesn't seem to provide a proper enum - if ((qt_modifiers & 0x1) != 0) { + + if ((qt_modifiers & Qt::KeyboardModifier::ShiftModifier) != 0) { modifier |= 1 << Settings::NativeKeyboard::LeftShift; } - if ((qt_modifiers & 0x2) != 0) { + if ((qt_modifiers & Qt::KeyboardModifier::ControlModifier) != 0) { modifier |= 1 << Settings::NativeKeyboard::LeftControl; } - if ((qt_modifiers & 0x4) != 0) { + if ((qt_modifiers & Qt::KeyboardModifier::AltModifier) != 0) { modifier |= 1 << Settings::NativeKeyboard::LeftAlt; } - if ((qt_modifiers & 0x08) != 0) { + if ((qt_modifiers & Qt::KeyboardModifier::MetaModifier) != 0) { modifier |= 1 << Settings::NativeKeyboard::LeftMeta; } - if ((qt_modifiers & 0x10) != 0) { - modifier |= 1 << Settings::NativeKeyboard::RightShift; - } - if ((qt_modifiers & 0x20) != 0) { - modifier |= 1 << Settings::NativeKeyboard::RightControl; - } - if ((qt_modifiers & 0x40) != 0) { - modifier |= 1 << Settings::NativeKeyboard::RightAlt; - } - if ((qt_modifiers & 0x80) != 0) { - modifier |= 1 << Settings::NativeKeyboard::RightMeta; - } - if ((qt_modifiers & 0x100) != 0) { - modifier |= 1 << Settings::NativeKeyboard::CapsLock; - } - if ((qt_modifiers & 0x200) != 0) { - modifier |= 1 << Settings::NativeKeyboard::NumLock; - } - // Verify the last two keys - if ((qt_modifiers & 0x400) != 0) { - modifier |= 1 << Settings::NativeKeyboard::Katakana; - } - if ((qt_modifiers & 0x800) != 0) { - modifier |= 1 << Settings::NativeKeyboard::Hiragana; - } + + // TODO: These keys can't be obtained with Qt::KeyboardModifier + + // if ((qt_modifiers & 0x10) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::RightShift; + // } + // if ((qt_modifiers & 0x20) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::RightControl; + // } + // if ((qt_modifiers & 0x40) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::RightAlt; + // } + // if ((qt_modifiers & 0x80) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::RightMeta; + // } + // if ((qt_modifiers & 0x100) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::CapsLock; + // } + // if ((qt_modifiers & 0x200) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::NumLock; + // } + // if ((qt_modifiers & ???) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::ScrollLock; + // } + // if ((qt_modifiers & ???) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::Katakana; + // } + // if ((qt_modifiers & ???) != 0) { + // modifier |= 1 << Settings::NativeKeyboard::Hiragana; + // } return modifier; } void GRenderWindow::keyPressEvent(QKeyEvent* event) { + /** + * This feature can be enhanced with the following functions, but they do not provide + * cross-platform behavior. + * + * event->nativeVirtualKey() can distinguish between keys on the numpad. + * event->nativeModifiers() can distinguish between left and right keys and numlock, + * capslock, scroll lock. + */ if (!event->isAutoRepeat()) { - const auto modifier = QtModifierToSwitchModifier(event->nativeModifiers()); - // Replace event->key() with event->nativeVirtualKey() since the second one provides raw key - // buttons + const auto modifier = QtModifierToSwitchModifier(event->modifiers()); const auto key = QtKeyToSwitchKey(Qt::Key(event->key())); input_subsystem->GetKeyboard()->SetKeyboardModifiers(modifier); input_subsystem->GetKeyboard()->PressKeyboardKey(key); - // This is used for gamepads + // This is used for gamepads that can have any key mapped input_subsystem->GetKeyboard()->PressKey(event->key()); } } void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { + /** + * This feature can be enhanced with the following functions, but they do not provide + * cross-platform behavior. + * + * event->nativeVirtualKey() can distinguish between keys on the numpad. + * event->nativeModifiers() can distinguish between left and right buttons and numlock, + * capslock, scroll lock. + */ if (!event->isAutoRepeat()) { - const auto modifier = QtModifierToSwitchModifier(event->nativeModifiers()); + const auto modifier = QtModifierToSwitchModifier(event->modifiers()); const auto key = QtKeyToSwitchKey(Qt::Key(event->key())); input_subsystem->GetKeyboard()->SetKeyboardModifiers(modifier); input_subsystem->GetKeyboard()->ReleaseKeyboardKey(key); - // This is used for gamepads + // This is used for gamepads that can have any key mapped input_subsystem->GetKeyboard()->ReleaseKey(event->key()); } } diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 541b54d1f..20c3e2d65 100755 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -158,7 +158,7 @@ public: static int QtKeyToSwitchKey(Qt::Key qt_keys); /// Converts a Qt modifier keys into NativeKeyboard modifier keys - static int QtModifierToSwitchModifier(quint32 qt_modifiers); + static int QtModifierToSwitchModifier(Qt::KeyboardModifiers qt_modifiers); void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override;