diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d830cc381d..2f7f3b5b24 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -863,6 +863,7 @@ add_library(core STATIC hle/service/nvdrv/nvmemp.cpp hle/service/nvdrv/nvmemp.h hle/service/nvnflinger/binder.h + hle/service/nvnflinger/buffer_history.h hle/service/nvnflinger/buffer_item.h hle/service/nvnflinger/buffer_item_consumer.cpp hle/service/nvnflinger/buffer_item_consumer.h diff --git a/src/core/hle/service/nvnflinger/buffer_history.h b/src/core/hle/service/nvnflinger/buffer_history.h index 614e7fc2fe..0a1d4e89bc 100644 --- a/src/core/hle/service/nvnflinger/buffer_history.h +++ b/src/core/hle/service/nvnflinger/buffer_history.h @@ -14,24 +14,25 @@ class BufferHistoryManager { public: void PushEntry(s32 slot, s64 timestamp, s64 frame_number) { std::lock_guard lock(mutex_); - if (entries_.size() >= kMaxHistorySize) { - entries_.pop_front(); + if (history_entries.size() >= kMaxHistorySize) { + history_entries.pop_front(); } - entries_.emplace_back(BufferHistoryEntry{slot, timestamp, frame_number}); + history_entries.emplace_back(BufferHistoryEntry{slot, timestamp, frame_number}); } - s32 GetHistory(std::span out_entries) { + s32 GetHistory(s32 wantedEntries, std::span& entries) { std::lock_guard lock(mutex_); - s32 count = - std::min(static_cast(entries_.size()), static_cast(out_entries.size())); - for (s32 i = 0; i < count; ++i) { - out_entries[i] = entries_[entries_.size() - count + i]; + s32 countToCopy = std::min(wantedEntries, static_cast(history_entries.size())); + auto out_entries = std::vector(countToCopy); + for (s32 i = 0; i < countToCopy; ++i) { + out_entries[i] = history_entries[history_entries.size() - countToCopy + i]; } - return count; + entries = std::span(out_entries); + return countToCopy; } private: static constexpr size_t kMaxHistorySize = 16; - std::deque entries_; + std::deque history_entries; std::mutex mutex_; }; \ No newline at end of file diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index e5f75e648c..e7d3e88bfc 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -27,7 +27,7 @@ BufferQueueProducer::BufferQueueProducer(Service::KernelHelpers::ServiceContext& std::shared_ptr buffer_queue_core_, Service::Nvidia::NvCore::NvMap& nvmap_) : service_context{service_context_}, core{std::move(buffer_queue_core_)}, slots(core->slots), - nvmap(nvmap_) { + buffer_history(), nvmap(nvmap_) { buffer_wait_event = service_context.CreateEvent("BufferQueue:WaitEvent"); } @@ -35,6 +35,18 @@ BufferQueueProducer::~BufferQueueProducer() { service_context.CloseEvent(buffer_wait_event); } +Status BufferQueueProducer::GetBufferHistory(s32 count, std::span& entries) { + if (count <= 0) { + LOG_ERROR(Service_Nvnflinger, "count must be positive"); + entries = std::span(); + return Status::BadValue; + + } else { + buffer_history.GetHistory(count, entries); + return Status::NoError; + } +} + Status BufferQueueProducer::RequestBuffer(s32 slot, std::shared_ptr* buf) { LOG_DEBUG(Service_Nvnflinger, "slot {}", slot); @@ -516,6 +528,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, slots[slot].buffer_state = BufferState::Queued; ++core->frame_counter; slots[slot].frame_number = core->frame_counter; + buffer_history.PushEntry(slot, timestamp, static_cast(core->frame_counter)); item.acquire_called = slots[slot].acquire_called; item.graphic_buffer = slots[slot].graphic_buffer; @@ -928,9 +941,18 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, } case TransactionId::GetBufferHistory: { LOG_DEBUG(Service_Nvnflinger, "GetBufferHistory"); - auto out_span = parcel_in.Read>(); - s32 count = buffer_history_.GetHistory(out_span); - parcel_out.Write(s32(count)); + auto entries_wanted = parcel_in.Read(); + if (entries_wanted <= 0) { + parcel_out.Write(0); + status = Status::BadValue; + } + else { + std::span entries; + buffer_history.GetHistory(entries_wanted, entries); + parcel_out.Write(static_cast(entries.size())); + parcel_out.Write(entries); + status = Status::NoError; + } break; } default: diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 28c26ca1ed..3443c0e7f5 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h @@ -13,6 +13,7 @@ #include #include +#include "buffer_history.h" #include "common/common_funcs.h" #include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvnflinger/binder.h" @@ -59,6 +60,7 @@ public: public: Status RequestBuffer(s32 slot, std::shared_ptr* buf); Status SetBufferCount(s32 buffer_count); + Status GetBufferHistory(s32 count, std::span& entries); Status DequeueBuffer(s32* out_slot, android::Fence* out_fence, bool async, u32 width, u32 height, PixelFormat format, u32 usage); Status DetachBuffer(s32 slot); @@ -84,7 +86,7 @@ private: std::shared_ptr core; BufferQueueDefs::SlotsType& slots; - BufferHistoryManager buffer_history_; + BufferHistoryManager buffer_history; u32 sticky_transform{}; std::mutex callback_mutex; s32 next_callback_ticket{}; diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 688e10d2e4..1849c35b21 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -21,8 +21,12 @@ set(SHADER_FILES convert_abgr8_srgb_to_d24s8.frag convert_abgr8_to_d24s8.frag convert_abgr8_to_d32f.frag + convert_r8_to_abgr8.frag + convert_abgr8_to_r8.frag convert_d32f_to_abgr8.frag convert_d24s8_to_abgr8.frag + convert_bgra8_to_s8d24.frag + convert_b10gr11f_to_abgr8.frag convert_depth_to_float.frag convert_float_to_depth.frag convert_msaa_to_non_msaa.comp diff --git a/src/video_core/host_shaders/convert_abgr8_to_r8.frag b/src/video_core/host_shaders/convert_abgr8_to_r8.frag new file mode 100644 index 0000000000..f76a42db9c --- /dev/null +++ b/src/video_core/host_shaders/convert_abgr8_to_r8.frag @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout(binding = 0) uniform sampler2D tex; + +layout(location = 0) out float color; + +layout(push_constant) uniform PushConstants { + uniform vec2 tex_scale; + uniform vec2 tex_offset; +}; + +void main() { + vec2 coord = gl_FragCoord.xy / tex_scale * textureSize(tex, 0); + vec4 fetch = texelFetch(tex, ivec2(coord), 0); + color = fetch.r; +} diff --git a/src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag b/src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag new file mode 100644 index 0000000000..f3ac16da20 --- /dev/null +++ b/src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout(binding = 0) uniform sampler2D tex; + +layout(push_constant) uniform PushConstants { + uniform vec2 tex_scale; + uniform vec2 tex_offset; +}; + +layout(location = 0) out vec4 color; + +void main() { + vec2 coord = gl_FragCoord.xy / tex_scale * textureSize(tex, 0); + vec4 fetch = texelFetch(tex, ivec2(coord), 0); + color = vec4(fetch.rgb, 1.0); +} \ No newline at end of file diff --git a/src/video_core/host_shaders/convert_bgra8_to_s8d24.frag b/src/video_core/host_shaders/convert_bgra8_to_s8d24.frag new file mode 100644 index 0000000000..8aae0481a4 --- /dev/null +++ b/src/video_core/host_shaders/convert_bgra8_to_s8d24.frag @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 +#extension GL_ARB_shader_stencil_export : require + +layout(binding = 0) uniform sampler2D color_texture; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + uvec4 color = uvec4(texelFetch(color_texture, coord, 0).bgra * (exp2(8) - 1.0f)); + uvec4 bytes = color << uvec4(24, 16, 8, 0); + uint depth_stencil_unorm = bytes.x | bytes.y | bytes.z | bytes.w; + + gl_FragDepth = float(depth_stencil_unorm >> 24) / (exp2(24.0) - 1.0f); + gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FFFFFFu); +} diff --git a/src/video_core/host_shaders/convert_r8_to_abgr8.frag b/src/video_core/host_shaders/convert_r8_to_abgr8.frag new file mode 100644 index 0000000000..8119c1f40c --- /dev/null +++ b/src/video_core/host_shaders/convert_r8_to_abgr8.frag @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout(binding = 0) uniform sampler2D tex; + +layout(push_constant) uniform PushConstants { + uniform vec2 tex_scale; + uniform vec2 tex_offset; +}; + +layout(location = 0) out vec4 color; + +void main() { + vec2 coord = gl_FragCoord.xy / tex_scale * textureSize(tex, 0); + float red = texelFetch(tex, ivec2(coord), 0).r; + color = vec4(1.0, red, red, red); +} diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index f2bf5a3228..a36198eb5b 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -11,8 +11,11 @@ #include "video_core/host_shaders/convert_abgr8_to_d32f_frag_spv.h" #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_d32f_to_abgr8_frag_spv.h" +#include "video_core/host_shaders/convert_r8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" +#include "video_core/host_shaders/convert_b10gr11f_to_abgr8_frag_spv.h" +#include "video_core/host_shaders/convert_bgra8_to_s8d24_frag_spv.h" #include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h" #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" @@ -29,6 +32,7 @@ #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/host_shaders/convert_abgr8_srgb_to_d24s8_frag_spv.h" +#include "video_core/host_shaders/convert_abgr8_to_r8_frag_spv.h" #include "video_core/host_shaders/convert_rgba8_to_bgra8_frag_spv.h" #include "video_core/host_shaders/convert_yuv420_to_rgb_comp_spv.h" #include "video_core/host_shaders/convert_rgb_to_yuv420_comp_spv.h" @@ -385,6 +389,17 @@ VkExtent2D GetConversionExtent(const ImageView& src_image_view) { }; } +VkExtent2D GetConversionExtent(const Framebuffer* framebuffer) { + const auto& resolution = Settings::values.resolution_info; + const bool is_rescaled = framebuffer->IsRescaled(); + u32 width = framebuffer->RenderArea().width; + u32 height = framebuffer->RenderArea().height; + return VkExtent2D{ + .width = is_rescaled ? resolution.ScaleUp(width) : width, + .height = is_rescaled ? resolution.ScaleUp(height) : height, + }; +} + void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout, VkImageLayout source_layout = VK_IMAGE_LAYOUT_GENERAL) { constexpr VkFlags flags{VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | @@ -442,13 +457,17 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, descriptor_pool.Allocator(*one_texture_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<1>)}, two_textures_descriptor_allocator{ descriptor_pool.Allocator(*two_textures_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<2>)}, + push_constant_range({ + PUSH_CONSTANT_RANGE, + PUSH_CONSTANT_RANGE + }), one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo( one_texture_set_layout.address(), - PUSH_CONSTANT_RANGE))), + push_constant_range))), two_textures_pipeline_layout( device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo( two_textures_set_layout.address(), - PUSH_CONSTANT_RANGE))), + push_constant_range))), clear_color_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo( nullptr, PUSH_CONSTANT_RANGE))), full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)), @@ -461,10 +480,14 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, 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_abgr8_to_d32f_frag(BuildShader(device, CONVERT_ABGR8_TO_D32F_FRAG_SPV)), + convert_abgr8_to_r8_frag(BuildShader(device, CONVERT_ABGR8_TO_R8_FRAG_SPV)), + convert_r8_to_abgr8_frag(BuildShader(device, CONVERT_R8_TO_ABGR8_FRAG_SPV)), convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)), convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)), convert_abgr8_srgb_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_SRGB_TO_D24S8_FRAG_SPV)), + convert_b10gr11f_to_abgr8_frag(BuildShader(device, CONVERT_B10GR11F_TO_ABGR8_FRAG_SPV)), + convert_bgra8_to_s8d24_frag(BuildShader(device, CONVERT_BGRA8_TO_S8D24_FRAG_SPV)), convert_rgba_to_bgra_frag(BuildShader(device, CONVERT_RGBA8_TO_BGRA8_FRAG_SPV)), convert_yuv420_to_rgb_comp(BuildShader(device, CONVERT_YUV420_TO_RGB_COMP_SPV)), convert_rgb_to_yuv420_comp(BuildShader(device, CONVERT_RGB_TO_YUV420_COMP_SPV)), @@ -588,6 +611,20 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view); } +void BlitImageHelper::ConvertR8ToABGR8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineColorTargetEx(convert_r8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), + convert_r8_to_abgr8_frag); + Convert(*convert_r8_to_abgr8_pipeline, dst_framebuffer, src_image_view); +} + +void BlitImageHelper::ConvertABGR8ToR8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineColorTargetEx(convert_abgr8_to_r8_pipeline, dst_framebuffer->RenderPass(), + convert_abgr8_to_r8_frag); + Convert(*convert_abgr8_to_r8_pipeline, dst_framebuffer, src_image_view); +} + void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view) { ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), @@ -631,6 +668,21 @@ void BlitImageHelper::ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer Convert(*convert_abgr8_srgb_to_d24s8_pipeline, dst_framebuffer, src_image_view); } +void BlitImageHelper::ConvertB10GR11ToABGR8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineDepthTargetEx(convert_b10gr11f_to_abgr8_pipeline, + dst_framebuffer->RenderPass(), + convert_b10gr11f_to_abgr8_frag); + Convert(*convert_b10gr11f_to_abgr8_pipeline, dst_framebuffer, src_image_view); +} + +void BlitImageHelper::ConvertBGRA8ToS8D24(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineDepthTargetEx(convert_bgra8_to_s8d24_pipeline, dst_framebuffer->RenderPass(), + convert_bgra8_to_s8d24_frag); + Convert(*convert_bgra8_to_s8d24_pipeline, dst_framebuffer, src_image_view); +} + void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, const std::array& clear_color, const Region2D& dst_region) { @@ -684,10 +736,10 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); const VkSampler sampler = *nearest_sampler; - const VkExtent2D extent = GetConversionExtent(src_image_view); + const VkExtent2D extent = GetConversionExtent(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer); - scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { + scheduler.Record([pipeline, layout, sampler, src_view, extent, this, dst_framebuffer](vk::CommandBuffer cmdbuf) { const VkOffset2D offset{ .x = 0, .y = 0, @@ -704,9 +756,16 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb .offset = offset, .extent = extent, }; - const PushConstants push_constants{ + /*const PushConstants push_constants_vertex{ .tex_scale = {viewport.width, viewport.height}, .tex_offset = {0.0f, 0.0f}, + };*/ + const PushConstants push_constants_frag{ + .tex_scale = { + static_cast(dst_framebuffer->RenderArea().width), + static_cast(dst_framebuffer->RenderArea().height) + }, + .tex_offset = {0.0f, 0.0f}, }; const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); @@ -717,7 +776,8 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb nullptr); cmdbuf.SetViewport(0, viewport); cmdbuf.SetScissor(0, scissor); - cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); + cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants_frag); + cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants_frag); cmdbuf.Draw(3, 1, 0, 0); }); scheduler.InvalidateState(); diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 3d400be6a9..bf3bed9ed4 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h @@ -65,6 +65,10 @@ public: void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ConvertR8ToABGR8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + + void ConvertABGR8ToR8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); @@ -77,6 +81,10 @@ public: void ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); + void ConvertB10GR11ToABGR8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + + void ConvertBGRA8ToS8D24(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, const std::array& clear_color, const Region2D& dst_region); @@ -131,6 +139,7 @@ private: vk::DescriptorSetLayout two_textures_set_layout; DescriptorAllocator one_texture_descriptor_allocator; DescriptorAllocator two_textures_descriptor_allocator; + std::vector push_constant_range; vk::PipelineLayout one_texture_pipeline_layout; vk::PipelineLayout two_textures_pipeline_layout; vk::PipelineLayout clear_color_pipeline_layout; @@ -144,10 +153,15 @@ private: vk::ShaderModule convert_float_to_depth_frag; vk::ShaderModule convert_abgr8_to_d24s8_frag; vk::ShaderModule convert_abgr8_to_d32f_frag; + vk::ShaderModule convert_abgr8_to_r8_frag; + vk::ShaderModule convert_r8_to_abgr8_frag; vk::ShaderModule convert_d32f_to_abgr8_frag; vk::ShaderModule convert_d24s8_to_abgr8_frag; vk::ShaderModule convert_s8d24_to_abgr8_frag; + vk::ShaderModule convert_s8d24_to_bgra8_frag; vk::ShaderModule convert_abgr8_srgb_to_d24s8_frag; + vk::ShaderModule convert_b10gr11f_to_abgr8_frag; + vk::ShaderModule convert_bgra8_to_s8d24_frag; vk::ShaderModule convert_rgba_to_bgra_frag; vk::ShaderModule convert_yuv420_to_rgb_comp; vk::ShaderModule convert_rgb_to_yuv420_comp; @@ -176,7 +190,11 @@ private: vk::Pipeline convert_d32f_to_abgr8_pipeline; vk::Pipeline convert_d24s8_to_abgr8_pipeline; vk::Pipeline convert_s8d24_to_abgr8_pipeline; + vk::Pipeline convert_r8_to_abgr8_pipeline; + vk::Pipeline convert_abgr8_to_r8_pipeline; vk::Pipeline convert_abgr8_srgb_to_d24s8_pipeline; + vk::Pipeline convert_bgra8_to_s8d24_pipeline; + vk::Pipeline convert_b10gr11f_to_abgr8_pipeline; vk::Pipeline convert_rgba_to_bgra_pipeline; vk::Pipeline convert_yuv420_to_rgb_pipeline; vk::Pipeline convert_rgb_to_yuv420_pipeline; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 0243693049..51e45d0809 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -518,6 +518,14 @@ void RasterizerVulkan::DispatchCompute() { } const std::array dim{qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z}; scheduler.RequestOutsideRenderPassOperationContext(); + static constexpr VkMemoryBarrier READ_BARRIER{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + }; + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, READ_BARRIER); }); scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); }); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 022a9ae572..e3bf2ddd46 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1219,8 +1219,27 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view); } break; - + case PixelFormat::R8_UNORM: + if (src_view.format == PixelFormat::A8B8G8R8_UNORM) { + return blit_image_helper.ConvertABGR8ToR8(dst, src_view); + } + break; case PixelFormat::A8B8G8R8_UNORM: + if (src_view.format == PixelFormat::R8_UNORM) { + return blit_image_helper.ConvertR8ToABGR8(dst, src_view); + } + if (src_view.format == PixelFormat::B10G11R11_FLOAT) { + return blit_image_helper.ConvertB10GR11ToABGR8(dst, src_view); + } + if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { + return blit_image_helper.ConvertS8D24ToABGR8(dst, src_view); + } + break; + case PixelFormat::S8_UINT_D24_UNORM: + if (src_view.format == PixelFormat::B8G8R8A8_UNORM) { + return blit_image_helper.ConvertBGRA8ToS8D24(dst, src_view); + } + break; case PixelFormat::A8B8G8R8_SNORM: case PixelFormat::A8B8G8R8_SINT: case PixelFormat::A8B8G8R8_UINT: @@ -1232,7 +1251,6 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im case PixelFormat::A2R10G10B10_UNORM: case PixelFormat::A1B5G5R5_UNORM: case PixelFormat::A5B5G5R1_UNORM: - case PixelFormat::R8_UNORM: case PixelFormat::R8_SNORM: case PixelFormat::R8_SINT: case PixelFormat::R8_UINT: @@ -1319,12 +1337,12 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im case PixelFormat::D16_UNORM: case PixelFormat::X8_D24_UNORM: case PixelFormat::S8_UINT: - case PixelFormat::S8_UINT_D24_UNORM: case PixelFormat::D32_FLOAT_S8_UINT: case PixelFormat::Invalid: default: break; } + LOG_WARNING(Render_Vulkan, "Unimplemented texture conversion from {} to {} format type", src_view.format, dst_view.format); } VkFormat TextureCacheRuntime::GetSupportedFormat(VkFormat requested_format, diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 9055b1b929..c791bfa4e4 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -237,6 +237,38 @@ SurfaceType GetFormatType(PixelFormat pixel_format) { return SurfaceType::Invalid; } +bool HasAlpha(PixelFormat pixel_format) { + switch (pixel_format) { + case PixelFormat::A8B8G8R8_UNORM: + case PixelFormat::A8B8G8R8_SNORM: + case PixelFormat::A8B8G8R8_SINT: + case PixelFormat::A8B8G8R8_UINT: + case PixelFormat::A1R5G5B5_UNORM: + case PixelFormat::A2B10G10R10_UNORM: + case PixelFormat::A2B10G10R10_UINT: + case PixelFormat::A2R10G10B10_UNORM: + case PixelFormat::A1B5G5R5_UNORM: + case PixelFormat::A5B5G5R1_UNORM: + case PixelFormat::R16G16B16A16_FLOAT: + case PixelFormat::R16G16B16A16_UNORM: + case PixelFormat::R16G16B16A16_SNORM: + case PixelFormat::R16G16B16A16_SINT: + case PixelFormat::R16G16B16A16_UINT: + case PixelFormat::R32G32B32A32_UINT: + case PixelFormat::BC1_RGBA_UNORM: + case PixelFormat::B8G8R8A8_UNORM: + case PixelFormat::R32G32B32A32_FLOAT: + case PixelFormat::R32G32B32A32_SINT: + case PixelFormat::A8B8G8R8_SRGB: + case PixelFormat::B8G8R8A8_SRGB: + case PixelFormat::BC1_RGBA_SRGB: + case PixelFormat::A4B4G4R4_UNORM: + return true; + default: + return false; + } +} + bool IsPixelFormatASTC(PixelFormat format) { switch (format) { case PixelFormat::ASTC_2D_4X4_UNORM: diff --git a/src/video_core/surface.h b/src/video_core/surface.h index ec9cd2fbf0..4ccb24f27d 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -503,6 +503,8 @@ PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format); SurfaceType GetFormatType(PixelFormat pixel_format); +bool HasAlpha(PixelFormat pixel_format); + bool IsPixelFormatASTC(PixelFormat format); bool IsPixelFormatBCn(PixelFormat format); diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6c733fe902..f1693948ae 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -26,6 +26,7 @@ namespace VideoCommon { using Tegra::Texture::TICEntry; using Tegra::Texture::TSCEntry; using VideoCore::Surface::GetFormatType; +using VideoCore::Surface::HasAlpha; using VideoCore::Surface::PixelFormat; using VideoCore::Surface::SurfaceType; using namespace Common::Literals; @@ -2398,7 +2399,7 @@ void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::vector::CopyImage(ImageId dst_id, ImageId src_id, std::vector