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()),
|
||||
trace_writer_(graphics_system->memory()->membase()),
|
||||
worker_running_(true),
|
||||
swap_mode_(SwapMode::kNormal),
|
||||
time_base_(0),
|
||||
counter_(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 {
|
||||
public:
|
||||
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) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
auto& regs = *register_file_;
|
||||
|
||||
PLOGI("XE_SWAP");
|
||||
|
||||
// Xenia-specific VdSwap hook.
|
||||
|
@ -823,38 +861,8 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingbufferReader* reader,
|
|||
// Ensure we issue any pending draws.
|
||||
draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent);
|
||||
|
||||
if (swap_handler_) {
|
||||
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();
|
||||
if (swap_mode_ == SwapMode::kNormal) {
|
||||
IssueSwap();
|
||||
}
|
||||
|
||||
trace_writer_.WriteEvent(EventType::kSwap);
|
||||
|
|
|
@ -43,6 +43,11 @@ struct SwapParameters {
|
|||
GLenum attachment;
|
||||
};
|
||||
|
||||
enum class SwapMode {
|
||||
kNormal,
|
||||
kIgnored,
|
||||
};
|
||||
|
||||
class CommandProcessor {
|
||||
public:
|
||||
CommandProcessor(GL4GraphicsSystem* graphics_system);
|
||||
|
@ -59,6 +64,9 @@ class CommandProcessor {
|
|||
void Shutdown();
|
||||
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 EndTracing();
|
||||
|
||||
|
@ -207,6 +215,8 @@ class CommandProcessor {
|
|||
std::function<void()> pending_fn_;
|
||||
HANDLE pending_fn_event_;
|
||||
|
||||
SwapMode swap_mode_;
|
||||
|
||||
uint64_t time_base_;
|
||||
uint32_t counter_;
|
||||
|
||||
|
|
|
@ -122,6 +122,10 @@ void GL4GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr,
|
|||
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,
|
||||
size_t trace_size,
|
||||
TracePlaybackMode playback_mode) {
|
||||
|
|
|
@ -36,6 +36,8 @@ class GL4GraphicsSystem : public GraphicsSystem {
|
|||
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count) 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,
|
||||
TracePlaybackMode playback_mode) override;
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ class GraphicsSystem {
|
|||
virtual void EnableReadPointerWriteBack(uint32_t ptr,
|
||||
uint32_t block_size) = 0;
|
||||
|
||||
virtual void RequestSwap() = 0;
|
||||
|
||||
void DispatchInterruptCallback(uint32_t source, uint32_t cpu);
|
||||
|
||||
enum class TracePlaybackMode {
|
||||
|
|
Loading…
Reference in New Issue