mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-20 08:15:46 +00:00
Compare commits
2 commits
603176b6e7
...
b9bcfe23f8
Author | SHA1 | Date | |
---|---|---|---|
|
b9bcfe23f8 | ||
|
1b23e2b8f1 |
17 changed files with 270 additions and 27 deletions
0
.gdbinit
Normal file
0
.gdbinit
Normal file
|
@ -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
|
||||
|
|
|
@ -14,24 +14,25 @@ class BufferHistoryManager {
|
|||
public:
|
||||
void PushEntry(s32 slot, s64 timestamp, s64 frame_number) {
|
||||
std::lock_guard<std::mutex> 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<BufferHistoryEntry> out_entries) {
|
||||
s32 GetHistory(s32 wantedEntries, std::span<BufferHistoryEntry>& entries) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
s32 count =
|
||||
std::min<s32>(static_cast<s32>(entries_.size()), static_cast<s32>(out_entries.size()));
|
||||
for (s32 i = 0; i < count; ++i) {
|
||||
out_entries[i] = entries_[entries_.size() - count + i];
|
||||
s32 countToCopy = std::min<s32>(wantedEntries, static_cast<s32>(history_entries.size()));
|
||||
auto out_entries = std::vector<BufferHistoryEntry>(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<BufferHistoryEntry> entries_;
|
||||
std::deque<BufferHistoryEntry> history_entries;
|
||||
std::mutex mutex_;
|
||||
};
|
|
@ -27,7 +27,7 @@ BufferQueueProducer::BufferQueueProducer(Service::KernelHelpers::ServiceContext&
|
|||
std::shared_ptr<BufferQueueCore> 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<BufferHistoryEntry>& entries) {
|
||||
if (count <= 0) {
|
||||
LOG_ERROR(Service_Nvnflinger, "count must be positive");
|
||||
entries = std::span<BufferHistoryEntry>();
|
||||
return Status::BadValue;
|
||||
|
||||
} else {
|
||||
buffer_history.GetHistory(count, entries);
|
||||
return Status::NoError;
|
||||
}
|
||||
}
|
||||
|
||||
Status BufferQueueProducer::RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* 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<s64>(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<const u8> parcel_data,
|
|||
}
|
||||
case TransactionId::GetBufferHistory: {
|
||||
LOG_DEBUG(Service_Nvnflinger, "GetBufferHistory");
|
||||
auto out_span = parcel_in.Read<std::span<BufferHistoryEntry>>();
|
||||
s32 count = buffer_history_.GetHistory(out_span);
|
||||
parcel_out.Write(s32(count));
|
||||
auto entries_wanted = parcel_in.Read<s32>();
|
||||
if (entries_wanted <= 0) {
|
||||
parcel_out.Write<s32>(0);
|
||||
status = Status::BadValue;
|
||||
}
|
||||
else {
|
||||
std::span<BufferHistoryEntry> entries;
|
||||
buffer_history.GetHistory(entries_wanted, entries);
|
||||
parcel_out.Write(static_cast<s32>(entries.size()));
|
||||
parcel_out.Write(entries);
|
||||
status = Status::NoError;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#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<GraphicBuffer>* buf);
|
||||
Status SetBufferCount(s32 buffer_count);
|
||||
Status GetBufferHistory(s32 count, std::span<BufferHistoryEntry>& 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<BufferQueueCore> core;
|
||||
BufferQueueDefs::SlotsType& slots;
|
||||
BufferHistoryManager buffer_history_;
|
||||
BufferHistoryManager buffer_history;
|
||||
u32 sticky_transform{};
|
||||
std::mutex callback_mutex;
|
||||
s32 next_callback_ticket{};
|
||||
|
|
|
@ -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
|
||||
|
|
19
src/video_core/host_shaders/convert_abgr8_to_r8.frag
Normal file
19
src/video_core/host_shaders/convert_abgr8_to_r8.frag
Normal file
|
@ -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;
|
||||
}
|
19
src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag
Normal file
19
src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag
Normal file
|
@ -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);
|
||||
}
|
17
src/video_core/host_shaders/convert_bgra8_to_s8d24.frag
Normal file
17
src/video_core/host_shaders/convert_bgra8_to_s8d24.frag
Normal file
|
@ -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);
|
||||
}
|
19
src/video_core/host_shaders/convert_r8_to_abgr8.frag
Normal file
19
src/video_core/host_shaders/convert_r8_to_abgr8.frag
Normal file
|
@ -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);
|
||||
}
|
|
@ -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<VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstants)>,
|
||||
PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(PushConstants)>
|
||||
}),
|
||||
one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo(
|
||||
one_texture_set_layout.address(),
|
||||
PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstants)>))),
|
||||
push_constant_range))),
|
||||
two_textures_pipeline_layout(
|
||||
device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo(
|
||||
two_textures_set_layout.address(),
|
||||
PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstants)>))),
|
||||
push_constant_range))),
|
||||
clear_color_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo(
|
||||
nullptr, PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(float) * 4>))),
|
||||
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<f32, 4>& 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<float>(dst_framebuffer->RenderArea().width),
|
||||
static_cast<float>(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();
|
||||
|
|
|
@ -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<f32, 4>& 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<VkPushConstantRange> 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;
|
||||
|
|
|
@ -518,6 +518,14 @@ void RasterizerVulkan::DispatchCompute() {
|
|||
}
|
||||
const std::array<u32, 3> 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]); });
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag
|
|||
}
|
||||
const auto dst_format_type = GetFormatType(dst.info.format);
|
||||
const auto src_format_type = GetFormatType(src.info.format);
|
||||
if (src_format_type == dst_format_type) {
|
||||
if (src_format_type == dst_format_type && HasAlpha(src.info.format) == HasAlpha(dst.info.format)) {
|
||||
if constexpr (HAS_EMULATED_COPIES) {
|
||||
if (!runtime.CanImageBeCopied(dst, src)) {
|
||||
return runtime.EmulateCopyImage(dst, src, copies);
|
||||
|
@ -2406,8 +2407,8 @@ void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag
|
|||
}
|
||||
return runtime.CopyImage(dst, src, copies);
|
||||
}
|
||||
UNIMPLEMENTED_IF(dst.info.type != ImageType::e2D);
|
||||
UNIMPLEMENTED_IF(src.info.type != ImageType::e2D);
|
||||
UNIMPLEMENTED_IF(dst.info.type != ImageType::e2D && dst.info.type != ImageType::Linear);
|
||||
UNIMPLEMENTED_IF(src.info.type != ImageType::e2D && dst.info.type != ImageType::Linear);
|
||||
if (runtime.ShouldReinterpret(dst, src)) {
|
||||
return runtime.ReinterpretImage(dst, src, copies);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue