mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-18 11:42:36 +00:00
commit
1c2977442f
114
Source/Core/VideoCommon/AsyncRequests.cpp
Normal file
114
Source/Core/VideoCommon/AsyncRequests.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#include "VideoCommon/AsyncRequests.h"
|
||||||
|
#include "VideoCommon/RenderBase.h"
|
||||||
|
|
||||||
|
AsyncRequests AsyncRequests::s_singleton;
|
||||||
|
|
||||||
|
AsyncRequests::AsyncRequests()
|
||||||
|
: m_enable(false), m_passthrough(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncRequests::PullEventsInternal()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
m_empty.store(true);
|
||||||
|
|
||||||
|
while (!m_queue.empty())
|
||||||
|
{
|
||||||
|
const Event& e = m_queue.front();
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
HandleEvent(e);
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
m_queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_wake_me_up_again)
|
||||||
|
{
|
||||||
|
m_wake_me_up_again = false;
|
||||||
|
m_cond.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncRequests::PushEvent(const AsyncRequests::Event& event, bool blocking)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_passthrough)
|
||||||
|
{
|
||||||
|
HandleEvent(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_empty.store(false);
|
||||||
|
m_wake_me_up_again |= blocking;
|
||||||
|
|
||||||
|
if (!m_enable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_queue.push(event);
|
||||||
|
|
||||||
|
if (blocking)
|
||||||
|
{
|
||||||
|
m_cond.wait(lock, [this]{return m_queue.empty();});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncRequests::SetEnable(bool enable)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
m_enable = enable;
|
||||||
|
|
||||||
|
if (!enable)
|
||||||
|
{
|
||||||
|
// flush the queue on disabling
|
||||||
|
while (!m_queue.empty())
|
||||||
|
m_queue.pop();
|
||||||
|
if (m_wake_me_up_again)
|
||||||
|
m_cond.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncRequests::HandleEvent(const AsyncRequests::Event& e)
|
||||||
|
{
|
||||||
|
EFBRectangle rc;
|
||||||
|
switch (e.type)
|
||||||
|
{
|
||||||
|
case Event::EFB_POKE_COLOR:
|
||||||
|
g_renderer->AccessEFB(POKE_COLOR, e.efb_poke.x, e.efb_poke.y, e.efb_poke.data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::EFB_POKE_Z:
|
||||||
|
g_renderer->AccessEFB(POKE_Z, e.efb_poke.x, e.efb_poke.y, e.efb_poke.data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::EFB_PEEK_COLOR:
|
||||||
|
*e.efb_peek.data = g_renderer->AccessEFB(PEEK_COLOR, e.efb_peek.x, e.efb_peek.y, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::EFB_PEEK_Z:
|
||||||
|
*e.efb_peek.data = g_renderer->AccessEFB(PEEK_Z, e.efb_peek.x, e.efb_peek.y, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::SWAP_EVENT:
|
||||||
|
Renderer::Swap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride, e.swap_event.fbHeight, rc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::BBOX_READ:
|
||||||
|
*e.bbox.data = g_renderer->BBoxRead(e.bbox.index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::PERF_QUERY:
|
||||||
|
g_perf_query->FlushResults();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncRequests::SetPassthrough(bool enable)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
m_passthrough = enable;
|
||||||
|
}
|
||||||
|
|
94
Source/Core/VideoCommon/AsyncRequests.h
Normal file
94
Source/Core/VideoCommon/AsyncRequests.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
class AsyncRequests
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Event
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
EFB_POKE_COLOR,
|
||||||
|
EFB_POKE_Z,
|
||||||
|
EFB_PEEK_COLOR,
|
||||||
|
EFB_PEEK_Z,
|
||||||
|
SWAP_EVENT,
|
||||||
|
BBOX_READ,
|
||||||
|
PERF_QUERY,
|
||||||
|
} type;
|
||||||
|
u64 time;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u16 x;
|
||||||
|
u16 y;
|
||||||
|
u32 data;
|
||||||
|
} efb_poke;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u16 x;
|
||||||
|
u16 y;
|
||||||
|
u32* data;
|
||||||
|
} efb_peek;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 xfbAddr;
|
||||||
|
u32 fbWidth;
|
||||||
|
u32 fbStride;
|
||||||
|
u32 fbHeight;
|
||||||
|
} swap_event;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
u16* data;
|
||||||
|
} bbox;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
} perf_query;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
AsyncRequests();
|
||||||
|
|
||||||
|
void PullEvents()
|
||||||
|
{
|
||||||
|
if (!m_empty.load())
|
||||||
|
PullEventsInternal();
|
||||||
|
}
|
||||||
|
void PushEvent(const Event& event, bool blocking = false);
|
||||||
|
void SetEnable(bool enable);
|
||||||
|
void SetPassthrough(bool enable);
|
||||||
|
|
||||||
|
static AsyncRequests* GetInstance() { return &s_singleton; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PullEventsInternal();
|
||||||
|
void HandleEvent(const Event& e);
|
||||||
|
|
||||||
|
static AsyncRequests s_singleton;
|
||||||
|
|
||||||
|
std::atomic<bool> m_empty;
|
||||||
|
std::queue<Event> m_queue;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
std::condition_variable m_cond;
|
||||||
|
|
||||||
|
bool m_wake_me_up_again;
|
||||||
|
bool m_enable;
|
||||||
|
bool m_passthrough;
|
||||||
|
};
|
@ -1,4 +1,5 @@
|
|||||||
set(SRCS BoundingBox.cpp
|
set(SRCS AsyncRequests.cpp
|
||||||
|
BoundingBox.cpp
|
||||||
BPFunctions.cpp
|
BPFunctions.cpp
|
||||||
BPMemory.cpp
|
BPMemory.cpp
|
||||||
BPStructs.cpp
|
BPStructs.cpp
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "Core/NetPlayProto.h"
|
#include "Core/NetPlayProto.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/AsyncRequests.h"
|
||||||
#include "VideoCommon/CommandProcessor.h"
|
#include "VideoCommon/CommandProcessor.h"
|
||||||
#include "VideoCommon/CPMemory.h"
|
#include "VideoCommon/CPMemory.h"
|
||||||
#include "VideoCommon/DataReader.h"
|
#include "VideoCommon/DataReader.h"
|
||||||
@ -282,11 +283,14 @@ void RunGpuLoop()
|
|||||||
// This allows a system that we are maxing out in dual core mode to do other things
|
// This allows a system that we are maxing out in dual core mode to do other things
|
||||||
bool yield_cpu = cpu_info.num_cores <= 2;
|
bool yield_cpu = cpu_info.num_cores <= 2;
|
||||||
|
|
||||||
|
AsyncRequests::GetInstance()->SetEnable(true);
|
||||||
|
AsyncRequests::GetInstance()->SetPassthrough(false);
|
||||||
|
|
||||||
while (GpuRunningState)
|
while (GpuRunningState)
|
||||||
{
|
{
|
||||||
g_video_backend->PeekMessages();
|
g_video_backend->PeekMessages();
|
||||||
|
|
||||||
VideoFifo_CheckAsyncRequest();
|
AsyncRequests::GetInstance()->PullEvents();
|
||||||
if (g_use_deterministic_gpu_thread)
|
if (g_use_deterministic_gpu_thread)
|
||||||
{
|
{
|
||||||
// All the fifo/CP stuff is on the CPU. We just need to run the opcode decoder.
|
// All the fifo/CP stuff is on the CPU. We just need to run the opcode decoder.
|
||||||
@ -348,7 +352,7 @@ void RunGpuLoop()
|
|||||||
// This call is pretty important in DualCore mode and must be called in the FIFO Loop.
|
// This call is pretty important in DualCore mode and must be called in the FIFO Loop.
|
||||||
// If we don't, s_swapRequested or s_efbAccessRequested won't be set to false
|
// If we don't, s_swapRequested or s_efbAccessRequested won't be set to false
|
||||||
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
|
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
|
||||||
VideoFifo_CheckAsyncRequest();
|
AsyncRequests::GetInstance()->PullEvents();
|
||||||
CommandProcessor::isPossibleWaitingSetDrawDone = false;
|
CommandProcessor::isPossibleWaitingSetDrawDone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +381,8 @@ void RunGpuLoop()
|
|||||||
}
|
}
|
||||||
// wake up SyncGPU if we were interrupted
|
// wake up SyncGPU if we were interrupted
|
||||||
s_video_buffer_cond.notify_all();
|
s_video_buffer_cond.notify_all();
|
||||||
|
AsyncRequests::GetInstance()->SetEnable(false);
|
||||||
|
AsyncRequests::GetInstance()->SetPassthrough(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,3 @@ void EmulatorState(bool running);
|
|||||||
bool AtBreakpoint();
|
bool AtBreakpoint();
|
||||||
void ResetVideoBuffer();
|
void ResetVideoBuffer();
|
||||||
void Fifo_SetRendering(bool bEnabled);
|
void Fifo_SetRendering(bool bEnabled);
|
||||||
|
|
||||||
|
|
||||||
// Implemented by the Video Backend
|
|
||||||
void VideoFifo_CheckAsyncRequest();
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "Common/Event.h"
|
#include "Common/Event.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/AsyncRequests.h"
|
||||||
#include "VideoCommon/BoundingBox.h"
|
#include "VideoCommon/BoundingBox.h"
|
||||||
#include "VideoCommon/BPStructs.h"
|
#include "VideoCommon/BPStructs.h"
|
||||||
#include "VideoCommon/CommandProcessor.h"
|
#include "VideoCommon/CommandProcessor.h"
|
||||||
@ -18,18 +19,7 @@
|
|||||||
|
|
||||||
bool s_BackendInitialized = false;
|
bool s_BackendInitialized = false;
|
||||||
|
|
||||||
Common::Flag s_swapRequested;
|
|
||||||
static Common::Flag s_FifoShuttingDown;
|
static Common::Flag s_FifoShuttingDown;
|
||||||
static Common::Flag s_efbAccessRequested;
|
|
||||||
static Common::Event s_efbAccessReadyEvent;
|
|
||||||
|
|
||||||
static Common::Flag s_perfQueryRequested;
|
|
||||||
static Common::Event s_perfQueryReadyEvent;
|
|
||||||
|
|
||||||
static Common::Flag s_BBoxRequested;
|
|
||||||
static Common::Event s_BBoxReadyEvent;
|
|
||||||
static int s_BBoxIndex;
|
|
||||||
static u16 s_BBoxResult;
|
|
||||||
|
|
||||||
static volatile struct
|
static volatile struct
|
||||||
{
|
{
|
||||||
@ -39,16 +29,6 @@ static volatile struct
|
|||||||
u32 fbHeight;
|
u32 fbHeight;
|
||||||
} s_beginFieldArgs;
|
} s_beginFieldArgs;
|
||||||
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
EFBAccessType type;
|
|
||||||
u32 x;
|
|
||||||
u32 y;
|
|
||||||
u32 Data;
|
|
||||||
} s_accessEFBArgs;
|
|
||||||
|
|
||||||
static u32 s_AccessEFBResult = 0;
|
|
||||||
|
|
||||||
void VideoBackendHardware::EmuStateChange(EMUSTATE_CHANGE newState)
|
void VideoBackendHardware::EmuStateChange(EMUSTATE_CHANGE newState)
|
||||||
{
|
{
|
||||||
EmulatorState((newState == EMUSTATE_CHANGE_PLAY) ? true : false);
|
EmulatorState((newState == EMUSTATE_CHANGE_PLAY) ? true : false);
|
||||||
@ -64,8 +44,6 @@ void VideoBackendHardware::Video_ExitLoop()
|
|||||||
{
|
{
|
||||||
ExitGpuLoop();
|
ExitGpuLoop();
|
||||||
s_FifoShuttingDown.Set();
|
s_FifoShuttingDown.Set();
|
||||||
s_efbAccessReadyEvent.Set();
|
|
||||||
s_perfQueryReadyEvent.Set();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBackendHardware::Video_SetRendering(bool bEnabled)
|
void VideoBackendHardware::Video_SetRendering(bool bEnabled)
|
||||||
@ -73,45 +51,11 @@ void VideoBackendHardware::Video_SetRendering(bool bEnabled)
|
|||||||
Fifo_SetRendering(bEnabled);
|
Fifo_SetRendering(bEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run from the graphics thread (from Fifo.cpp)
|
|
||||||
static void VideoFifo_CheckSwapRequest()
|
|
||||||
{
|
|
||||||
if (g_ActiveConfig.bUseXFB)
|
|
||||||
{
|
|
||||||
if (s_swapRequested.IsSet())
|
|
||||||
{
|
|
||||||
EFBRectangle rc;
|
|
||||||
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbStride, s_beginFieldArgs.fbHeight, rc);
|
|
||||||
s_swapRequested.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run from the graphics thread (from Fifo.cpp)
|
|
||||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
|
|
||||||
{
|
|
||||||
if (g_ActiveConfig.bUseXFB)
|
|
||||||
{
|
|
||||||
if (s_swapRequested.IsSet())
|
|
||||||
{
|
|
||||||
u32 aLower = xfbAddr;
|
|
||||||
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
|
||||||
u32 bLower = s_beginFieldArgs.xfbAddr;
|
|
||||||
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbStride * s_beginFieldArgs.fbHeight;
|
|
||||||
|
|
||||||
if (AddressRangesOverlap(aLower, aUpper, bLower, bUpper))
|
|
||||||
VideoFifo_CheckSwapRequest();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run from the CPU thread (from VideoInterface.cpp)
|
// Run from the CPU thread (from VideoInterface.cpp)
|
||||||
void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight)
|
void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight)
|
||||||
{
|
{
|
||||||
if (s_BackendInitialized && g_ActiveConfig.bUseXFB)
|
if (s_BackendInitialized && g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
|
||||||
VideoFifo_CheckSwapRequest();
|
|
||||||
s_beginFieldArgs.xfbAddr = xfbAddr;
|
s_beginFieldArgs.xfbAddr = xfbAddr;
|
||||||
s_beginFieldArgs.fbWidth = fbWidth;
|
s_beginFieldArgs.fbWidth = fbWidth;
|
||||||
s_beginFieldArgs.fbStride = fbStride;
|
s_beginFieldArgs.fbStride = fbStride;
|
||||||
@ -122,16 +66,19 @@ void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStri
|
|||||||
// Run from the CPU thread (from VideoInterface.cpp)
|
// Run from the CPU thread (from VideoInterface.cpp)
|
||||||
void VideoBackendHardware::Video_EndField()
|
void VideoBackendHardware::Video_EndField()
|
||||||
{
|
{
|
||||||
if (s_BackendInitialized)
|
if (s_BackendInitialized && g_ActiveConfig.bUseXFB && g_renderer)
|
||||||
{
|
{
|
||||||
SyncGPU(SYNC_GPU_SWAP);
|
SyncGPU(SYNC_GPU_SWAP);
|
||||||
|
|
||||||
// Wait until the GPU thread has swapped. Prevents FIFO overflows.
|
AsyncRequests::Event e;
|
||||||
while (g_ActiveConfig.bUseXFB && SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread && s_swapRequested.IsSet())
|
e.time = 0;
|
||||||
{
|
e.type = AsyncRequests::Event::SWAP_EVENT;
|
||||||
Common::YieldCPU();
|
|
||||||
}
|
e.swap_event.xfbAddr = s_beginFieldArgs.xfbAddr;
|
||||||
s_swapRequested.Set();
|
e.swap_event.fbWidth = s_beginFieldArgs.fbWidth;
|
||||||
|
e.swap_event.fbStride = s_beginFieldArgs.fbStride;
|
||||||
|
e.swap_event.fbHeight = s_beginFieldArgs.fbHeight;
|
||||||
|
AsyncRequests::GetInstance()->PushEvent(e, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,53 +99,35 @@ bool VideoBackendHardware::Video_Screenshot(const std::string& filename)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoFifo_CheckEFBAccess()
|
|
||||||
{
|
|
||||||
if (s_efbAccessRequested.IsSet())
|
|
||||||
{
|
|
||||||
s_AccessEFBResult = g_renderer->AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
|
|
||||||
s_efbAccessRequested.Clear();
|
|
||||||
s_efbAccessReadyEvent.Set();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
||||||
{
|
{
|
||||||
if (s_BackendInitialized && g_ActiveConfig.bEFBAccessEnable)
|
if (!g_ActiveConfig.bEFBAccessEnable)
|
||||||
{
|
{
|
||||||
SyncGPU(SYNC_GPU_EFB_POKE);
|
|
||||||
|
|
||||||
s_accessEFBArgs.type = type;
|
|
||||||
s_accessEFBArgs.x = x;
|
|
||||||
s_accessEFBArgs.y = y;
|
|
||||||
s_accessEFBArgs.Data = InputData;
|
|
||||||
|
|
||||||
s_efbAccessRequested.Set();
|
|
||||||
|
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
|
||||||
{
|
|
||||||
s_efbAccessReadyEvent.Reset();
|
|
||||||
if (s_FifoShuttingDown.IsSet())
|
|
||||||
return 0;
|
return 0;
|
||||||
s_efbAccessRequested.Set();
|
}
|
||||||
s_efbAccessReadyEvent.Wait();
|
|
||||||
|
if (type == POKE_COLOR || type == POKE_Z)
|
||||||
|
{
|
||||||
|
AsyncRequests::Event e;
|
||||||
|
e.type = type == POKE_COLOR ? AsyncRequests::Event::EFB_POKE_COLOR : AsyncRequests::Event::EFB_POKE_Z;
|
||||||
|
e.time = 0;
|
||||||
|
e.efb_poke.data = InputData;
|
||||||
|
e.efb_poke.x = x;
|
||||||
|
e.efb_poke.y = y;
|
||||||
|
AsyncRequests::GetInstance()->PushEvent(e, false);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
VideoFifo_CheckEFBAccess();
|
|
||||||
|
|
||||||
return s_AccessEFBResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VideoFifo_CheckPerfQueryRequest()
|
|
||||||
{
|
|
||||||
if (s_perfQueryRequested.IsSet())
|
|
||||||
{
|
{
|
||||||
g_perf_query->FlushResults();
|
AsyncRequests::Event e;
|
||||||
s_perfQueryRequested.Clear();
|
u32 result;
|
||||||
s_perfQueryReadyEvent.Set();
|
e.type = type == PEEK_COLOR ? AsyncRequests::Event::EFB_PEEK_COLOR : AsyncRequests::Event::EFB_PEEK_Z;
|
||||||
|
e.time = 0;
|
||||||
|
e.efb_peek.x = x;
|
||||||
|
e.efb_peek.y = y;
|
||||||
|
e.efb_peek.data = &result;
|
||||||
|
AsyncRequests::GetInstance()->PushEvent(e, true);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,20 +140,12 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type)
|
|||||||
|
|
||||||
SyncGPU(SYNC_GPU_PERFQUERY);
|
SyncGPU(SYNC_GPU_PERFQUERY);
|
||||||
|
|
||||||
// TODO: Is this check sane?
|
AsyncRequests::Event e;
|
||||||
|
e.time = 0;
|
||||||
|
e.type = AsyncRequests::Event::PERF_QUERY;
|
||||||
|
|
||||||
if (!g_perf_query->IsFlushed())
|
if (!g_perf_query->IsFlushed())
|
||||||
{
|
AsyncRequests::GetInstance()->PushEvent(e, true);
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
|
||||||
{
|
|
||||||
s_perfQueryReadyEvent.Reset();
|
|
||||||
if (s_FifoShuttingDown.IsSet())
|
|
||||||
return 0;
|
|
||||||
s_perfQueryRequested.Set();
|
|
||||||
s_perfQueryReadyEvent.Wait();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_perf_query->FlushResults();
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_perf_query->GetQueryResult(type);
|
return g_perf_query->GetQueryResult(type);
|
||||||
}
|
}
|
||||||
@ -236,43 +157,23 @@ u16 VideoBackendHardware::Video_GetBoundingBox(int index)
|
|||||||
|
|
||||||
SyncGPU(SYNC_GPU_BBOX);
|
SyncGPU(SYNC_GPU_BBOX);
|
||||||
|
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
AsyncRequests::Event e;
|
||||||
{
|
u16 result;
|
||||||
s_BBoxReadyEvent.Reset();
|
e.time = 0;
|
||||||
if (s_FifoShuttingDown.IsSet())
|
e.type = AsyncRequests::Event::BBOX_READ;
|
||||||
return 0;
|
e.bbox.index = index;
|
||||||
s_BBoxIndex = index;
|
e.bbox.data = &result;
|
||||||
s_BBoxRequested.Set();
|
AsyncRequests::GetInstance()->PushEvent(e, true);
|
||||||
s_BBoxReadyEvent.Wait();
|
|
||||||
return s_BBoxResult;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return g_renderer->BBoxRead(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VideoFifo_CheckBBoxRequest()
|
return result;
|
||||||
{
|
|
||||||
if (s_BBoxRequested.IsSet())
|
|
||||||
{
|
|
||||||
s_BBoxResult = g_renderer->BBoxRead(s_BBoxIndex);
|
|
||||||
s_BBoxRequested.Clear();
|
|
||||||
s_BBoxReadyEvent.Set();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBackendHardware::InitializeShared()
|
void VideoBackendHardware::InitializeShared()
|
||||||
{
|
{
|
||||||
VideoCommon_Init();
|
VideoCommon_Init();
|
||||||
|
|
||||||
s_swapRequested.Clear();
|
|
||||||
s_efbAccessRequested.Clear();
|
|
||||||
s_perfQueryRequested.Clear();
|
|
||||||
s_FifoShuttingDown.Clear();
|
s_FifoShuttingDown.Clear();
|
||||||
memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs));
|
memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs));
|
||||||
memset(&s_accessEFBArgs, 0, sizeof(s_accessEFBArgs));
|
|
||||||
s_AccessEFBResult = 0;
|
|
||||||
m_invalid = false;
|
m_invalid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,11 +192,7 @@ void VideoBackendHardware::DoState(PointerWrap& p)
|
|||||||
VideoCommon_DoState(p);
|
VideoCommon_DoState(p);
|
||||||
p.DoMarker("VideoCommon");
|
p.DoMarker("VideoCommon");
|
||||||
|
|
||||||
p.Do(s_swapRequested);
|
|
||||||
p.Do(s_efbAccessRequested);
|
|
||||||
p.Do(s_beginFieldArgs);
|
p.Do(s_beginFieldArgs);
|
||||||
p.Do(s_accessEFBArgs);
|
|
||||||
p.Do(s_AccessEFBResult);
|
|
||||||
p.DoMarker("VideoBackendHardware");
|
p.DoMarker("VideoBackendHardware");
|
||||||
|
|
||||||
// Refresh state.
|
// Refresh state.
|
||||||
@ -326,20 +223,11 @@ void VideoBackendHardware::PauseAndLock(bool doLock, bool unpauseOnUnlock)
|
|||||||
Fifo_PauseAndLock(doLock, unpauseOnUnlock);
|
Fifo_PauseAndLock(doLock, unpauseOnUnlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VideoBackendHardware::RunLoop(bool enable)
|
void VideoBackendHardware::RunLoop(bool enable)
|
||||||
{
|
{
|
||||||
VideoCommon_RunLoop(enable);
|
VideoCommon_RunLoop(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoFifo_CheckAsyncRequest()
|
|
||||||
{
|
|
||||||
VideoFifo_CheckSwapRequest();
|
|
||||||
VideoFifo_CheckEFBAccess();
|
|
||||||
VideoFifo_CheckPerfQueryRequest();
|
|
||||||
VideoFifo_CheckBBoxRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoBackendHardware::Video_GatherPipeBursted()
|
void VideoBackendHardware::Video_GatherPipeBursted()
|
||||||
{
|
{
|
||||||
CommandProcessor::GatherPipeBursted();
|
CommandProcessor::GatherPipeBursted();
|
||||||
|
@ -4,7 +4,3 @@
|
|||||||
#include "Common/Flag.h"
|
#include "Common/Flag.h"
|
||||||
|
|
||||||
extern bool s_BackendInitialized;
|
extern bool s_BackendInitialized;
|
||||||
extern Common::Flag s_swapRequested;
|
|
||||||
|
|
||||||
void VideoFifo_CheckEFBAccess();
|
|
||||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
|
||||||
|
@ -116,8 +116,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt
|
|||||||
if (!fbWidth || !fbHeight)
|
if (!fbWidth || !fbHeight)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VideoFifo_CheckEFBAccess();
|
|
||||||
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
|
|
||||||
XFBWrited = true;
|
XFBWrited = true;
|
||||||
|
|
||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
@ -127,7 +125,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Swap(xfbAddr, fbWidth, fbWidth, fbHeight, sourceRc, Gamma);
|
Swap(xfbAddr, fbWidth, fbWidth, fbHeight, sourceRc, Gamma);
|
||||||
s_swapRequested.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +166,6 @@ void VertexManager::Flush()
|
|||||||
// loading a state will invalidate BP, so check for it
|
// loading a state will invalidate BP, so check for it
|
||||||
g_video_backend->CheckInvalidState();
|
g_video_backend->CheckInvalidState();
|
||||||
|
|
||||||
VideoFifo_CheckEFBAccess();
|
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfmem.numTexGen.numTexGens,
|
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfmem.numTexGen.numTexGens,
|
||||||
xfmem.numChan.numColorChans, xfmem.dualTexTrans.enabled, bpmem.ztex2.op,
|
xfmem.numChan.numColorChans, xfmem.dualTexTrans.enabled, bpmem.ztex2.op,
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="AsyncRequests.cpp" />
|
||||||
<ClCompile Include="AVIDump.cpp" />
|
<ClCompile Include="AVIDump.cpp" />
|
||||||
<ClCompile Include="BoundingBox.cpp" />
|
<ClCompile Include="BoundingBox.cpp" />
|
||||||
<ClCompile Include="BPFunctions.cpp" />
|
<ClCompile Include="BPFunctions.cpp" />
|
||||||
@ -84,6 +85,7 @@
|
|||||||
<ClCompile Include="XFStructs.cpp" />
|
<ClCompile Include="XFStructs.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="AsyncRequests.h" />
|
||||||
<ClInclude Include="AVIDump.h" />
|
<ClInclude Include="AVIDump.h" />
|
||||||
<ClInclude Include="BoundingBox.h" />
|
<ClInclude Include="BoundingBox.h" />
|
||||||
<ClInclude Include="BPFunctions.h" />
|
<ClInclude Include="BPFunctions.h" />
|
||||||
|
@ -146,6 +146,9 @@
|
|||||||
<ClCompile Include="TextureDecoder_x64.cpp">
|
<ClCompile Include="TextureDecoder_x64.cpp">
|
||||||
<Filter>Decoding</Filter>
|
<Filter>Decoding</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="AsyncRequests.cpp">
|
||||||
|
<Filter>Util</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="BoundingBox.cpp">
|
<ClCompile Include="BoundingBox.cpp">
|
||||||
<Filter>Util</Filter>
|
<Filter>Util</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -290,6 +293,9 @@
|
|||||||
<ClInclude Include="VertexLoaderUtils.h">
|
<ClInclude Include="VertexLoaderUtils.h">
|
||||||
<Filter>Vertex Loading</Filter>
|
<Filter>Vertex Loading</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="AsyncRequests.h">
|
||||||
|
<Filter>Util</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="BoundingBox.h">
|
<ClInclude Include="BoundingBox.h">
|
||||||
<Filter>Util</Filter>
|
<Filter>Util</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user