graphics: fix initialization

This commit is contained in:
nmzik
2026-07-21 07:37:52 +02:00
parent 0a5f78c727
commit 8a4600c5e9
16 changed files with 39 additions and 170 deletions
-8
View File
@@ -709,9 +709,6 @@ void GraphicsRing::Submit(OwnedCmdBuffer draw_buffer, OwnedCmdBuffer const_buffe
Common::LockGuard lock(m_mutex);
WindowWaitForGraphicInitialized();
GraphicsRenderCreateContext();
if (m_done) {
while (!m_idle) {
m_idle_cond_var.Wait(&m_mutex);
@@ -738,8 +735,6 @@ void GraphicsRing::SubmitFlipPreparation() {
EXIT_IF(m_cp == nullptr);
Common::LockGuard lock(m_mutex);
WindowWaitForGraphicInitialized();
GraphicsRenderCreateContext();
if (m_done) {
while (!m_idle) {
m_idle_cond_var.Wait(&m_mutex);
@@ -921,9 +916,6 @@ void ComputeRing::Submit(OwnedCmdBuffer buffer, bool trigger_agc_interrupt_on_do
EXIT_IF(buffer.data == nullptr);
EXIT_IF(buffer.num_dw == 0);
WindowWaitForGraphicInitialized();
GraphicsRenderCreateContext();
if (m_done) {
m_done = false;
}
-1
View File
@@ -277,7 +277,6 @@ void TileCompute::Init() {
if (resources.pipeline_layout != nullptr) {
return;
}
EXIT_IF(graphics.device == nullptr || graphics.allocator == nullptr);
std::array<vk::DescriptorSetLayoutBinding, 2> bindings {};
for (uint32_t i = 0; i < bindings.size(); i++) {
bindings[i] = {i, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eCompute,
+4 -35
View File
@@ -16,18 +16,14 @@
#include "graphics/host_gpu/transfer.h"
#include "graphics/host_gpu/vma.h"
#include "graphics/host_gpu/vulkanCommon.h"
#include "graphics/presentation/window.h"
#include <algorithm>
#include <array>
#include <atomic>
#include <cstring>
#include <memory>
#include <mutex>
namespace Libs::Graphics {
static std::atomic<uint64_t> g_command_buffer_submit_seq = 0;
static bool g_render_initialized = false;
static std::mutex g_render_init_mutex;
static void RequireValidQueueId(int queue_id) {
EXIT_IF(queue_id < 0 || queue_id >= GraphicContext::QUEUES_NUM);
@@ -71,12 +67,7 @@ private:
static RenderContext* g_render_ctx = nullptr;
static thread_local CommandPool g_command_pool;
bool HasRenderContext() noexcept {
return g_render_ctx != nullptr;
}
RenderContext& GetRenderContext() {
EXIT_IF(g_render_ctx == nullptr);
RenderContext& GetRenderContext() noexcept {
return *g_render_ctx;
}
@@ -101,30 +92,12 @@ void FenceResourceRetainer::ReleaseAfterFence() noexcept {
m_resources.clear();
}
void GraphicsRenderInit() {
std::scoped_lock lock(g_render_init_mutex);
EXIT_IF(g_render_initialized || g_render_ctx != nullptr);
g_render_initialized = true;
void GraphicsRenderInit(GraphicContext& graphics) {
g_render_ctx = new RenderContext(graphics);
}
void GraphicsRenderReleaseThreadCommandPools() {
if (g_render_ctx != nullptr) {
g_command_pool.DeleteAll();
}
}
void GraphicsRenderCreateContext() {
std::scoped_lock lock(g_render_init_mutex);
EXIT_IF(!g_render_initialized);
if (g_render_ctx == nullptr) {
g_render_ctx = new RenderContext(WindowGetGraphicContext());
}
}
void GraphicsRenderSetContext(RenderContext& context) {
std::scoped_lock lock(g_render_init_mutex);
EXIT_IF(!g_render_initialized || g_render_ctx != nullptr);
g_render_ctx = &context;
g_command_pool.DeleteAll();
}
CommandBuffer::CommandBuffer(int queue)
@@ -139,7 +112,6 @@ void CommandPool::Create(int queue_id) {
auto*& pool = m_pools[queue_id];
EXIT_IF(pool != nullptr);
EXIT_IF(graphics.device == nullptr);
EXIT_IF(graphics.queues[queue_id].family == static_cast<uint32_t>(-1));
pool = new VulkanCommandPool;
@@ -204,8 +176,6 @@ void CommandPool::DeleteAll() {
for (auto& pool: m_pools) {
if (pool != nullptr) {
EXIT_IF(graphics.device == nullptr);
for (uint32_t i = 0; i < pool->buffers_count; i++) {
graphics.device.destroySemaphore(pool->semaphores[i], nullptr);
graphics.device.destroyFence(pool->fences[i], nullptr);
@@ -369,7 +339,6 @@ void CommandBuffer::Submit(vk::Semaphore wait_semaphore, vk::PipelineStageFlags
submit_info.pSignalSemaphores = has_signal ? &signal_semaphore : nullptr;
auto& graphics = GetRenderContext().GetGraphics();
EXIT_IF(graphics.device == nullptr);
const auto& queue = graphics.queues[m_queue];
auto result = graphics.device.resetFences(1, &fence);
+1 -4
View File
@@ -33,7 +33,6 @@ struct VulkanFramebuffer;
struct RenderDepthInfo;
struct RenderColorInfo;
class BufferCache;
class RenderContext;
struct HtileClearTarget {
uint64_t address = 0;
@@ -162,9 +161,7 @@ void RenderDrawIndexAuto(uint64_t submit_id, RenderCommandBuffer& buffer, uint32
void RenderDispatchDirect(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t thread_group_x,
uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode);
void GraphicsRenderInit();
void GraphicsRenderCreateContext();
void GraphicsRenderSetContext(RenderContext& context);
void GraphicsRenderInit(GraphicContext& graphics);
void GraphicsRenderReleaseThreadCommandPools();
[[nodiscard]] bool ResolveComputeImageClear(const ShaderComputeInputInfo& input, uint32_t group_x,
@@ -63,8 +63,7 @@ private:
std::vector<EopEqRegistration> m_eop_eqs;
};
[[nodiscard]] bool HasRenderContext() noexcept;
[[nodiscard]] RenderContext& GetRenderContext();
[[nodiscard]] RenderContext& GetRenderContext() noexcept;
} // namespace Libs::Graphics
@@ -303,12 +303,9 @@ static void LogDrawInputState(const RenderColorInfo& color,
}
}
static void VulkanCmdSetColorWriteEnableEXT(const RenderCommandBuffer& buffer,
vk::CommandBuffer command_buffer,
static void VulkanCmdSetColorWriteEnableEXT(vk::CommandBuffer command_buffer,
uint32_t attachment_count,
const vk::Bool32* p_color_write_enables) {
EXIT_IF(buffer.GetGraphics().device == nullptr);
if (VULKAN_HPP_DEFAULT_DISPATCHER.vkCmdSetColorWriteEnableEXT == nullptr) {
EXIT("vkCmdSetColorWriteEnableEXT not present\n");
}
@@ -413,7 +410,7 @@ static void SetDynamicParams(const RenderCommandBuffer& buffer, vk::CommandBuffe
for (uint32_t i = 0; i < dynamic_params.color_write_count; i++) {
enable[i] = (dynamic_params.color_write_enable[i] ? VK_TRUE : VK_FALSE);
}
VulkanCmdSetColorWriteEnableEXT(buffer, vk_buffer, dynamic_params.color_write_count, enable);
VulkanCmdSetColorWriteEnableEXT(vk_buffer, dynamic_params.color_write_count, enable);
}
static bool DrawHasValidVertexShader(const HW::Shader& sh_ctx) {
+10 -10
View File
@@ -52,20 +52,20 @@ struct ImageImageCopy {
explicit ImageImageCopy(VulkanImage& source): src_image(source) {}
VulkanImage& src_image;
uint32_t src_level;
uint32_t dst_level;
uint32_t width;
uint32_t height;
uint32_t src_level = 0;
uint32_t dst_level = 0;
uint32_t width = 0;
uint32_t height = 0;
uint32_t src_layer = 0;
uint32_t dst_layer = 0;
vk::ImageAspectFlags src_aspect = vk::ImageAspectFlagBits::eColor;
vk::ImageAspectFlags dst_aspect = vk::ImageAspectFlagBits::eColor;
int src_x;
int src_y;
int src_z = 0;
int dst_x;
int dst_y;
int dst_z = 0;
int src_x = 0;
int src_y = 0;
int src_z = 0;
int dst_x = 0;
int dst_y = 0;
int dst_z = 0;
};
namespace Transfer {
-2
View File
@@ -1104,8 +1104,6 @@ static int RegisterBuffersInternal(VideoOutConfig& ctx, int set_id, int start_in
if (set_id < 0 || set_id >= VIDEO_OUT_BUFFER_ATTRIBUTE_NUM_MAX) {
EXIT("internal video-out buffer set identifier is out of range\n");
}
Graphics::WindowWaitForGraphicInitialized();
Graphics::GraphicsRenderCreateContext();
Common::LockGuard lock(ctx.mutex);
if (ctx.closing) {
EXIT("cannot register buffers on a closing video-out handle\n");
-7
View File
@@ -3,22 +3,15 @@
#include "common/abi.h"
#include "common/common.h"
#include "graphics/host_gpu/vulkanCommon.h"
namespace Libs::Graphics {
struct GraphicContext;
class CommandBuffer;
struct VideoOutVulkanImage;
struct PreparedFrame;
vk::SurfaceCapabilitiesKHR* VulkanGetSurfaceCapabilities();
GraphicContext& WindowGetGraphicContext();
void WindowInit(uint32_t width, uint32_t height);
void WindowRun();
void WindowWaitForGraphicInitialized();
PreparedFrame& WindowPrepareFrame(CommandBuffer& buffer, VideoOutVulkanImage& image);
PreparedFrame& WindowPrepareBlankFrame(CommandBuffer& buffer, uint32_t width, uint32_t height,
bool opaque);
@@ -139,7 +139,6 @@ static PreparedFramePool* GetPreparedFramePool() {
}
static void ConfigurePreparedFrame(PreparedFrame& frame, vk::Extent2D extent, vk::Format format) {
EXIT_IF(g_window_ctx == nullptr);
if (extent.width == 0 || extent.height == 0 || format == vk::Format::eUndefined) {
EXIT("unsupported prepared frame, extent=%ux%u format=%d\n", extent.width, extent.height,
static_cast<int>(format));
@@ -284,7 +283,6 @@ VulkanSwapchain::~VulkanSwapchain() = default;
}
VulkanSwapchain* VulkanCreateSwapchain(uint32_t image_count) {
EXIT_IF(g_window_ctx == nullptr);
auto& graphics = g_window_ctx->graphic_ctx;
EXIT_IF(graphics.screen_width == 0);
EXIT_IF(graphics.screen_height == 0);
@@ -363,10 +361,6 @@ static void VulkanDeleteSwapchain(VulkanSwapchain* s) {
}
static void VulkanRefreshSurfaceSize() {
EXIT_IF(g_window_ctx == nullptr);
EXIT_IF(g_window_ctx->window == nullptr);
EXIT_IF(g_window_ctx->surface_capabilities == nullptr);
int width = 0;
int height = 0;
SDL_Vulkan_GetDrawableSize(g_window_ctx->window, &width, &height);
@@ -380,8 +374,6 @@ static void VulkanRefreshSurfaceSize() {
}
static void VulkanRecreateSwapchain() {
EXIT_IF(g_window_ctx == nullptr);
LOGF("Recreating Vulkan swapchain\n");
VulkanRefreshSurfaceSize();
VulkanDeleteSwapchain(g_window_ctx->swapchain);
@@ -431,8 +423,6 @@ PreparedFrame& WindowPrepareBlankFrame(CommandBuffer& buffer, uint32_t width, ui
void WindowPresentFrame(PreparedFrame& frame) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(g_window_ctx == nullptr);
EXIT_IF(g_window_ctx->swapchain == nullptr);
struct ReleaseScope {
PreparedFrame* frame;
~ReleaseScope() { GetPreparedFramePool()->Release(frame); }
+8 -56
View File
@@ -242,6 +242,7 @@ struct WindowGamePrivate {
};
WindowContext* g_window_ctx = nullptr;
static WindowGame g_window_game;
constexpr const char* KYTY_SDL_WINDOW_CAPTION = "Game";
constexpr uint32_t KYTY_SDL_WINDOW_FLAGS =
@@ -309,7 +310,7 @@ static bool RenderAndUpdate(WindowGame& game) {
bool GameInit(WindowGame& game, const Common::Timer& timer) {
EXIT_IF(game.private_data || game.event);
auto& graphics = WindowGetGraphicContext();
auto& graphics = g_window_ctx->graphic_ctx;
EXIT_IF(graphics.screen_width == 0 || graphics.screen_height == 0);
@@ -956,44 +957,16 @@ void WindowInit(uint32_t width, uint32_t height) {
g_window_ctx->graphic_ctx.screen_width = width;
g_window_ctx->graphic_ctx.screen_height = height;
}
void WindowWaitForGraphicInitialized() {
EXIT_IF(g_window_ctx == nullptr);
Common::LockGuard lock(g_window_ctx->mutex);
while (!g_window_ctx->graphic_initialized) {
g_window_ctx->graphic_initialized_condvar.Wait(&g_window_ctx->mutex);
}
WindowCreate(*g_window_ctx);
VulkanCreate(*g_window_ctx);
GraphicsRenderInit(g_window_ctx->graphic_ctx);
}
void WindowRun() {
EXIT_IF(g_window_ctx == nullptr);
KYTY_PROFILER_THREAD("Thread_Window");
WindowGame game;
g_window_ctx->mutex.Lock();
{
EXIT_IF(g_window_ctx->graphic_initialized);
WindowCreate(*g_window_ctx);
VulkanCreate(*g_window_ctx);
g_window_ctx->game = &game;
}
g_window_ctx->mutex.Unlock();
GraphicsRenderCreateContext();
g_window_ctx->mutex.Lock();
g_window_ctx->graphic_initialized = true;
g_window_ctx->graphic_initialized_condvar.Signal();
g_window_ctx->mutex.Unlock();
GameMainLoop(game);
GameMainLoop(g_window_game);
// TODO: replace std::_Exit shutdown with full Vulkan teardown, then destroy
// the VMA allocator immediately before vkDestroyDevice.
@@ -1001,22 +974,6 @@ void WindowRun() {
std::_Exit(0);
}
vk::SurfaceCapabilitiesKHR* VulkanGetSurfaceCapabilities() {
EXIT_IF(g_window_ctx == nullptr);
Common::LockGuard lock(g_window_ctx->mutex);
return &g_window_ctx->surface_capabilities->capabilities;
}
GraphicContext& WindowGetGraphicContext() {
EXIT_IF(g_window_ctx == nullptr);
Common::LockGuard lock(g_window_ctx->mutex);
return g_window_ctx->graphic_ctx;
}
static int WindowIconRead(void* user, char* data, int size) {
auto* src = static_cast<Common::File*>(user);
uint32_t bytes_read = 0;
@@ -1077,8 +1034,6 @@ static void WindowLoadPngIcon(const std::string& path, WindowIcon* icon) {
}
void WindowUpdateIcon() {
EXIT_IF(g_window_ctx == nullptr);
static WindowIcon icon;
static bool icon_loaded = false;
@@ -1096,9 +1051,6 @@ void WindowUpdateIcon() {
}
void WindowUpdateTitle() {
EXIT_IF(g_window_ctx == nullptr);
EXIT_IF(g_window_ctx->game == nullptr);
static char title[128];
static char title_id[12];
static char app_ver[12];
@@ -1112,8 +1064,8 @@ void WindowUpdateTitle() {
(has_title ? ", " : ""), (has_title_id ? title_id : ""),
(has_title_id ? ", " : ""), (has_app_ver ? app_ver : ""),
(has_app_ver ? " " : ""), g_window_ctx->device_name,
g_window_ctx->processor_name, g_window_ctx->game->m_frame_num,
g_window_ctx->game->m_current_fps);
g_window_ctx->processor_name, g_window_game.m_frame_num,
g_window_game.m_current_fps);
SDL_SetWindowTitle(g_window_ctx->window, fps.c_str());
}
@@ -11,8 +11,6 @@
namespace Libs::Graphics {
struct WindowGame;
struct SurfaceCapabilities {
vk::SurfaceCapabilitiesKHR capabilities {};
std::vector<vk::SurfaceFormatKHR> formats;
@@ -28,14 +26,11 @@ struct WindowContext {
bool window_hidden = true;
vk::SurfaceKHR surface = nullptr;
SurfaceCapabilities* surface_capabilities = nullptr;
WindowGame* game = nullptr;
char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] = {0};
char processor_name[64] = {0};
Common::Mutex mutex;
bool graphic_initialized = false;
Common::CondVar graphic_initialized_condvar;
Common::Mutex mutex;
};
extern WindowContext* g_window_ctx;
+1 -1
View File
@@ -883,7 +883,7 @@ void WriteBacking(uint64_t vaddr, const void* data, uint64_t size) noexcept {
}
void PrepareHostWrite(uint64_t vaddr, uint64_t size) {
if (size == 0 || !Graphics::HasRenderContext()) {
if (size == 0) {
return;
}
Graphics::GetRenderContext().GetGpuResources().PrepareHostWrite(vaddr, size);
-2
View File
@@ -12,7 +12,6 @@
#include "graphics/guest_gpu/pm4.h"
#include "graphics/guest_gpu/tile.h"
#include "graphics/host_gpu/objects/label.h"
#include "graphics/host_gpu/renderer/render.h"
#include "graphics/host_gpu/renderer/sync.h"
#include "graphics/presentation/renderDoc.h"
#include "graphics/presentation/videoOut.h"
@@ -49,7 +48,6 @@ KYTY_SUBSYSTEM_INIT(Graphics) {
WindowInit(width, height);
VideoOut::VideoOutInit(width, height);
GraphicsRenderInit();
GraphicsRunInit();
LabelInit();
ShaderInit();
+1 -2
View File
@@ -515,8 +515,7 @@ static bool KytyExceptionHandler(const Common::HostException::ExceptionInfo& exc
EXIT("invalid access type for page fault at 0x%016" PRIx64 "\n",
info->access_violation_vaddr);
}();
if (Libs::Graphics::HasRenderContext() &&
Libs::Graphics::GetRenderContext().GetGpuResources().HandleFault(
if (Libs::Graphics::GetRenderContext().GetGpuResources().HandleFault(
access, info->access_violation_vaddr)) {
return true;
}
+10 -19
View File
@@ -1068,13 +1068,11 @@ public:
RequireVk(name, "memory", m_device.bindImageMemory(image_handle, memory, 0),
"vkBindImageMemory");
GraphicContext context{};
context.physical_device = m_physical_device;
context.device = m_device;
EnsureRuntimeContext();
ResourceMutex resource_mutex;
PageManager page_manager(RejectUnexpectedPageFault, nullptr);
BufferCache buffer_cache(context, page_manager, resource_mutex);
TextureCache texture_cache(context, page_manager, buffer_cache,
BufferCache buffer_cache(m_runtime_context, page_manager, resource_mutex);
TextureCache texture_cache(m_runtime_context, page_manager, buffer_cache,
resource_mutex);
buffer_cache.SetTextureCache(texture_cache);
RenderTextureVulkanImage image;
@@ -1182,13 +1180,11 @@ public:
RequireVk(name, "memory", m_device.bindImageMemory(image_handle, memory, 0),
"vkBindImageMemory");
GraphicContext context{};
context.physical_device = m_physical_device;
context.device = m_device;
EnsureRuntimeContext();
ResourceMutex resource_mutex;
PageManager page_manager(RejectUnexpectedPageFault, nullptr);
BufferCache buffer_cache(context, page_manager, resource_mutex);
TextureCache texture_cache(context, page_manager, buffer_cache,
BufferCache buffer_cache(m_runtime_context, page_manager, resource_mutex);
TextureCache texture_cache(m_runtime_context, page_manager, buffer_cache,
resource_mutex);
buffer_cache.SetTextureCache(texture_cache);
DepthStencilVulkanImage image;
@@ -1253,13 +1249,11 @@ public:
vk::ImageUsageFlagBits::eSampled,
{}, 1, vk::ImageLayout::eShaderReadOnlyOptimal);
GraphicContext context{};
context.physical_device = m_physical_device;
context.device = m_device;
EnsureRuntimeContext();
ResourceMutex resource_mutex;
PageManager page_manager(RejectUnexpectedPageFault, nullptr);
BufferCache buffer_cache(context, page_manager, resource_mutex);
TextureCache texture_cache(context, page_manager, buffer_cache,
BufferCache buffer_cache(m_runtime_context, page_manager, resource_mutex);
TextureCache texture_cache(m_runtime_context, page_manager, buffer_cache,
resource_mutex);
buffer_cache.SetTextureCache(texture_cache);
VideoOutVulkanImage image;
@@ -3076,10 +3070,7 @@ private:
static_cast<vk::Result>(vmaCreateAllocator(
&allocator_info, &m_runtime_context.allocator)),
"vmaCreateAllocator");
if (!HasRenderContext()) {
GraphicsRenderInit();
GraphicsRenderSetContext(*new RenderContext(m_runtime_context));
}
GraphicsRenderInit(m_runtime_context);
}
void Init() {