Support rendering windowless (tested on the Vulkan backend)
This commit is contained in:
@@ -51,16 +51,21 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||
// This must happen on the UI thread.
|
||||
std::unique_ptr<xe::ui::GraphicsContext> processor_context = nullptr;
|
||||
if (provider_) {
|
||||
target_window_->loop()->PostSynchronous([&]() {
|
||||
// Create the context used for presentation.
|
||||
assert_null(target_window->context());
|
||||
target_window_->set_context(provider_->CreateContext(target_window_));
|
||||
if (target_window_) {
|
||||
target_window_->loop()->PostSynchronous([&]() {
|
||||
// Create the context used for presentation.
|
||||
assert_null(target_window->context());
|
||||
target_window_->set_context(provider_->CreateContext(target_window_));
|
||||
|
||||
// Setup the context the command processor will do all its drawing in.
|
||||
// It's shared with the display context so that we can resolve
|
||||
// framebuffers from it.
|
||||
// Setup the context the command processor will do all its drawing in.
|
||||
// It's shared with the display context so that we can resolve
|
||||
// framebuffers from it.
|
||||
processor_context = provider()->CreateOffscreenContext();
|
||||
});
|
||||
} else {
|
||||
processor_context = provider()->CreateOffscreenContext();
|
||||
});
|
||||
}
|
||||
|
||||
if (!processor_context) {
|
||||
xe::FatalError(
|
||||
"Unable to initialize graphics context. Xenia requires OpenGL 4.5 or "
|
||||
@@ -78,16 +83,21 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||
XELOGE("Unable to initialize command processor");
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
command_processor_->set_swap_request_handler(
|
||||
[this]() { target_window_->Invalidate(); });
|
||||
|
||||
// Watch for paint requests to do our swap.
|
||||
target_window->on_painting.AddListener(
|
||||
[this](xe::ui::UIEvent* e) { Swap(e); });
|
||||
if (target_window) {
|
||||
command_processor_->set_swap_request_handler(
|
||||
[this]() { target_window_->Invalidate(); });
|
||||
|
||||
// Watch for context lost events.
|
||||
target_window->on_context_lost.AddListener(
|
||||
[this](xe::ui::UIEvent* e) { Reset(); });
|
||||
// Watch for paint requests to do our swap.
|
||||
target_window->on_painting.AddListener(
|
||||
[this](xe::ui::UIEvent* e) { Swap(e); });
|
||||
|
||||
// Watch for context lost events.
|
||||
target_window->on_context_lost.AddListener(
|
||||
[this](xe::ui::UIEvent* e) { Reset(); });
|
||||
} else {
|
||||
command_processor_->set_swap_request_handler([]() {});
|
||||
}
|
||||
|
||||
// Let the processor know we want register access callbacks.
|
||||
memory_->AddVirtualMappedRange(
|
||||
|
||||
@@ -212,13 +212,13 @@ VkResult TextureCache::Initialize() {
|
||||
invalidated_textures_sets_[1].reserve(64);
|
||||
invalidated_textures_ = &invalidated_textures_sets_[0];
|
||||
|
||||
device_queue_ = device_->AcquireQueue();
|
||||
device_queue_ = device_->AcquireQueue(device_->queue_family_index());
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void TextureCache::Shutdown() {
|
||||
if (device_queue_) {
|
||||
device_->ReleaseQueue(device_queue_);
|
||||
device_->ReleaseQueue(device_queue_, device_->queue_family_index());
|
||||
}
|
||||
|
||||
// Free all textures allocated.
|
||||
|
||||
@@ -62,7 +62,7 @@ bool VulkanCommandProcessor::SetupContext() {
|
||||
// Acquire our device and queue.
|
||||
auto context = static_cast<xe::ui::vulkan::VulkanContext*>(context_.get());
|
||||
device_ = context->device();
|
||||
queue_ = device_->AcquireQueue();
|
||||
queue_ = device_->AcquireQueue(device_->queue_family_index());
|
||||
if (!queue_) {
|
||||
// Need to reuse primary queue (with locks).
|
||||
queue_ = device_->primary_queue();
|
||||
@@ -159,7 +159,7 @@ void VulkanCommandProcessor::ShutdownContext() {
|
||||
|
||||
// Release queue, if we were using an acquired one.
|
||||
if (!queue_mutex_) {
|
||||
device_->ReleaseQueue(queue_);
|
||||
device_->ReleaseQueue(queue_, device_->queue_family_index());
|
||||
queue_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,16 +37,19 @@ X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
|
||||
kernel::KernelState* kernel_state,
|
||||
ui::Window* target_window) {
|
||||
// Must create the provider so we can create contexts.
|
||||
provider_ = xe::ui::vulkan::VulkanProvider::Create(target_window);
|
||||
auto provider = xe::ui::vulkan::VulkanProvider::Create(target_window);
|
||||
device_ = provider->device();
|
||||
provider_ = std::move(provider);
|
||||
|
||||
auto result = GraphicsSystem::Setup(processor, kernel_state, target_window);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
display_context_ = reinterpret_cast<xe::ui::vulkan::VulkanContext*>(
|
||||
target_window->context());
|
||||
device_ = display_context_->device();
|
||||
if (target_window) {
|
||||
display_context_ = reinterpret_cast<xe::ui::vulkan::VulkanContext*>(
|
||||
target_window->context());
|
||||
}
|
||||
|
||||
// Create our own command pool we can use for captures.
|
||||
VkCommandPoolCreateInfo create_info = {
|
||||
|
||||
Reference in New Issue
Block a user