diff --git a/include/kaacore/renderer.h b/include/kaacore/renderer.h index 538c66fb..1d78812f 100644 --- a/include/kaacore/renderer.h +++ b/include/kaacore/renderer.h @@ -183,8 +183,6 @@ class Renderer { uint32_t _calculate_reset_flags() const; bgfx::ProgramHandle _get_program_handle(const Material* material); - bgfx::RendererType::Enum _choose_bgfx_renderer( - const std::string& name) const; friend class Engine; }; diff --git a/src/engine.cpp b/src/engine.cpp index 29d90142..5fe7f6cf 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "kaacore/audio.h" #include "kaacore/display.h" @@ -14,6 +15,7 @@ #include "kaacore/log.h" #include "kaacore/scenes.h" #include "kaacore/statistics.h" +#include "kaacore/platform.h" #include "kaacore/engine.h" @@ -46,6 +48,63 @@ class InitGuard { std::scoped_lock _lock; }; +std::string +get_env_or_empty_string(const char* env_name) { + if (auto value = SDL_getenv(env_name)) { + return value; + } + return ""; +} + +bgfx::RendererType::Enum +choose_renderer_backend(const std::string& renderer_name) +{ + if (renderer_name == "noop") { + return bgfx::RendererType::Noop; + } else if (renderer_name == "dx9") { + return bgfx::RendererType::Direct3D9; + } else if (renderer_name == "dx11") { + return bgfx::RendererType::Direct3D11; + } else if (renderer_name == "dx12") { + return bgfx::RendererType::Direct3D12; + } else if (renderer_name == "metal") { + return bgfx::RendererType::Metal; + } else if (renderer_name == "opengl") { + return bgfx::RendererType::OpenGL; + } else if (renderer_name == "vulkan") { + return bgfx::RendererType::Vulkan; + } else if (renderer_name == "bgfx_default") { + return bgfx::RendererType::Count; // bgfx default + } else if (renderer_name == "default" or renderer_name == "") { + if (get_platform() == PlatformType::linux) { + return bgfx::RendererType::OpenGL; + } + return bgfx::RendererType::Count; // bgfx default + } else { + throw exception( + fmt::format("Unsupported renderer: {}.\n", renderer_name)); + } +} + +uint16_t +choose_gpu_vendor(const std::string& vendor_name) +{ + if (vendor_name == "software") { + return BGFX_PCI_ID_SOFTWARE_RASTERIZER; + } else if (vendor_name == "amd") { + return BGFX_PCI_ID_AMD; + } else if (vendor_name == "intel") { + return BGFX_PCI_ID_INTEL; + } else if (vendor_name == "nvidia") { + return BGFX_PCI_ID_NVIDIA; + } else if (vendor_name == "default" or vendor_name == "") { + return BGFX_PCI_ID_NONE; + } else { + throw exception( + fmt::format("Unsupported GPU vendor: {}.\n", vendor_name)); + } +} + std::string get_persistent_path( const std::string& prefix, const std::string& organization_prefix) @@ -288,11 +347,23 @@ Engine::_gather_platform_data() SDL_VERSION(&wminfo.version); SDL_GetWindowWMInfo(this->window->_window, &wminfo); + auto renderer_type = choose_renderer_backend(get_env_or_empty_string("KAACORE_RENDERER")); + bgfx_init_data.type = renderer_type; + bgfx_init_data.vendorId = choose_gpu_vendor(get_env_or_empty_string("KAACORE_GPU_VENDOR")); #if SDL_VIDEO_DRIVER_X11 - // using sdl's provided ndt pointer might cause - // segfault during engine 2nd initialization, - // bgfx is capable of querying this info on it's own - bgfx_init_data.platformData.ndt = nullptr; + if (renderer_type == bgfx::RendererType::OpenGL) { + // using sdl's provided ndt pointer might cause + // segfault during engine 2nd initialization, + // bgfx is capable of querying this info on it's own + bgfx_init_data.platformData.ndt = nullptr; + } else { + // Vulkan renderer implementation in bgfx is not capable + // of querying the display details on their own so we have to + // fetch this data from SDL. + // Unfortunately it will most cause a SEGFAULT + // on 2nd kaaengine initialization. + bgfx_init_data.platformData.ndt = wminfo.info.x11.display; + } bgfx_init_data.platformData.nwh = reinterpret_cast(wminfo.info.x11.window); #elif SDL_VIDEO_DRIVER_WINDOWS diff --git a/src/renderer.cpp b/src/renderer.cpp index 3b314400..5be5e802 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -66,8 +66,8 @@ load_embedded_shaders( fragment_shader_name); KAACORE_LOG_TRACE("Detected platform : {}", get_platform_name()); return { - EmbeddedShader::load(ShaderType::fragment, fragment_shader_name), EmbeddedShader::load(ShaderType::vertex, vertex_shader_name), + EmbeddedShader::load(ShaderType::fragment, fragment_shader_name), }; } @@ -178,10 +178,6 @@ Renderer::Renderer( bgfx_init_data.resolution.width = window_size.x; bgfx_init_data.resolution.height = window_size.y; - if (auto renderer_name = SDL_getenv("KAACORE_RENDERER")) { - bgfx_init_data.type = this->_choose_bgfx_renderer(renderer_name); - } - bgfx::init(bgfx_init_data); KAACORE_LOG_INFO("Initializing bgfx completed."); KAACORE_LOG_INFO("Initializing renderer."); @@ -615,27 +611,4 @@ Renderer::_get_program_handle(const Material* material) return ptr->program->_handle; } -bgfx::RendererType::Enum -Renderer::_choose_bgfx_renderer(const std::string& renderer_name) const -{ - if (renderer_name == "noop") { - return bgfx::RendererType::Noop; - } else if (renderer_name == "dx9") { - return bgfx::RendererType::Direct3D9; - } else if (renderer_name == "dx11") { - return bgfx::RendererType::Direct3D11; - } else if (renderer_name == "dx12") { - return bgfx::RendererType::Direct3D12; - } else if (renderer_name == "metal") { - return bgfx::RendererType::Metal; - } else if (renderer_name == "opengl") { - return bgfx::RendererType::OpenGL; - } else if (renderer_name == "vulkan") { - return bgfx::RendererType::Vulkan; - } else { - throw exception( - fmt::format("Unsupported renderer: {}.\n", renderer_name)); - } -} - } // namespace kaacore