mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-27 04:25:12 +00:00
driver: Make flip blocking
This commit is contained in:
parent
2e4f32a840
commit
502dc1cbf3
@ -296,7 +296,7 @@ static void ResetSubmissionLock(Platform::InterruptId irq) {
|
|||||||
cv_lock.notify_all();
|
cv_lock.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WaitGpuIdle() {
|
void WaitGpuIdle() {
|
||||||
HLE_TRACE;
|
HLE_TRACE;
|
||||||
std::unique_lock lock{m_submission};
|
std::unique_lock lock{m_submission};
|
||||||
cv_lock.wait(lock, [] { return submission_lock == 0; });
|
cv_lock.wait(lock, [] { return submission_lock == 0; });
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
extern std::unique_ptr<Vulkan::RendererVulkan> renderer;
|
extern std::unique_ptr<Vulkan::RendererVulkan> renderer;
|
||||||
extern std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
extern std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
||||||
|
|
||||||
|
namespace Libraries::GnmDriver {
|
||||||
|
void WaitGpuIdle();
|
||||||
|
}
|
||||||
|
|
||||||
namespace Libraries::VideoOut {
|
namespace Libraries::VideoOut {
|
||||||
|
|
||||||
constexpr static bool Is32BppPixelFormat(PixelFormat format) {
|
constexpr static bool Is32BppPixelFormat(PixelFormat format) {
|
||||||
@ -189,6 +193,11 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
|||||||
bool is_eop /*= false*/) {
|
bool is_eop /*= false*/) {
|
||||||
std::scoped_lock lock{mutex};
|
std::scoped_lock lock{mutex};
|
||||||
|
|
||||||
|
if (!is_eop) {
|
||||||
|
liverpool->SubmitDone();
|
||||||
|
GnmDriver::WaitGpuIdle();
|
||||||
|
}
|
||||||
|
|
||||||
Vulkan::Frame* frame;
|
Vulkan::Frame* frame;
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
frame = renderer->PrepareBlankFrame();
|
frame = renderer->PrepareBlankFrame();
|
||||||
|
@ -362,11 +362,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||||||
}
|
}
|
||||||
case PM4ItOpcode::EventWriteEop: {
|
case PM4ItOpcode::EventWriteEop: {
|
||||||
const auto* event_eop = reinterpret_cast<const PM4CmdEventWriteEop*>(header);
|
const auto* event_eop = reinterpret_cast<const PM4CmdEventWriteEop*>(header);
|
||||||
// Guest can wait for GfxEop event to submit CPU flips.
|
|
||||||
// Flush command list to ensure order.
|
|
||||||
if (rasterizer && event_eop->int_sel == InterruptSelect::IrqWhenWriteConfirm) {
|
|
||||||
rasterizer->Flush();
|
|
||||||
}
|
|
||||||
event_eop->SignalFence();
|
event_eop->SignalFence();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -380,11 +375,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||||||
const u32 data_size = (header->type3.count.Value() - 2) * 4;
|
const u32 data_size = (header->type3.count.Value() - 2) * 4;
|
||||||
u64* address = write_data->Address<u64*>();
|
u64* address = write_data->Address<u64*>();
|
||||||
if (!write_data->wr_one_addr.Value()) {
|
if (!write_data->wr_one_addr.Value()) {
|
||||||
// Guest can poll VO label before submitting CPU flips.
|
|
||||||
// Flush command list before signalling to ensure order.
|
|
||||||
if (rasterizer && vo_port->IsVoLabel(address)) {
|
|
||||||
rasterizer->Flush();
|
|
||||||
}
|
|
||||||
std::memcpy(address, write_data->data, data_size);
|
std::memcpy(address, write_data->data, data_size);
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -65,10 +65,9 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice physical_device, vk::Format for
|
|||||||
|
|
||||||
RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_)
|
RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_)
|
||||||
: window{window_}, liverpool{liverpool_}, instance{window, Config::getGpuId(), Config::vkValidationEnabled()},
|
: window{window_}, liverpool{liverpool_}, instance{window, Config::getGpuId(), Config::vkValidationEnabled()},
|
||||||
schedulers{Scheduler{instance}, Scheduler{instance}, Scheduler{instance}},
|
draw_scheduler{instance}, present_scheduler{instance}, flip_scheduler{instance},
|
||||||
swapchain{instance, window}, texture_cache{instance, schedulers[SchedulerType::Draw]} {
|
swapchain{instance, window}, texture_cache{instance, draw_scheduler} {
|
||||||
rasterizer = std::make_unique<Rasterizer>(instance, schedulers[SchedulerType::Draw],
|
rasterizer = std::make_unique<Rasterizer>(instance, draw_scheduler, texture_cache, liverpool);
|
||||||
texture_cache, liverpool);
|
|
||||||
const u32 num_images = swapchain.GetImageCount();
|
const u32 num_images = swapchain.GetImageCount();
|
||||||
const vk::Device device = instance.GetDevice();
|
const vk::Device device = instance.GetDevice();
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool*
|
|||||||
}
|
}
|
||||||
|
|
||||||
RendererVulkan::~RendererVulkan() {
|
RendererVulkan::~RendererVulkan() {
|
||||||
schedulers[SchedulerType::Draw].Finish();
|
draw_scheduler.Finish();
|
||||||
const vk::Device device = instance.GetDevice();
|
const vk::Device device = instance.GetDevice();
|
||||||
for (auto& frame : present_frames) {
|
for (auto& frame : present_frames) {
|
||||||
vmaDestroyImage(instance.GetAllocator(), frame.image, frame.allocation);
|
vmaDestroyImage(instance.GetAllocator(), frame.image, frame.allocation);
|
||||||
@ -170,7 +169,7 @@ bool RendererVulkan::ShowSplash(Frame* frame /*= nullptr*/) {
|
|||||||
info.pitch = splash->GetImageInfo().width;
|
info.pitch = splash->GetImageInfo().width;
|
||||||
info.guest_address = VAddr(splash->GetImageData().data());
|
info.guest_address = VAddr(splash->GetImageData().data());
|
||||||
info.guest_size_bytes = splash->GetImageData().size();
|
info.guest_size_bytes = splash->GetImageData().size();
|
||||||
splash_img.emplace(instance, schedulers[SchedulerType::Present], info);
|
splash_img.emplace(instance, present_scheduler, info);
|
||||||
texture_cache.RefreshImage(*splash_img);
|
texture_cache.RefreshImage(*splash_img);
|
||||||
}
|
}
|
||||||
frame = PrepareFrameInternal(*splash_img);
|
frame = PrepareFrameInternal(*splash_img);
|
||||||
@ -186,7 +185,7 @@ Frame* RendererVulkan::PrepareFrameInternal(VideoCore::Image& image, bool is_eop
|
|||||||
// EOP flips are triggered from GPU thread to use the drawing scheduler to record
|
// EOP flips are triggered from GPU thread to use the drawing scheduler to record
|
||||||
// commands. Otherwise we are dealing with a CPU flip which could have arrived
|
// commands. Otherwise we are dealing with a CPU flip which could have arrived
|
||||||
// from any guest thread. Use a separate scheduler for that.
|
// from any guest thread. Use a separate scheduler for that.
|
||||||
auto& scheduler = schedulers[is_eop ? SchedulerType::Draw : SchedulerType::CpuFlip];
|
auto& scheduler = is_eop ? draw_scheduler : flip_scheduler;
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
||||||
image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits::eTransferRead,
|
image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits::eTransferRead,
|
||||||
@ -253,7 +252,7 @@ void RendererVulkan::Present(Frame* frame) {
|
|||||||
|
|
||||||
const vk::Image swapchain_image = swapchain.Image();
|
const vk::Image swapchain_image = swapchain.Image();
|
||||||
|
|
||||||
auto& scheduler = schedulers[SchedulerType::Present];
|
auto& scheduler = present_scheduler;
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
{
|
{
|
||||||
auto* profiler_ctx = instance.GetProfilerContext();
|
auto* profiler_ctx = instance.GetProfilerContext();
|
||||||
|
@ -83,7 +83,9 @@ private:
|
|||||||
Frontend::WindowSDL& window;
|
Frontend::WindowSDL& window;
|
||||||
AmdGpu::Liverpool* liverpool;
|
AmdGpu::Liverpool* liverpool;
|
||||||
Instance instance;
|
Instance instance;
|
||||||
std::array<Scheduler, 3> schedulers;
|
Scheduler draw_scheduler;
|
||||||
|
Scheduler present_scheduler;
|
||||||
|
Scheduler flip_scheduler;
|
||||||
Swapchain swapchain;
|
Swapchain swapchain;
|
||||||
std::unique_ptr<Rasterizer> rasterizer;
|
std::unique_ptr<Rasterizer> rasterizer;
|
||||||
VideoCore::TextureCache texture_cache;
|
VideoCore::TextureCache texture_cache;
|
||||||
|
Loading…
Reference in New Issue
Block a user