RequestSwap to force a swap from the GL thread.
This commit is contained in:
parent
9b21dd8874
commit
5227fe72b5
|
@ -55,6 +55,7 @@ CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system)
|
||||||
register_file_(graphics_system_->register_file()),
|
register_file_(graphics_system_->register_file()),
|
||||||
trace_writer_(graphics_system->memory()->membase()),
|
trace_writer_(graphics_system->memory()->membase()),
|
||||||
worker_running_(true),
|
worker_running_(true),
|
||||||
|
swap_mode_(SwapMode::kNormal),
|
||||||
time_base_(0),
|
time_base_(0),
|
||||||
counter_(0),
|
counter_(0),
|
||||||
primary_buffer_ptr_(0),
|
primary_buffer_ptr_(0),
|
||||||
|
@ -480,6 +481,45 @@ void CommandProcessor::ReturnFromWait() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandProcessor::IssueSwap() {
|
||||||
|
if (!swap_handler_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& regs = *register_file_;
|
||||||
|
SwapParameters swap_params;
|
||||||
|
|
||||||
|
// Lookup the framebuffer in the recently-resolved list.
|
||||||
|
// TODO(benvanik): make this much more sophisticated.
|
||||||
|
// TODO(benvanik): handle not found cases.
|
||||||
|
// TODO(benvanik): handle dirty cases (resolved to sysmem, touched).
|
||||||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
// HACK: just use whatever our current framebuffer is.
|
||||||
|
if (active_framebuffer_) {
|
||||||
|
swap_params.framebuffer = active_framebuffer_->framebuffer;
|
||||||
|
// TODO(benvanik): pick the right one?
|
||||||
|
swap_params.attachment = GL_COLOR_ATTACHMENT0;
|
||||||
|
} else {
|
||||||
|
swap_params.framebuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess frontbuffer dimensions.
|
||||||
|
// Command buffer seems to set these right before the XE_SWAP.
|
||||||
|
uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32;
|
||||||
|
uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32;
|
||||||
|
swap_params.x = window_scissor_tl & 0x7FFF;
|
||||||
|
swap_params.y = (window_scissor_tl >> 16) & 0x7FFF;
|
||||||
|
swap_params.width = window_scissor_br & 0x7FFF - swap_params.x;
|
||||||
|
swap_params.height = (window_scissor_br >> 16) & 0x7FFF - swap_params.y;
|
||||||
|
|
||||||
|
PrepareForWait();
|
||||||
|
swap_handler_(swap_params);
|
||||||
|
ReturnFromWait();
|
||||||
|
|
||||||
|
// Remove any dead textures, etc.
|
||||||
|
texture_cache_.Scavenge();
|
||||||
|
}
|
||||||
|
|
||||||
class CommandProcessor::RingbufferReader {
|
class CommandProcessor::RingbufferReader {
|
||||||
public:
|
public:
|
||||||
RingbufferReader(uint8_t* membase, uint32_t base_ptr, uint32_t ptr_mask,
|
RingbufferReader(uint8_t* membase, uint32_t base_ptr, uint32_t ptr_mask,
|
||||||
|
@ -809,8 +849,6 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingbufferReader* reader,
|
||||||
uint32_t count) {
|
uint32_t count) {
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
|
||||||
auto& regs = *register_file_;
|
|
||||||
|
|
||||||
PLOGI("XE_SWAP");
|
PLOGI("XE_SWAP");
|
||||||
|
|
||||||
// Xenia-specific VdSwap hook.
|
// Xenia-specific VdSwap hook.
|
||||||
|
@ -823,38 +861,8 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingbufferReader* reader,
|
||||||
// Ensure we issue any pending draws.
|
// Ensure we issue any pending draws.
|
||||||
draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent);
|
draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent);
|
||||||
|
|
||||||
if (swap_handler_) {
|
if (swap_mode_ == SwapMode::kNormal) {
|
||||||
SwapParameters swap_params;
|
IssueSwap();
|
||||||
|
|
||||||
// Lookup the framebuffer in the recently-resolved list.
|
|
||||||
// TODO(benvanik): make this much more sophisticated.
|
|
||||||
// TODO(benvanik): handle not found cases.
|
|
||||||
// TODO(benvanik): handle dirty cases (resolved to sysmem, touched).
|
|
||||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
// HACK: just use whatever our current framebuffer is.
|
|
||||||
if (active_framebuffer_) {
|
|
||||||
swap_params.framebuffer = active_framebuffer_->framebuffer;
|
|
||||||
// TODO(benvanik): pick the right one?
|
|
||||||
swap_params.attachment = GL_COLOR_ATTACHMENT0;
|
|
||||||
} else {
|
|
||||||
swap_params.framebuffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guess frontbuffer dimensions.
|
|
||||||
// Command buffer seems to set these right before the XE_SWAP.
|
|
||||||
uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32;
|
|
||||||
uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32;
|
|
||||||
swap_params.x = window_scissor_tl & 0x7FFF;
|
|
||||||
swap_params.y = (window_scissor_tl >> 16) & 0x7FFF;
|
|
||||||
swap_params.width = window_scissor_br & 0x7FFF - swap_params.x;
|
|
||||||
swap_params.height = (window_scissor_br >> 16) & 0x7FFF - swap_params.y;
|
|
||||||
|
|
||||||
PrepareForWait();
|
|
||||||
swap_handler_(swap_params);
|
|
||||||
ReturnFromWait();
|
|
||||||
|
|
||||||
// Remove any dead textures, etc.
|
|
||||||
texture_cache_.Scavenge();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_writer_.WriteEvent(EventType::kSwap);
|
trace_writer_.WriteEvent(EventType::kSwap);
|
||||||
|
|
|
@ -43,6 +43,11 @@ struct SwapParameters {
|
||||||
GLenum attachment;
|
GLenum attachment;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SwapMode {
|
||||||
|
kNormal,
|
||||||
|
kIgnored,
|
||||||
|
};
|
||||||
|
|
||||||
class CommandProcessor {
|
class CommandProcessor {
|
||||||
public:
|
public:
|
||||||
CommandProcessor(GL4GraphicsSystem* graphics_system);
|
CommandProcessor(GL4GraphicsSystem* graphics_system);
|
||||||
|
@ -59,6 +64,9 @@ class CommandProcessor {
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void CallInThread(std::function<void()> fn);
|
void CallInThread(std::function<void()> fn);
|
||||||
|
|
||||||
|
void set_swap_mode(SwapMode swap_mode) { swap_mode_ = swap_mode; }
|
||||||
|
void IssueSwap();
|
||||||
|
|
||||||
void BeginTracing(const std::wstring& root_path);
|
void BeginTracing(const std::wstring& root_path);
|
||||||
void EndTracing();
|
void EndTracing();
|
||||||
|
|
||||||
|
@ -207,6 +215,8 @@ class CommandProcessor {
|
||||||
std::function<void()> pending_fn_;
|
std::function<void()> pending_fn_;
|
||||||
HANDLE pending_fn_event_;
|
HANDLE pending_fn_event_;
|
||||||
|
|
||||||
|
SwapMode swap_mode_;
|
||||||
|
|
||||||
uint64_t time_base_;
|
uint64_t time_base_;
|
||||||
uint32_t counter_;
|
uint32_t counter_;
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,10 @@ void GL4GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr,
|
||||||
command_processor_->EnableReadPointerWriteBack(ptr, block_size);
|
command_processor_->EnableReadPointerWriteBack(ptr, block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GL4GraphicsSystem::RequestSwap() {
|
||||||
|
command_processor_->CallInThread([&]() { command_processor_->IssueSwap(); });
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t* GL4GraphicsSystem::PlayTrace(const uint8_t* trace_data,
|
const uint8_t* GL4GraphicsSystem::PlayTrace(const uint8_t* trace_data,
|
||||||
size_t trace_size,
|
size_t trace_size,
|
||||||
TracePlaybackMode playback_mode) {
|
TracePlaybackMode playback_mode) {
|
||||||
|
|
|
@ -36,6 +36,8 @@ class GL4GraphicsSystem : public GraphicsSystem {
|
||||||
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count) override;
|
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count) override;
|
||||||
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size) override;
|
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size) override;
|
||||||
|
|
||||||
|
void RequestSwap() override;
|
||||||
|
|
||||||
const uint8_t* PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
const uint8_t* PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
||||||
TracePlaybackMode playback_mode) override;
|
TracePlaybackMode playback_mode) override;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ class GraphicsSystem {
|
||||||
virtual void EnableReadPointerWriteBack(uint32_t ptr,
|
virtual void EnableReadPointerWriteBack(uint32_t ptr,
|
||||||
uint32_t block_size) = 0;
|
uint32_t block_size) = 0;
|
||||||
|
|
||||||
|
virtual void RequestSwap() = 0;
|
||||||
|
|
||||||
void DispatchInterruptCallback(uint32_t source, uint32_t cpu);
|
void DispatchInterruptCallback(uint32_t source, uint32_t cpu);
|
||||||
|
|
||||||
enum class TracePlaybackMode {
|
enum class TracePlaybackMode {
|
||||||
|
|
Loading…
Reference in New Issue